HTML5视频:使用Blob网址流式传输视频 [英] HTML5 Video: Streaming Video with Blob URLs

查看:245
本文介绍了HTML5视频:使用Blob网址流式传输视频的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Blob数组(二进制数据,真的 - 我可以表达它但效率最高。我现在使用Blob但可能是 Uint8Array 或什么会更好)。每个Blob包含1秒的音频/视频数据。每秒生成一个新的Blob并附加到我的数组。所以代码大致如下:

I have an array of Blobs (binary data, really -- I can express it however is most efficient. I'm using Blobs for now but maybe a Uint8Array or something would be better). Each Blob contains 1 second of audio/video data. Every second a new Blob is generated and appended to my array. So the code roughly looks like so:

var arrayOfBlobs = [];
setInterval(function() {
    arrayOfBlobs.append(nextChunk());
}, 1000);

我的目标是将此音频/视频数据流式传输到HTML5元素。我知道可以像这样生成和播放Blob URL:

My goal is to stream this audio/video data to an HTML5 element. I know that a Blob URL can be generated and played like so:

var src = URL.createObjectURL(arrayOfBlobs[0]);
var video = document.getElementsByTagName("video")[0];
video.src = src;

当然这只播放视频的前1秒。我还假设我可以简单地连接当前在我的数组中的所有Blob以某种方式播放超过一秒:

Of course this only plays the first 1 second of video. I also assume I can trivially concatenate all of the Blobs currently in my array somehow to play more than one second:

// Something like this (untested)
var concatenatedBlob = new Blob(arrayOfBlobs);
var src = ...

然而,这仍将最终耗尽数据。由于Blob是不可变的,我不知道如何继续附加数据。

However this will still eventually run out of data. As Blobs are immutable, I don't know how to keep appending data as it's received.

我确信这应该是可能的,因为YouTube和许多其他视频流服务利用Blob URL进行视频播放。 他们 如何做?

I'm certain this should be possible because YouTube and many other video streaming services utilize Blob URLs for video playback. How do they do it?

推荐答案

解决方案



经过一番重要的谷歌搜索后,我设法找到了这个难题的缺失部分: MediaSource

有效的过程如下:


  1. 创建 MediaSource

  2. MediaSource <创建对象URL / code>

  3. 将视频的 src 设置为对象URL

  4. sourceopen 事件,创建 SourceBuffer

  5. 使用 SourceBuffer.appendBuffer()将所有块添加到视频中

  1. Create a MediaSource
  2. Create an object URL from the MediaSource
  3. Set the video's src to the object URL
  4. On the sourceopen event, create a SourceBuffer
  5. Use SourceBuffer.appendBuffer() to add all of your chunks to the video

这样你就可以保持在不更改对象URL的情况下添加新的视频位。

This way you can keep adding new bits of video without changing the object URL.


  • SourceBuffer 对象 非常 挑剔编解码器。这些必须声明,必须准确,否则无效。

  • 您只能将一个视频数据块添加到 SourceBuffer 一次,并且在第一个blob完成(异步)处理之前你不能追加第二个blob

  • 如果你向 SourceBuffer 没有调用 .remove()那么你最终会耗尽RAM并且视频将停止播放。我在笔记本电脑上大约1小时达到此限制

  • The SourceBuffer object is very picky about codecs. These have to be declared, and must be exact, or it won't work
  • You can only append one blob of video data to the SourceBuffer at a time, and you can't append a second blob until the first one has finished (asynchronously) processing
  • If you append too much data to the SourceBuffer without calling .remove() then you'll eventually run out of RAM and the video will stop playing. I hit this limit around 1 hour on my laptop

根据您的设置,其中一些可能是不必要的(特别是在我们有 SourceBuffer 之前构建视频数据队列的部分,然后使用<$ c慢慢地附加我们的队列$ C> updateend )。如果您能够等到 SourceBuffer 已经创建以开始抓取视频数据,那么您的代码看起来会更好。

Depending on your setup, some of this may be unnecessary (particularly the part where we build a queue of video data before we have a SourceBuffer then slowly append our queue using updateend). If you are able to wait until the SourceBuffer has been created to start grabbing video data, your code will look much nicer.

<html>
<head>
</head>
<body>
    <video id="video"></video>
    <script>
        // As before, I'm regularly grabbing blobs of video data
        // The implementation of "nextChunk" could be various things:
        //   - reading from a MediaRecorder
        //   - reading from an XMLHttpRequest
        //   - reading from a local webcam
        //   - generating the files on the fly in JavaScript
        //   - etc
        var arrayOfBlobs = [];
        setInterval(function() {
            arrayOfBlobs.append(nextChunk());
            // NEW: Try to flush our queue of video data to the video element
            appendToSourceBuffer();
        }, 1000);

        // 1. Create a `MediaSource`
        var mediaSource = new MediaSource();

        // 2. Create an object URL from the `MediaSource`
        var url = URL.createObjectURL(mediaSource);

        // 3. Set the video's `src` to the object URL
        var video = document.getElementById("video");
        video.src = url;

        // 4. On the `sourceopen` event, create a `SourceBuffer`
        var sourceBuffer = null;
        mediaSource.addEventListener("sourceopen", function()
        {
            // NOTE: Browsers are VERY picky about the codec being EXACTLY
            // right here. Make sure you know which codecs you're using!
            sourceBuffer = mediaSource.addSourceBuffer("video/webm; codecs=\"opus,vp8\"");

            // If we requested any video data prior to setting up the SourceBuffer,
            // we want to make sure we only append one blob at a time
            sourceBuffer.addEventListener("updateend", appendToSourceBuffer);
        });

        // 5. Use `SourceBuffer.appendBuffer()` to add all of your chunks to the video
        function appendToSourceBuffer()
        {
            if (
                mediaSource.readyState === "open" &&
                sourceBuffer &&
                sourceBuffer.updating === false
            )
            {
                sourceBuffer.appendBuffer(arrayOfBlobs.shift());
            }

            // Limit the total buffer size to 20 minutes
            // This way we don't run out of RAM
            if (
                video.buffered.length &&
                video.buffered.end(0) - video.buffered.start(0) > 1200
            )
            {
                sourceBuffer.remove(0, video.buffered.end(0) - 1200)
            }
        }
    </script>
</body>
</html>

作为额外奖励,这会自动为您提供实时流的DVR功能,因为您保留了20分钟缓冲区中的视频数据(您可以通过简单地使用 video.currentTime = ... 进行搜索)

As an added bonus this automatically gives you DVR functionality for live streams, because you're retaining 20 minutes of video data in your buffer (you can seek by simply using video.currentTime = ...)

这篇关于HTML5视频:使用Blob网址流式传输视频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆