首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MediaSource缓冲区只在一个客户端上工作。

问MediaSource缓冲区只在一个客户端上工作。
EN

Stack Overflow用户
提问于 2018-05-07 19:41:21
回答 2查看 679关注 0票数 3

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

因此,我使用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-内嵌时,我会看到以下错误:

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而没有视频流的测试之后,两个客户端都运行了流,这意味着问题确实来自于其他客户端在中途跳入流中,如何解决这个问题呢?

然而,我对这一切并不熟悉,所以我不确定这是否是很好的推理。供参考,以下是脚本:

代码语言:javascript
复制
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);
};
EN

回答 2

Stack Overflow用户

发布于 2018-05-08 14:09:28

您不能只把针掉进WebM流中.您必须首先发送几个部分来初始化流。

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

我应该指出,你所做的是一个已解决的问题。查看一下WebRTC,寻找一种更有效的方法来实现这一点。你控制的越少..。但是很多东西都是免费的。

票数 1
EN

Stack Overflow用户

发布于 2021-09-11 14:22:19

根据我使用MediaRecorder和MediaSource的经验,大部分与视频冻结或返回错误相关的错误可能是由于接收到的块不同步所致。我认为webm (可能还有其他媒体类型)需要按时间顺序来接收这些块。记录、发送、然后接收块异步可能无法保持时间序列的递增顺序。

因此,在对我自己使用MediaRecorder/MediaSource进行视频冻结的经验进行分析之后,我更改了代码,将记录的块发送到Sync中,而不是异步。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50221344

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档