MSE和Video标签的关系

H5直播系列二 MSE(Media Source Extensions) - 简书

1、Video标签

拥有解封装和解码功能的浏览器自带播放器

随着视频点播、直播等视频业务的发展,视频通过流媒体传输协议(目前常用的有两种,MPEG-DASH和Apple的HLS)从服务器端分发给客户端,媒体内容进一步包含在一层传输协议中,这样

仅靠

hls实际会先通过 ajax(loader 是可以完成自定义的) 请求 m3u8文件,然后会读取到文件的分片列表,以及视频的编码格式,时长等。随后会按照顺序(非 seek )去对分片进行请求,这些也是通过 ajax 请求二进制的文件,然后借助 Media Source Extensions 将 buffer 内容进行合流,然后组成一个可播的媒体资源文件。

2、MSE的功能一:转封装(FLV/FMP4->mp4)

很多媒体源都是适用Flash播放的FLV格式:而由于历史遗留问题(HTML5 视频标准最终被广泛支持以前,Flash 在 Web 视频播放方面有着统治地位),视频网站的视频源和转码设置,很多都高清源都是适用于 Flash 播放 FLV 格式,只有少量低清晰度视频是 mp4 格式,webm 和 ogg 更是听都没听说过。比如优酷只有高清和标清才有 MP4 源,超清、1080P 等,基本都是 FLV 和 HLS(M3U8)的视频源(在 Windows PC 上支持 M3U8 比支持 FLV 更复杂,我们不做过多赘述)。

而Video标签只支持mp4、webm、ogg 等封装的264/265码流

因此MSE应运而生,他可以把FLV格式转换成mp4格式。

B 站开源的 flv.js 就是这个技术的一个典型实现。B 站的 PC HTML5 播放器,就是MSE 技术,将 FLV 源JS 实时转成 HTML5 支持的视频流编码格式(其实就一个文件头的差异(这里文件头改成容器。感谢评论区谦谦的指教,是容器的差异,容器不只是文件头)),提供给 HTML5 播放器播放。

FLV和MP4的对比,为什么不直接采用mp4格式 

  • 一方面是历史遗留问题,由于视频网站前期完全依赖 Flash 播放而选择 FLV 格式;
  • 另一方面,如果仔细研究过 FLV/MP4 封装格式,你会发现 FLV 格式非常简洁,而 MP4 内部 box 种类繁杂,结构复杂固实而又有太多冗余数据。FLV 天生具备流式特征适合网络流传输,而 MP4 这种使用最广泛的存储格式,设计却并不一定优雅。

MP4和FMP4对比:

对于普通 MP4 文件,整个mp4文件的的meta数据都在文件头,所有媒体数据为整体一块。当文件比较大的时候,meta数据就比较大。这样对mp4文件的本地播放是没有问题。但对于一些视频播放网站而言,用户的播放器必须下载全meta数据才能开始播放,这就意味着用户的缓冲时间将因为mp4文件的存储结构而延长。目前一种解决方法是将大的mp4文件切成物理分离的多段,使得每段的meta都比较小,从而在一定程度上减少缓冲时间。 fMP4 是一个流式的封装格式,这样更适合在网络中进行流式传输,而不需要依赖文件头的metadata。

3、MSE的功能二:自适应比特率播放

我们已经可以在 Web 应用程序上无插件地播放视频和音频了。但是,现有架构过于简单,只能满足一次播放整个曲目的需要,无法实现拆分/合并数个缓冲文件。

使用MSE,我们可以:①把通常的单个媒体文件的 src 值替换成引用 MediaSource 对象(一个包含即将播放的媒体文件的准备状态等信息的容器)以及引用多个 SourceBuffer 对象(组成整个串流的不同媒体块)的元素。②能够根据内容获取视频的大小、频率、内存占用详情,从而进行更加精准地控制。 这是基于它可扩展的 API 建立的自适应比特率流客户端(例如DASH 或 HLS 的客户端)的基础。

4、使用createObjectURL将MediaSource和video标签连接起来

var mediaSource = new MediaSource;
//console.log(mediaSource.readyState); // closed
video.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', sourceOpen);

MS 的实例通过 URL.createObjectURL() 创建的 url 并不会同步连接到 video.src。换句话说,URL.createObjectURL() 只是底层流(MS)和 video.src 的连接中间者,一旦两者连接到一起之后,该对象就没用了。那么什么时候 MS 才会和 video.src 连接到一起呢?创建实例都是同步的,但是底层流和 video.src 的连接是异步的。MS 提供了一个 sourceopen 事件给我们进行这项异步处理。一旦连接到一起之后,该 URL object 就没用了,处于内存节省的目的,可以使用 URL.revokeObjectURL(vidElement.src) 销毁指定的 URL object。

mediaSource.addEventListener('sourceopen', sourceOpen);
function sourceOpen(){
    URL.revokeObjectURL(vidElement.src)
}

5、设置编码类型mime字符串

'avc1.42E01E'

有一处要注意,后面两个值(profile_compability、AVCLevelIndication)只是浏览器用于判断自身的解码能力能否满足需求,所以不需要和视频完全对应,更高也是可以的。

你可能感兴趣的:(多媒体播放(音视频解析,编解码,渲染),ffmpeg)