MediaSource Buffer仅适用于一个客户端

时间:2018-05-07 19:41:22

标签: websocket media-source web-mediarecorder

所以我正在尝试构建一个直播应用程序,并遇到了一个奇怪的问题。

所以我使用getUserMedia来捕获用户的视频,然后将用户标记为广播者。然后,我使用MediaRecorderMediaStream获取实际视频数据,然后通过websocket发送。

websocket只是将视频数据广播到所有连接的客户端,但由于某种原因,它只能在广播公司的播放器上正常播放,但是当我尝试从不同的客户端播放相同的精确流时,它只是给了我这个错误:

Uncaught DOMException: Failed to execute 'appendBuffer' on 'SourceBuffer': This SourceBuffer has been removed from the parent media source.

当我查看 chrome:// media-internals 时,我看到了这个错误:

00:00:00 94 error Unexpected element ID 0x8c 00:00:00 94 error Append: stream parsing failed. Data size=33926 append_window_start=0 append_window_end=inf 00:00:00 94 pipeline_error CHUNK_DEMUXER_ERROR_APPEND_FAILED

两个客户端上的脚本和所有内容当然是相同的。唯一不同的是,我认为可能是罪魁祸首是广播公司的流没有立即开始,因为广播公司首先需要将视频数据发送到websocket服务器,以便服务器转发任何东西。然而,非广播客户有点跳入中间"流。

唯一的另一个区别是广播是通过同一个插槽下载和上传视频数据,但我不知道这会如何解决这个问题。

编辑:运行测试后,两个客户端都连接到websocket没有视频流,然后运行流后,两个客户端都工作,这意味着问题确实源于其他客户端跳入流中那么,这将如何解决?

我对这一切都很陌生,所以我不确定这是否是一个很好的推理。作为参考,这是脚本:

var socket = new WebSocket('websocket');
socket.binaryType = 'arraybuffer';

var broadcastMs = new MediaSource();

var video = document.querySelector("#broadcast");
video.src = window.URL.createObjectURL(broadcastMs);

var msReady = false;
var sourceBuffer = false;
var queue = [];

broadcastMs.addEventListener('sourceopen', function(e)
{
    sourceBuffer = broadcastMs.addSourceBuffer('video/webm; codecs="opus,vp8"');

    sourceBuffer.addEventListener('update', function()
    {
        if ( queue.length > 0 && !sourceBuffer.updating )
            sourceBuffer.appendBuffer(queue.shift());
    });

    msReady = true;     
});

socket.onmessage = function(ev)
{
    setTimeout(function()
    {
        if ( msReady )
        {
            if ( sourceBuffer.updating )
                queue.push(ev.data);
            else
                sourceBuffer.appendBuffer(ev.data);
        }
    }, 50);
};

1 个答案:

答案 0 :(得分:1)

你不能只是插入WebM流。您必须先发送几个部分来初始化流。

抓取EBML Viewer的副本。 https://code.google.com/archive/p/ebml-viewer/downloads(EBML是Matroska基于的标准二进制格式.WebM是Matroska的子集。)打开WebM文件。您将看到一个Segment元素,它将包含一组配置流的数据。 (轨道,编解码器等)所有这些数据,直到第一个集群的开头,必须首先发送到MediaSource。之后,您可以从包含关键帧的任何段开始。

我应该指出,你所做的是一个已解决的问题。查看WebRTC以获得更有效的方法。你得到的控制力较少......但很多东西都是免费的。