我的 Javascript 应用程序通过 Websocket 连接获取 WebM 视频流。远程端发送视频帧和应用程序获取视频帧之间没有延迟。
我在应用程序中创建了一个 MediaSource
对象,我向其“附加视频帧”,并让视频元素显示它:
video.src = window.URL.createObjectURL(mediaSource);
这很好用,但存在一些(不到一秒)延迟,这可能使该解决方案不是视频通话的最佳选择。
显然,一些 WebRTC 应用程序使用 MediaStream
代替:
video.srcObject = mediaStream;
...并且这些显示没有延迟。
我无法根据文档确定浏览器是否以不同方式处理 src
和 srcObject
。
另一件我找不到的事情是,是否可以创建一个 MediaStream
并将缓冲区附加到它,就像使用 MediaSource
一样。我想尝试一下,只是为了检查 srcObject
是否会导致我的应用程序出现上述延迟。
如果我使用:
video.srcObject = mediaSource;
我得到错误:
TypeError: Failed to set the 'srcObject' property on 'HTMLMediaElement': The provided value is not of type 'MediaStream'
最佳答案
你问的是非常好的问题,我们所有人,流媒体视频开发者,在浏览器中的无插件近实时流媒体视频方面遇到了同样的问题并分享了同样的挫败感。
让我尽我所知回答您的问题(我在最近几年为流媒体服务器软件实现了 WebRTC 和媒体源扩展)
- “如果可以创建一个 MediaStream 并向其附加缓冲区,例如 MediaSource”
这个很简单 - 这是不可能的。媒体流 API: https://developer.mozilla.org/en-US/docs/Web/API/MediaStream 不公开对 MediaStream 对象的帧缓冲区的访问,它使用 WebRTC 在内部处理所有内容,使用 getUserMedia(来自本地网络摄像头)或来自 RTCPeerConeection(来自网络)获取帧。使用 MediaStream 对象,您无需直接操作帧或段。
当然,video.srcObject = mediaSource 将不起作用:video.srcObject 必须是由 WebRTC API 创建的 MediaStream 对象,没有别的。
- “如果浏览器以不同方式处理 src 和 srcObject,我无法在文档中找到”
是的,浏览器确实以非常不同的方式对待 video.src 和 video.srcObject;并且没有关于它的文档,也没有多大意义。政治在其中发挥了重要作用。
Chrome 浏览器中臭名昭著的例子:
一个。媒体源扩展 (video.src) 支持 AAC 音频,但 WebRTC (video.srcObject) 不支持,也永远不会支持。原因是 - 谷歌收购了太多音频压缩公司,其中之一 - Opus - 符合 WebRTC 规范,谷歌正在插入 Opus 成为新的“免版税”音频之王,因此 video.srcObject 中不支持 AAC,现在所有的硬件世界都必须实现 Opus。 因此,Google 可以并且在法律上允许向 Chrome 添加 AAC 支持,因为它是为媒体源扩展 (video.src) 这样做的。但它不会向 WebRTC 添加 AAC 支持,永远不会。
Chrome 在 video.src 和 video.srcObject 中对 H264 视频解码器使用不同的策略。 这没有任何意义,但这是事实。例如,在 Android 上,只有支持硬件 H264 解码的设备才会支持 WebRTC (video.srcObject) 中的 H264。没有硬件 H264 支持的旧设备将无法通过 WebRTC 播放 H264 视频。但相同的设备将通过媒体源扩展 (video.src) 播放相同的 H264 视频。因此,如果硬件不可用,video.src 必须使用软件解码器。为什么不能在 WebRTC 中做同样的事情?
最后,你的VP8流不会在iOS上播放,无论是Media Source Extensions(iOS根本不支持,哈哈哈),还是WebRTC(iOS只支持WebRTC的H264视频,哈哈哈).你问苹果为什么这样做?哈哈哈哈哈哈
关于javascript - Javascript 中的 MediaSource 与 MediaStream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51843518/