【问题标题】:HTML5 Video stream from websocket via MediaSource and MediaSourceBuffer通过 MediaSource 和 MediaSourceBuffer 来自 websocket 的 HTML5 视频流
【发布时间】:2020-08-11 01:37:42
【问题描述】:

我正在尝试从 websocket 播放视频

<video id="output" width="320" height="240" autoplay></video>

<script>
    function sockets(buffer) {
        const socket = new WebSocket('wss://localhost:5002/ws')

        socket.onmessage = async function (event) {
            // event.data is a blob
            buffer.appendBuffer(new Uint8Array(event.data))
        }
    }

    let ms = new MediaSource()
    let output = document.getElementById('output')
    output.src = URL.createObjectURL(ms)
    ms.onsourceopen = () => {
        let buffer = ms.addSourceBuffer('video/webm; codecs="vorbis,vp8"')
        sockets(buffer)
    }
</script>

我在这里以 Blob 形式接收 MediaRecorder 块,并尝试使用 MediaSource API 顺序播放它们。没有错误,也没有任何反应。这里有什么根本错误吗?

我试过了:

  • 使用不同的编解码器
  • 使用媒体源模式播放,例如序列/片段
  • 我还尝试了不同的方法,您不使用 MediaSource API 但面临其他挑战,而 MediaSource 似乎是我的最佳方法。

更新:这就是视频的制作方式:

let options = { mimeType: 'video/webm;codecs=vp8' }
let stream = await navigator.mediaDevices.getUserMedia({ video: true })
mediaRecorder = new MediaRecorder(stream, options)
mediaRecorder.ondataavailable = event => {
    if (event.data && event.data.size > 0) {
        send(event.data)
    }
}

【问题讨论】:

  • 视频是如何制作的。什么编解码器/容器? chrome 媒体内部人员怎么说?
  • @szatmary 我已经更新了帖子。请看一下
  • @Andrei 按照 szatmary 的建议转到 chrome://media-internals 以获取更多信息。此外,您的源只有一个视频流,但您在接收端指定了视频和音频编解码器。您也不应该假设您从 MediaRecorder 返回的编解码器将是您请求的编解码器。在 blob 上使用生成的 mimeType

标签: javascript html websocket http-live-streaming media-source


【解决方案1】:

这里的根本问题是您不能流式传输来自MediaRecorder 的数据并期望另一端播放它;这不是一个完整的视频。它只有在接收端能够接收到 初始化字节 时才会起作用——我怀疑这在现实世界的场景中是否会起作用。

您可以做的是创建一个间隔,例如每 1 秒启动/停止 MediaRecorder,以制作 1 秒的视频块,您可以通过网络传输(我知道和测试的最好的是 websockets)

我强烈建议不要使用MediaRecorder,因为你正在做你帖子中没有说明的实时视频流,但如果是的话,你最好创建一个画布来复制流并做一些@ 987654325@ 可以将您的视频流捕获为您可以传输的东西的东西。

看看这个演示以供参考:https://github.com/cyberquarks/quarkus-websockets-streamer/blob/master/src/main/resources/META-INF/resources/index.html

MediaRecorder 以我的经验响应延迟,这通常会在视频中增加相当大的延迟,更不用说套接字也会引入的延迟。

一般情况下,其他开发人员会建议您只采用 WebRTC 路线,但根据我的经验,WebRTC 通常也不会更快。

【讨论】:

  • 可以从 MediaRecorder 流式传输数据并稍后播放。尤其是使用 WebM,这是微不足道的。初始化数据是直到第一个集群的所有数据。您的间隔示例不能保证工作...启动/停止 MediaRecorder 是异步的,不一定在任何特定时间下降。它今天在某些地方可能对您有用,但不能保证有效。 MediaRecorder 非常适合实时流式传输。低延迟并不是每个人的要求。很多时候,最好丢帧和音频。
  • @Brad 您能否在答案中详细说明?你似乎知道你在说什么:)。谢谢。
  • @Andrei 您可以推动自己使用 MediaStream 通过网络进行流式传输,这是可能的(从未说过不可能)我指出的问题是您无法实现实时,您可以搜索整个 Stackoverflow,没有人建议实时使用它。如果您不需要实时,那么 MediaRecorded 是最简单的方法。
  • @Brad 启动/停止对我的简单演示有效,但由于速度很慢,我什至问过 Mozilla 开发人员,他们说只是实时使用画布。但是您提到 MediaRecorder 可以用于实时流媒体,这是新的,如果事实如此,那就太好了,您有可以展示这一点的示例或演示吗?自从上次我记得我使用 MediaRecorder 进行我们的原型实时流式传输时,我切换到画布的原因是 MediaRecorder 发出的视频已经延迟了,如果我们引入网络延迟,还会有更多的延迟。
  • 您可以在不使用 FFmpeg 的情况下通过直接流式传输到 &lt;video&gt; 元素来实现。不需要 MediaSource 扩展。所以,MediaRecorder -> Web Socket -> Passive Server -> HTTP -> Video Element。如果您确实想进入实时流,您只需要 WebM 的数据直到第一个集群,然后从任何以关键帧开始的集群开始。我现在不在电脑前,但还有另一个 Stack Overflow 答案,我有详细信息……我明天看看能不能找到。
猜你喜欢
  • 1970-01-01
  • 2012-02-03
  • 1970-01-01
  • 2013-05-04
  • 1970-01-01
  • 2016-07-05
  • 2015-05-27
  • 2011-08-01
  • 2018-11-09
相关资源
最近更新 更多