首页 > 解决方案 > Javascript 中的 MediaSource 与 MediaStream

问题描述

我的 Javascript 应用程序通过 Websocket 连接获取 WebM 视频流。远程对等方发送视频帧和应用程序获取它们之间没有延迟。

我在应用程序中创建了一个MediaSource对象,我“附加视频帧”,并让一个视频元素显示它:

video.src = window.URL.createObjectURL(mediaSource);

这很好用,但是有一些(不到一秒)延迟,可以说这个解决方案对于视频通话来说不是最佳的。

显然,一些 WebRTC 应用程序使用MediaStream

video.srcObject = mediaStream;

...而且这些显示没有延迟。

我无法从文档中确定浏览器的处理src方式是否srcObject不同。

我找不到的另一件事是是否可以MediaStream像使用MediaSource. 我想尝试一下,只是为了检查是否srcObject不会导致我的申请出现上述延迟。

如果我使用:

video.srcObject = mediaSource;

我得到错误:

TypeError:无法在“HTMLMediaElement”上设置“srcObject”属性:提供的值不是“MediaStream”类型

标签: javascriptvideomedia-sourcemediastream

解决方案


您问的是非常好的问题,我们所有人,流媒体视频开发人员,在浏览器中的无插件近实时流媒体视频方面遇到同样的问题并分享同样的挫败感。

让我尽我所知解决您的问题(近年来,我为流服务器软件实现了 WebRTC 和媒体源扩展)

  1. “如果可以创建 MediaStream 并向其附加缓冲区,例如 MediaSource”

这很容易 - 这是不可能的。MediaStream API: https ://developer.mozilla.org/en-US/docs/Web/API/MediaStream 不公开对 MediaStream 对象的帧缓冲区的访问,它使用 WebRTC 在内部处理所有内容,或者使用 getUserMedia 获取帧(来自本地网络摄像头),或来自 RTCPeerConeection(来自网络)。使用 MediaStream 对象,您无需直接操作帧或段。

当然,video.srcObject = mediaSource是行不通的:video.srcObject 必须是 WebRTC API 创建的 MediaStream 对象,仅此而已。

  1. “如果浏览器以不同方式处理 src 和 srcObject,我无法在文档中找到”

是的,浏览器确实对待 video.src 和 video.srcObject 非常不同;并且没有关于它的文档,并且没有多大意义。政治在其中扮演着重要角色。

来自 Chrome 浏览器的臭名昭著的例子:

一个。媒体源扩展 (video.src) 支持 AAC 音频,但 WebRTC (video.srcObject) 不支持,也永远不会。原因是 - 谷歌收购了太多的音频压缩公司,其中之一 - Opus - 使其符合 WebRTC 规范,而谷歌正在推动 Opus 成为新的“免版税”音频之王,因此在 video.srcObject 中不支持 AAC,现在所有硬件世界都必须实施 Opus。因此,Google 可以并且在法律上允许将 AAC 支持添加到 Chrome,因为它是针对媒体源扩展 (video.src) 进行的。但它永远不会向 WebRTC 添加 AAC 支持。

湾。Chrome 在 vi​​deo.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视频,哈哈哈)。你问苹果为什么要这么做?哈哈哈哈哈


推荐阅读