Html5 之前,业界对音视频没有标准,因此网页中看到的视频,都是通过第三插件的方式嵌入的,可能是 QuickTime、 RealPlayer 或 Flash。在 Html5 标准中,为<audio><video> 元素规定了一些方法、属性和事件。这些方法、属性和事件允许使用 JavaScript 操作 <audio><video> 元素。目前的情况是,传统的第三方插件嵌入的方式已经越来越少,浏览器也逐渐不在高度支持。

音视频基础

视频文件(视频容器)包含了音频轨道、视频轨道和其他一些元数据。元数据包含了视频的封面、标题、子标题、字幕等相关信息。视频播放的时候,音频轨道和视频轨道是绑定在一起的。

avi、mp4 事实上仅仅是容器的格式,只决定怎么将视频存储起来,而不关系存储的内容。有点类似于 zip 和 rar 的区别。不管是音频文件或视频文件,实际上都只是一个容器文件。

主流的视频容器格式:

  • MPEG-4:通常以.mp4 为扩展名
  • Flash 视频:通常以.flv 为扩展名
  • Ogg:通常以.ogv 为扩展名
  • WebM:通常以.webm 为扩展名
  • 音频视频交错: 通常以.avi 为扩展名

主流的音频容器格式:

  • MPEG-3:.mp3
  • Acc 音频:.acc
  • Ogg 音频:.ogg

原始的媒体文件体积非常巨大,需要以流数据的形式传输。音频和视频编码/解码是一组算法,用来对一段特定音频或视频进行解码和编码,以便音频和视频能够在线播放。

视频编解码器有 H.264、VP8、Ogg Theora,音频编解码器有 AAC、MPEG-3、Ogg Vorbis。

目前还没有一种编解码和容器的组合能应用于所有的浏览器中,因此处理视频的一个流程是:

  1. 制作一个 Ogg 容器中使用 Theora 视频和 Vorbis 音频的版本;
  2. 制作另外一个版本,使用 WebM 视频容器(VP8 + Vorbis);
  3. 再制作一个版本,使用 MP4 视频容器,并使用 H.264 基本配置的视频和 ACC 低配的音频;
  4. 链接上面 3 个文件到同一个 video 元素,并向后兼容基于 Flash 的视频播放器。
1
2
3
4
5
6
7
<video controls width="300" height="300">
<source src="resource/video/OUTPUT.mp4" type="video/mp4"></source>
<source src="resource/video/OUTPUT.ogv" type="video/ogg"></source>
<source src="resource/video/OUTPUT.webm" type="video/webm"></source>
当前浏览器不支持 video直接播放,点击这里下载视频:
<a href="resource/video/OUTPUT.mp4">下载视频</a>
</video>

在上面的代码中,浏览器会先后判断三个source标签的type属性是否支持,如果支持则加载对应文件。

现在的视频编解码器会使用各种技巧减少从一帧到另一帧过程中传递的信息数量,它们不会存储每一帧的所有信息,而只是存储两帧之间的差异信息。 编码器也分有损和无损,无损视频文件一般太大,在网页中没有优势,所以我们重点研究有损编解码器。有损编解码器中,信息在编码过程中丢失是无法避免的,反复的对视频编码会导致其画面不均匀。

<audio><video>的属性

两个标签的主要 attribute 属性有:

  • src:要嵌到页面的视频的 URL
  • controls:显示或隐藏用户控制界面
  • autoplay:媒体是否自动播放
  • loop:媒体是否循环播放
  • muted:是否静音
  • preload:该属性旨在告诉浏览器作者认为达到最佳的用户体验的方式是什么,有四个值。
    • none: 提示作者认为用户不需要查看该视频,服务器也想要最小化访问流量,换句话说就是提示浏览器该视频不需要缓存。
    • metadata: 提示尽管作者认为用户不需要查看该视频,不过抓取元数据(比如:长度)还是很合理的。
    • auto: 用户需要这个视频优先加载,换句话说就是提示:如果需要的话,可以下载整个视频,即使用户并不一定会用它。
    • 空字符串:也就代指 auto 值。

此外,<video>还有宽高属性 widthheight 和 用于在用户播放或者跳帧之前的展示海报帧 URL poster

两个标签的主要 property 属性有:

  • duration:媒体总时间(只读),不能马上取到对应的值,最好在loadeddata事件中(加载第一帧后)读取。
  • currentTime:开始播放到现在所用的时间(可读写)
  • muted:是否静音(可读写,相比于 volume 优先级要高)
  • volume:0.0-1.0 的音量相对值(可读写)
  • paused:媒体是否暂停(只读)
  • ended:媒体是否播放完毕(只读)
  • error:媒体发生错误的时候,返回错误代码 (只读)
  • currentSrc:以字符串的形式返回媒体地址(只读)

此外,<video>还有poster:视频播放前的预览图片(读写);widthheight:设置视频的尺寸(读写);videoWidthvideoHeight:视频的实际尺寸(只读)。

<audio><video>的函数和事件

相关函数有:

  • play():媒体播放
  • pause():媒体暂停
  • load():重新加载媒体

相关事件有:

  • abort 在播放被终止时触发,例如当播放中的视频重新开始播放时会触发这个事件。
  • canplay 在媒体数据已经有足够的数据(至少播放数帧)可供播放时触发。这个事件对应 CAN_PLAY 的 readyState。
  • canplaythrough 在媒体的 readyState 变为 CAN_PLAY_THROUGH 时触发,表明媒体可以在保持当前的下载速度的情况下不被中断地播放完毕。注意:手动设置 currentTime 会使得 firefox 触发一次 canplaythrough 事件,其他浏览器或许不会如此。
  • durationchange 元信息已载入或已改变,表明媒体的长度发生了改变。例如,在媒体已被加载足够的长度从而得知总长度时会触发这个事件。
  • emptied 媒体被清空(初始化)时触发。
  • ended 播放结束时触发。
  • error 在发生错误时触发。元素的 error 属性会包含更多信息。参阅 Error handling 获得详细信息。
  • loadeddata 媒体的第一帧已经加载完毕。
  • loadedmetadata 媒体的元数据已经加载完毕,现在所有的属性包含了它们应有的有效信息。
  • loadstart 在媒体开始加载时触发。
  • mozaudioavailable 当音频数据缓存并交给音频层处理时
  • pause 播放暂停时触发。
  • play 在媒体回放被暂停后再次开始时触发。即,在一次暂停事件后恢复媒体回放。
  • playing 在媒体开始播放时触发(不论是初次播放、在暂停后恢复、或是在结束后重新开始)。
  • progress 告知媒体相关部分的下载进度时周期性地触发。有关媒体当前已下载总计的信息可以在元素的 buffered 属性中获取到。
  • ratechange 在回放速率变化时触发。
  • seeked 在跳跃操作完成时触发。
  • seeking 在跳跃操作开始时触发。
  • stalled 在尝试获取媒体数据,但数据不可用时触发。
  • suspend 在媒体资源加载终止时触发,这可能是因为下载已完成或因为其他原因暂停。
  • timeupdate 元素的 currentTime 属性表示的时间已经改变。
  • volumechange 在音频音量改变时触发(既可以是 volume 属性改变,也可以是 muted 属性改变)。
  • waiting 在一个待执行的操作(如回放)因等待另一个操作(如跳跃或下载)被延迟时触发。