初识 HTML5 Video Blob

<video src="blob:http://www.bilibili.com/d0823f0f-2b2a-4fd6-a93a-e4c82173c107"></video>

为何会有一个 blob?直接点击这个链接,返回了 404!什么情况?于是对此做了一番探索。

Examples

The following simple example loads a video chunk by chunk as fast as possible, playing it as soon as it can. This example was written by Nick Desaulniers and can be viewed live here.

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();
};

首先创建变量名为 video 的 DOM 对象和变量名为 mediaSource 的 MediaSource 对象。通过函数 createObjectURL 来将 DOM::video 对象的属性 src 和 mediaSource 进行“连接”。接下来,通过注册事件 Event::sourceopen 来触发当上述“连接”结束之后的回调处理。回调处理就是需要赋值 视频数据 的地方。 调用 MediaSource::addSourceBuffer 方法来构建一个存放视频数据的 sourceBuffer。 在往 sourceBuffer 中存放数据结束之后会触发事件 Event::updateend 。通过注册这个事件的回调,可以知晓数据已经加载完毕,然后关闭数据流,调用 Video::play 函数通知浏览器播放视频。至此,整个 Blob 运行机制讲解完毕。

W3C 上有明确关于 MediaSource 扩展接口的文档。扩展文档中是这么定义的, 它允许 JS 脚本动态构建媒体流和允许 JS 传送媒体块到 H5 媒体元素。这种接口的应用可以让 H5 播放器实现持续添加数据进行播放。

综上,这个只是 HTML5 提供的新特性,但是截止目前还是处于试验状态。

特别注意

在上面示例中使用的视频格式不是普通的 MP4 而是 FMP4。如果没有注意到这个问题,就可能造成:
HTML5 MediaSource works with some mp4 files and not with others (same codecs)。

解决方案:
It works fine if mp4 is fragmented.
You can do that using Bento4's mp4fragment tool.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容