所以我正在尝试构建一个直播应用程序,并遇到了一个奇怪的问题。
所以我使用getUserMedia
来捕获用户的视频,然后将用户标记为广播者。然后,我使用MediaRecorder
从MediaStream
获取实际视频数据,然后通过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);
};
答案 0 :(得分:1)
你不能只是插入WebM流。您必须先发送几个部分来初始化流。
抓取EBML Viewer的副本。 https://code.google.com/archive/p/ebml-viewer/downloads(EBML是Matroska基于的标准二进制格式.WebM是Matroska的子集。)打开WebM文件。您将看到一个Segment元素,它将包含一组配置流的数据。 (轨道,编解码器等)所有这些数据,直到第一个集群的开头,必须首先发送到MediaSource。之后,您可以从包含关键帧的任何段开始。
我应该指出,你所做的是一个已解决的问题。查看WebRTC以获得更有效的方法。你得到的控制力较少......但很多东西都是免费的。