MSE

什么是MSE

MSE是一个允许在支持html5-video的浏览器中发送字节流的w3c标准, 全称是Media Souce Extensions.

MSE来由

要先知道MSE的来由,先要知道没有MSE之前浏览器对video的支持情况。

Html5发布后浏览器支持video标签, 但是只是基本支持了播放一个完整单轨道,无法支持视频arraybuffer的分隔与组合;由于现在社会多媒体技术的发展,
人们对视频观看方式的需求日益剧增,如视频点播, 代表为国内的youku/souhu/iqiyi等视频网站,国外的youtube netflix hulu等;到现在的各种直播网站,
国内的斗鱼国外的twitch等;之前浏览器的video功能已经不能支持,所以MSE标准应运而生。

MSE特点

MSE首先提供了MediaSource对象,作为一个容器,内部包含了一系列视频信息,如要被播放的media资源的状态, 指向组成播放流的多个轨道的SouceBuffer对象,
除此之外,MSE还提供了对视频内容获取的多少与速度的把控,以及一些内存的管理;

但是,MSE也有一些不足之处,因为浏览器处理视频解码转码方面性能消耗很大,这些功能只能放在浏览器之外处理,所以浏览器只接受主流的一些媒体格式,如
H.264 video codec, AAC audio codec, and MP4 container format; 还有一点就是各浏览器对MSE的支持程度不太一致,实现也有一些差别,导致现在html5播放器
在浏览器使用上没有普及开来,需要各方的协作.

主要对象

1.MediaSouce

构造函数

MediaSource() // 构造并且返回一个新的MediaSource的空对象

属性

MediaSource.sourceBuffers / MediaSource.activeSourceBuffers / MediaSource.readyState /MediaSource.duration

方法

MediaSource.addSourceBuffer() / MediaSource.removeSourceBuffer() / MediaSource.endOfStream() / MediaSource.isTypeSupported()

2.SouceBuffer

构造

可以通过MediaSource.addSourceBuffer()来构造

属性

mode / updating / buffered / timestampOffset / audioTracks / videoTracks / textTracks / appendWindowStart / trackDefaults

方法

appendBuffer() / appendStream() / abort() / remove()

事件

onabort / onerror / onupdate / onupdateend / onupdatestart

3.URL Object Extensions

构造方法

1
2
3
4
var video = document.querySelector('#video')
var m = new MediaSource
var l = URL.createObjectURL(m)
video.src = l

4.HTMLMediaElement Extensions

HTMLMediaElement.seekable -> normalized TimeRanges object

HTMLMediaElement.buffered -> normalized TimeRanges objec

一个简单例子

下面是从MDN上摘录下来的一个栗子, 这个栗子可以在这里下载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
var video = document.querySelector('video');
var assetURL = 'frag_bunny.mp4';
// Need to be specific for Blink regarding codecs
// ./mp4info frag_bunny.mp4 | grep Codec
var mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
if ('MediaSource' in window && MediaSource.isTypeSupported(mimeCodec)) {
var mediaSource = new MediaSource();
//console.log(mediaSource.readyState); // closed
video.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', sourceOpen);
} else {
console.error('Unsupported MIME type or codec: ', mimeCodec);
}
function sourceOpen (_) {
//console.log(this.readyState); // open
var mediaSource = this;
var sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
fetchAB(assetURL, function (buf) {
sourceBuffer.addEventListener('updateend', function (_) {
mediaSource.endOfStream();
video.play();
//console.log(mediaSource.readyState); // ended
});
sourceBuffer.appendBuffer(buf);
});
};
function fetchAB (url, cb) {
console.log(url);
var xhr = new XMLHttpRequest;
xhr.open('get', url);
xhr.responseType = 'arraybuffer';
xhr.onload = function () {
cb(xhr.response);
};
xhr.send();
};

相关库