MediaStreamTrack
W3C 文档Media Capture and Streams中定义的接口是开发 WebRTC 应用程序时需要了解的关键接口之一。
此接口表示源自一个媒体源(例如麦克风或网络摄像头)的媒体。从这个接口,应用程序可以访问媒体,无论它来自物理或虚拟设备、生成器(例如文件或画布)还是来自对等连接。
但是,尽管这个接口看起来很容易使用,但该MediaStreamTrack
接口提供了几个管理其全局状态的属性。我花了一些时间了解如何解释它的价值和应对变化。
我有兴趣在本地执行操作时查看轨道状态,并了解远程端的后果(如果存在)。
和往常一样,这并不像人们想象的那么容易……
ReadyState:轨道生命周期
我想了解 a 的第一件事MediaStreamTrack
是它的生命周期。
在这里,它看起来很简单,因为只有 2 个状态:live
和ended
。
在能够呈现媒体live
时。MediaStreamTrack
相反,当处于 时ended
,该轨道将不承载任何媒体。这是永久性的,无论赛道发生了什么。因此,不会再从该轨道渲染任何媒体。绝不。
这可以通过多种方式发生:
- 用户停止源:这是最常见的切换方式
ended
- 来源中没有更多可用数据
- 用户撤销了对设备的访问权限。
- 生成源数据的设备已断开连接、移除或弹出,或出现故障。
为了访问状态,提供了公开当前值的MediaStreamTrack
属性。readyState
我试图readyState
根据已完成的操作恢复双方的演变方式。
从这张图中,有3点需要注意:
- 在轨道或媒体源上进行的直接操作会改变其状态
- 对 track 进行的间接操作
RTCPeerConnection
不会影响轨道的状态,这是正常的,因为 trackRTCPeerConnection
只是一种通信介质,因此没有它轨道也可以继续存在。 - 在远程端,只有当与发送方关联的收发器停止时,轨道才会受到影响。注意,关闭
RTCPeerConnection
本地端对远程端的轨道没有影响。
如果您不依赖其他事件来更新应用程序,最后一点可能会导致应用程序出现一些奇怪的行为。我预计远程轨道会移动到,ended
因为没有更多可用数据。但是浏览器并没有这样实现。
在远程对等点上没有镜像轨道的事实对我来说是一个混乱的根源。
启用或禁用
当轨道呈现音频或视频时,它被启用。当轨道可以渲染时,有MediaStreamTrack
一个属性enabled
等于true 。
应用程序可以通过将此属性设置为 false 来使轨道“静音enabled
” 。然后轨道被禁用。禁用时,轨道输出呈现黑帧(视频轨道)或静音(音频轨道)。
请注意,对于视频轨道,禁用轨道时网络摄像头的指示灯不会关闭。
如图所示,远程端不知道此更改。enabled
无论本地所做的更改如何,远程端的轨道都会保持不变。这就是为什么,这种静音/取消静音的方式需要一些额外的信令消息来通知远程应用程序。
所以,我不知道如何处理enabled
从RTCPeerConnection
.
同样,此属性的值不会在远程端复制。
静音或取消静音
当轨道呈现音频或视频时,它是未静音的。这是接口muted
的另一个属性,当轨道可以渲染时MediaStreamTrack
它等于false 。
此处的区别在于此属性大部分不受应用程序的控制。没有 API 可以直接更改此值。只是一个吸气剂。
静音与启用不同。muted属性指示轨道当前是否能够提供媒体输出。
在大多数情况下,可以通过按下设备上的物理静音按钮或通过从操作系统将设备的输入音量更改为 0 来获得静音轨道。在这些情况下,本地音轨变为静音。
从该enabled
属性可以看出,当轨道在本地“物理上”或“外部”静音时,在远程端,没有任何变化,也没有传播任何事件。
muted
此图总结了影响本地或远程端属性的操作:
- 在设备或操作系统上执行的外部操作会修改本地轨道,而不会对远程端产生任何影响
- 在轨道上的直接操作(例如停止它)具有奇怪的行为,或者这可能是由于设备本身造成的,但在我的测试中,停止视频轨道会将远程轨道更改为静音,而音频则不是这样。
- 使用 ORTC API 和重新协商对轨道进行的间接操作将远程轨道更改为静音
- 最后,使用
setParameters
fromRTCRtpSender
接口来防止发送编码(通过将active
属性设置为 false)将远程轨道更改为muted。静音时不会发送任何数据包,但请记住,在此期间相机不会关闭。
全局图片
我更喜欢分开并拥有一张全局图片来了解本地的状态MediaStreamTrack
,另一张用于远程端的状态。
在本地
在本地方面,轨道的状态非常清楚。
4 个状态可以分为 2 类:
- 当曲目能够提供媒体时:这对应于状态Active where
readyState
= “lived” ,enabled
= true ,muted
= false - 当曲目无法提供媒体时:这对应于其他 3 种状态Disabled、Muted和Ended
虚拟设备大部分时间都处于活动状态,如果不使用本文中讨论的其他方法,则很难检测到
无论在应用程序外部发生什么,由于onmute
和onunmute
事件,轨道都知道。
在应用程序中,对轨道的直接操作(例如更改属性enabled
或调用stop()
方法)会直接更改轨道的状态。
这里,除了虚拟设备,如果轨道是活动的,应用程序应该接收媒体。而在其他情况下,应用程序能够通过检查收到的内部属性和事件来做出反应。
在远端
在远程端,情况有点不同。
我保留了 4 个状态,分为两类:
- 当轨道的状态是可预测的:Muted和Ended。从这些步骤来看,曲目是否可以提供媒体并不存在混淆。如果曲目处于这些状态之一,则不会提供任何媒体。
- 当轨道的状态不可预测时:Active和Remotely Disturbed。具体来说,这是相同的状态,因为与 properties 和 关联的所有值
readyState
在两种状态下都是相同的。此时,远端应用程序需要依赖其他信息(通过信令层发送)来正确解释轨道状态。因为,当处于Remotely Disturbed状态时,所有属性似乎都表明应用程序应该接收媒体,但从用户的角度来看,情况有所不同……enabled
muted
状态Remotely Disturbed包括远程应用程序强制的情况,例如禁用轨道时或非强制的情况,例如远程端出现问题时。
注意:WebRTC Statistics API、Audio API 或 WebCodecs API 等其他 API 可用于提供有关传入媒体的附加信息。
MediaStreamTrack 方向
W3C 正在讨论一些演变,例如应用程序在更改时适应共享内容的可能性。对于这种特殊情况,W3C 想到了一个新paused
属性,可以进行更改然后继续流式传输。
另一个演变涉及一个新configurationchange
事件,当其配置(例如约束)发生变化时,该事件可能会从轨道本身触发。
另外,关于双静音(app + device)的问题已经公开了一段时间,但由于涉及隐私问题,目前还没有达成共识。
结论
尽管MediaStreamTrack
现在所有 WebRTC 场景都使用了该接口,但对我来说,仍有一些潜在的用例不干净。远程轨道可以被认为与本地轨道不同步的事实是一个复杂的因素。
因此,在大多数情况下,信令层被用来发送额外的信息,使刚刚发生的事情有意义(没有一个好的信令层是很难生存的…)。
作者:Olivier Anguenot
原文链接:https://webrtc-developers.com/state-of-a-mediastreamtrack/
本文来自作者投稿,版权归原作者所有。如需转载,请注明出处:https://www.nxrte.com/jishu/webrtc/12837.html