Javascript中的MediaSource与MediaStream有何区别?

21

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

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

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

这个方案效果很好,但存在一些(不到一秒钟)的延迟。可以说,这种解决方案并不是视频通话的最佳选择。

显然,某些 WebRTC 应用程序使用 MediaStream 替代:

video.srcObject = mediaStream;

......而这些都表现出无延迟。

我无法从文档中确定浏览器是否以不同方式处理srcsrcObject

我找不到的另一件事是是否可以创建一个MediaStream并向其附加缓冲区,就像使用MediaSource一样。 我想尝试一下,只是为了检查srcObject是否会导致我的应用程序出现前面提到的延迟。

如果我使用:

video.srcObject = mediaSource;

我遇到了以下错误:

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


4
如果你想要低延迟,你应该使用WebRTC。除了简单地在网络上传输数据之外,还有很多工作需要做。编解码器需要进行调整,需要适应拥塞控制,需要纠正抖动,需要配置缓冲以实现低延迟等等。 - Brad
我的(Windows)本地应用程序通过WebSocket传递WebM流,或者我可以只传递VP8流。MediaSource避免了WebRTC所需的ICE / DTLS / SRTP...我必须在本地应用程序中实现整个工作。让我困扰的是为什么相同的视频(vp8)流在MediaSource中显示有轻微延迟,在MediaStream中则没有延迟。我想找出差异所在。我尝试挖掘Chrome源代码,但没有成功... - Sergio
1
我在我的评论中告诉了你为什么。 - Brad
3个回答

29

你所提出的问题非常好,对于我们这些流视频开发人员来说,在涉及无插件、几乎实时的浏览器流视频方面,我们都会遇到相同的问题和困扰。

让我尽我所知回答你的问题(我最近几年已经实现了WebRTC和媒体源扩展,用于流媒体服务器软件)。

  1. “如果可以创建MediaStream并向其附加缓冲区,就像MediaSource一样?”

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

当然,“video.srcObject = mediaSource”是不起作用的:video.srcObject必须是由WebRTC API创建的MediaStream对象,没有其他东西。

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

当然,浏览器确实会非常不同地处理video.src和video.srcObject; 但是没有关于它的文档,这也没有太多意义。政治在其中起着很大的作用。

Chrome浏览器中的典型例子:

a. 媒体源扩展(video.src)支持AAC音频,但WebRTC(video.srcObject)不支持,也永远不会支持。原因是-谷歌收购了太多音频压缩公司之一-Opus-已经成为WebRTC规范,谷歌正在推动Opus成为新的“免费版权”音频标准,因此video.srcObject不支持AAC,所有硬件必须现在实施Opus。 因此,谷歌可以并且有合法权利向Chrome添加AAC支持,因为它在媒体源扩展(video.src)中这样做了。 但是,它不会向WebRTC添加AAC支持,永远不会。

b. Chrome在video.src和video.srcObject中使用不同的H264视频解码器策略。 这没有意义,但这是事实。例如,在Android上,仅支持硬件H264解码的设备才支持WebRTC中的H264(video.srcObject)。 没有硬件H264支持的旧设备将无法通过WebRTC播放H264视频。 但是,相同的设备将通过媒体源扩展(video.src)播放相同的H264视频。 因此,如果没有可用的硬件,则video.src必须使用软解码器。 为什么WebRTC不能做同样的事情呢?

最后,你的VP8流无法在iOS上播放,无论是在媒体源扩展(iOS根本不支持它,哈哈哈)还是在WebRTC中(iOS仅支持WebRTC的H264视频,哈哈哈哈)。 您问为什么苹果会这样做?哈哈哈哈哈


就纯解码和渲染延迟而言,您认为哪个会提供更低的延迟?假设 MSE 启用了低延迟模式。在什么情况下,您认为使用 MSE 而不是 WebRTC 是主要原因,反之亦然? - Zip
WebRTC将提供更低的延迟。 MSE中的延迟不幸会波动。 - user1390208
那么使用WebRTC,我们只需要信任浏览器来处理所有工作吗?我知道对于MSE,我们可以欺骗它(即将持续时间设置为无限或0),以进入“实时”低延迟模式,这使我们能够实现零缓冲。WebRTC能做到同样的事情吗? - Zip
是的,在WebRTC中,你必须相信浏览器完成所有工作;在下面的网页中,你可以比较使用MSE和WebRTC播放器从IP摄像头进行实时流传输的延迟:http://umediaserver.net/umediaserver/demos.html - user1390208
你应该编辑你的旧答案,包括新信息...这样人们就更容易找到信息了。 - user202729
1
这个答案有些过时了。将MediaSource赋值给src属性现在由WHATWG指定;对于那些只想为Chrome发布应用程序的人(羞耻!羞耻!羞耻!),Google/Chromium团队正在尝试一些自定义媒体跟踪生成API,但我却找不到它的链接,尽管我100%肯定我一周前读过它。 - Armen Michaeli

5
最后,您的VP8流无法在iOS上播放,无论是在媒体源扩展中(iOS根本不支持它,哈哈哈),还是在WebRTC中(iOS仅支持WebRTC的H264视频,哈哈哈哈)。您会问为什么苹果这样做?哈哈哈哈哈。
2020更新-现在iOS设备通过WebRTC支持VP8,并且新款iPad开始支持媒体源扩展。干得好,苹果!

0
video.srcObject = mediaStream
video.src = URL.createObjectURL(mediaSource)

已在Electron中测试(因此应该也可以在Chrome中运行)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接