·您当前的位置:主页 > 技术教程 > 播放器教程 >

[播放器]Media Source Extensions是如何完成视频流的加载和播放

时间:2017-06-07 16:24bijishequ.com
[播放器]Media Source Extensions是如何完成视频流的加载和播放

在没有 MSE 出现之前,前端对 video 的操作,仅仅局限在对视频文件的操作,而并不能对视频流做任何相关的操作。现在 MSE 提供了一系列的 接口 ,使开发者可以直接提供 media stream。

那 MSE 是如何完成视频流的加载和播放呢?

入门实例

这可以参考 google 的 MSE 简介

var vidElement = document.querySelector('video');  if (window.MediaSource) {   var mediaSource = new MediaSource();   vidElement.src = URL.createObjectURL(mediaSource);   mediaSource.addEventListener('sourceopen', sourceOpen); } else {   console.log("The Media Source Extensions API is not supported.") }  function sourceOpen(e) {   URL.revokeObjectURL(vidElement.src);   var mime = 'video/webm; codecs="opus, vp9"';   var mediaSource = e.target;   var sourceBuffer = mediaSource.addSourceBuffer(mime);   var videoUrl = 'droid.webm';   fetch(videoUrl)     .then(function(response) {       return response.arrayBuffer();     })     .then(function(arrayBuffer) {       sourceBuffer.addEventListener('updateend', function(e) {         if (!sourceBuffer.updating && mediaSource.readyState === 'open') {           mediaSource.endOfStream();         }       });       sourceBuffer.appendBuffer(arrayBuffer);     }); }

可以从上面的代码看出,一套完整的执行代码,不仅需要使用 MSE 而且,还有一下这些相关的 API。

  • HTMLVideoElement.getVideoPlaybackQuality()
  • SourceBuffer
  • SourceBufferList
  • TextTrack.sourceBuffer
  • TrackDefault
  • TrackDefaultList
  • URL.createObjectURL()
  • VideoPlaybackQuality
  • VideoTrack.sourceBuffer

我们简单讲解一下上面的流程。根据 google 的阐述,整个过程可以为:

  • 第一步,通过异步拉取数据。
  • 第二步,通过 MediaSource 处理数据。
  • 第三步,将数据流交给 audio/video 标签进行播放。

而中间传递的数据都是通过 Buffer 的形式来进行传递的。

中间有个需要注意的点,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) }

MS 对流的解析

MS 提供了我们对底层音视频流的处理,那一开始我们怎么决定以何种格式进行编解码呢?

这里,可以使用 addSourceBuffer(mime) 来设置相关的编码器:

var mime = 'video/webm; codecs="opus, vp9"';     var sourceBuffer = mediaSource.addSourceBuffer(mime);

然后通过,异步拉取相关的音视频流:

fetch(url) .then(res=>{     return res.arrayBuffer(); }) .then(buffer=>{     sourceBuffer.appendBuffer(buffer); })

如果视频已经传完了,而相关的 Buffer 还在占用内存,这时候,就需要我们显示的中断当前的 Buffer 内容。那么最终我们的异步处理结果变为:

fetch(url) .then(res=>{     return res.arrayBuffer(); }) .then(function(arrayBuffer) {       sourceBuffer.addEventListener('updateend', function(e) {       // 是否有持续更新的流         if (!sourceBuffer.updating && mediaSource.readyState === 'open') {         // 没有,则中断连接           mediaSource.endOfStream();         }       });       sourceBuffer.appendBuffer(arrayBuffer);     });

上面我们大致了解了一下关于 Media Source Extensions 的大致流程,但里面的细节我们还没有细讲。接下来,我们来具体看一下 MSE 一篮子的生态技术包含哪些内容。首先是,MediaSource

保利威视云直播提供稳定流畅,高画质,低延迟的直播服务

酷播云服务,酷播云