前言
在 H5 开发中,视频(Video)和音频(Audio)的应用非常广泛。虽然市面上有很多优秀的第三方播放器插件(如 DPlayer、Video.js),但理解原生的媒体属性和事件,是实现自定义交互、埋点统计以及性能优化的核心基础。
一、 媒体元素基础结构
HTML5 引入了 <video> 和 <audio> 标签。为了确保不同浏览器的兼容性,通常建议使用 <source> 标签提供多种格式。
<video id="myVideo" width="640" height="360" controls>
<source src="movie.mp4" type="video/mp4">
<source src="movie.webm" type="video/webm">
您的浏览器不支持 HTML5 视频。
</video>
<audio id="myAudio" src="music.mp3" controls></audio>
二、 核心 API:公共属性与方法
video 和 audio 共享了大部分 API,允许我们通过 JavaScript 精确控制播放状态。
1. 状态与控制属性
src:媒体文件地址。controls:是否显示浏览器默认控件。autoplay:是否自动播放(注意:现代浏览器通常要求静音muted才能自动播放)。loop: 是否循环播放。paused(只读):返回布尔值,表示媒体是否处于暂停状态。volume:音量控制(0.0 ~ 1.0)。playbackRate:播放倍速(如 0.5, 1.0, 2.0),常用于视频学习网站。
2. 进度与缓冲
currentTime:当前播放到的时间(单位:秒)。duration:媒体总时长。buffered:返回一个TimeRanges对象,表示浏览器已经缓冲的范围。
三、 核心事件流:监听媒体生命周期
通过监听这些事件,我们可以实现自定义进度条、播放按钮以及加载动画。
| 事件名称 | 触发时机 | 典型用途 |
|---|---|---|
loadstart | 浏览器开始搜索媒体并下载时。 | 显示加载转圈(Spinner)。 |
loadeddata | 媒体第一帧加载完成(视频可见)。 | 隐藏封面图,准备播放。 |
canplaythrough | 预计在不卡顿的情况下能播放完整视频。 | 移除所有 Loading 状态。 |
play / pause | 播放状态切换。 | 同步 UI 按钮图标。 |
timeupdate | 最常用:播放位置改变时触发。 | 更新进度条数值、同步歌词。 |
ended | 播放结束。 | 展示重播按钮或推荐视频。 |
error | 资源加载或网络发生错误。 | 提示用户检查网络或切换线路。 |
四、 进阶实战:如何优雅地控制播放?
1. 播放/暂停切换
const media = document.getElementById('myVideo');
function togglePlay() {
if (media.paused) {
media.play();
} else {
media.pause();
}
}
2. 实时进度展示
media.addEventListener('timeupdate', () => {
const progress = (media.currentTime / media.duration) * 100;
console.log(`当前进度:${progress.toFixed(2)}%`);
});
五、 面试模拟题与避坑指南
Q1:为什么我设置了 autoplay 视频却没有自动播放?
参考回答:
为了防止网页骚扰用户,现代浏览器(Chrome、Safari 等)严格限制了自动播放。
解决办法:必须同时设置 muted(静音)属性,或者由用户产生交互动作(如点击页面)后才能触发播放。
Q2:如何判断视频已经加载完毕可以流畅播放?
参考回答:
应该监听 canplaythrough 事件。相比 canplay 事件,canplaythrough 代表浏览器预估后续下载速度能跟上播放速度,不会产生卡顿。
Q3:timeupdate 事件触发的频率是多少?
参考回答:
触发频率由浏览器决定,通常是每秒 4 到 66 毫秒触发一次(每秒约 15-25 次)。如果需要更高精度的同步(如高精度视频标注),可能需要结合 requestAnimationFrame。