目录
1 源(Sources)与 接收器(Sinks)
2 MediaStreamTrack(轨道)
2.1 轨道的基本概念
2.2 轨道的生存周期(life-cycle)
2.3 轨道上的媒体流(Media Flow)
2.4 轨道接口相关的API
2.5 轨道所支持的约束
2.6 可约束的属性
2.7 轨道的能力 MediaTrackCapabilities
2.8 轨道的约束 MediaTrackConstraints
2.9 轨道的设置 MediaTrackSettings
3 MediaStream(流)
3.1 流的基本概念
3.2 流相关API
3.3 流与媒体标签元素
4 关于模型的应用示例
4.1 示例情景一
4.2 示例情景二
4.3 示例情景三
Media pipeline
浏览器提供了多媒体数据从源(sources)流向消费者或接收器(sinks)的媒体管线(media pipeline)。
Sources
源是一个理论上的实体,浏览器可以基于可用的设备以任意方式提供源。源本身是一个提供媒体数据的“东西”。大致可以将源分为两大类:
1)静态源:传统的源(sources)包括 流式的内容(内存中的数据),本地文件,网络资源。传统源所提供的的媒体数据一般是不随时间而变化的,这些源可以认为是静态的源。
2)动态源:getUserMedia API使得用户可以访问动态的源,比如 摄像头,麦克风。这些源的特征是可以响应应用程序的需求进行改变,这些源可以被认为是天然动态的。
“源” 本身没有约束 ,而轨道有约束。当源连接到轨道时,它必须生成符合该轨道上存在的约束的媒体。多个轨道可以连接到同一个源。WebRTC不能直接访问或控制源,对源的一切控制都通过轨道实施。对轨道应用约束,并且应用约束时可能会影响到隐藏在轨道背后的源。更改或应用轨道约束的行为可能会影响共享该源(source)的所有轨道的设置,从而影响共享该源的所有下层消费者(sinks)。 有些消费者(sinks)可能能够适配这种更改,例如
MediaStreamTrack
in question);MediaStreamTrack的属性:
MediaStreamTrack的方法:
MediaTrackSupportedConstraints字典代表了用户代理(UA,User Agent)当前能识别的所有可约束属性,UA通过这些属性来控制轨道对象的capabilities,未来规范可以通过partial关键字来扩展该字典的boolean成员以支持更多的属性。
上述UA所能识别的可约束属性可分为3类:
Property Name | Values | Notes |
---|---|---|
deviceId | DOMString | 该属性指定了为轨道提供媒体数据的源,该值与媒体设备MediaDeviceInfo.deviceId属性相匹配。该约束值可用于getUserMedia()方法,在获取用户媒体流时,指定设备. 但是,不要在运行时,调用applyConstraints()方法中使用该属性,因为该值在创建轨道,并与源绑定时就已经确定下来,无法更改,如果进行这种尝试只会导致一个无法满足的约束设置。如果在调用getUserMedia()方法,对该约束值设置为空字符串,则会被认定为该约束没有被指定。 |
groupId | DOMString | 该属性与deviceId,二者唯一指定了为轨道提供媒体数据的源,比如一个既可以提供音频,又可以提供视频的摄像头物理设备,在进行设备枚举时,会得到两个代表设备的MediaDeviceInfo对象,这两个对象的groupId相同,因为是同一物理设备,而两个MediaDeviceInfo对象的deviceId不同,分别代表音频输入设备和视频输入设备。与deviceId一样,可约束属性groupId也只用在getUserMedia()方法中指定提供媒体流的物理设备,一旦指定,成功生成媒体流后,与媒体流所关联的源就无法更改,也即在对轨道调用applyConstraints()方法时,不能再提供该属性的约束。 |
视频轨道独有的可约束属性
Property Name | Values | Notes |
---|---|---|
width |
|
指定单个宽度值或宽度范围,以像素为单位。作为一种能力,范围应该跨越视频源的预设高度值,其中min是最小高度,max是最大高度。 |
height |
|
指定单个高度值或高度范围,以像素为单位。 作为一种能力,范围应该跨越视频源的预设高度值,其中min是最小高度,max是最大高度。 |
frameRate |
|
指定单个帧率值或帧率的范围。如果帧率无法确定下来(比如,源不提供这种帧率,或者无法从源流确定帧率),则此值必须指代用户代理的vsync显示速率。 |
aspectRatio |
|
指定单个宽高比值或宽高比范围(以像素为单位的宽度除以以像素为单位的高度,表示为二次四舍五入到小数点后十位)。 |
facingMode |
|
此字符串(当为字符串列表时,每个字符串)应该是VideoFacingModeEnum的成员之一("user", "left","right","environment")。 从用户的角度来看,成员描述了相机可以面对的方向。 |
resizeMode |
|
此字符串(当为字符串列表时,每个字符串)应该是VideoResizeModeEnum的成员之一("none","crop-and-scale"),描述了是否允许UA对相机输出使用裁剪(crop)和缩小(downscaled )。如果是"none",那么分辨率只能是camera,驱动程序,os来提供的那些;如果是"crop-and-sacle",那么UA就可以通过对摄像头提供的高分辨率图像使用裁剪,缩小的手段来提供低分辨率的图像。 |
音频轨道独有的可约束属性
Property Name | Values | Notes |
---|---|---|
sampleRate |
|
指定单个音频采样率值,每秒采样点数。 |
sampleSize |
|
指定单个采样点所占位数,即线性样本大小(以位为单位),只有生成线性样本的音频设备才能满足此约束。 |
echoCancellation |
|
是否启用回声消除 |
autoGainControl |
|
是否启用自动增益 |
noiseSuppression |
|
是否启用噪声抑制 |
latency |
|
指定单个延迟值或延迟范围,以秒为单位。 延迟是处理开始(例如,当现实世界中发生声音时)与可用于该过程中下一步骤的数据之间的时间。 低延迟对某些应用至关重要; 高延迟对于其他应用程序可能是可接受的,因为它有助于功率限制。 该数字预计将是配置的目标延迟; 实际的延迟可能与目标延迟有一定的差别。 |
channelCount |
|
指定通道数 |
轨道对象的getCapabilities()方法返回MediaTrackCapabilities对象,该对象描述了轨道的能力Capabilities,绑定到同一个源的轨道,他们的Capabilities是相同的。
轨道对象的getConstraints()方法返回MediaTrackConstraints对象,该对象描述了应用到轨道上的约束。
轨道对象的getSettings()方法返回MediaTrackSettings对象,该对象描述了应用到轨道上的设置。
和
MediaStream赋值给标签的srcObject属性),Web实时通信(WebRTC的RTCPeerConnection
),媒体录制(MediaRecorder
),图像捕获(ImageCapture
),和网络音频(MediaStreamAudioSourceNode
)。MediaStream的构造函数
MediaStream提供3类构造函数:
MediaStream的属性
id(readonly,DOMString):当MediaStream被创建时,用户代理生成一个标识符字符串并赋值给id,一个好的做法是使用UUID,它的规范形式长度为36个字符;
active(readonly,boolean):如果MediaStream是活动的,那么该值为true,否则为false;而MediaStream是否为active状态,取决于MediaStream所包含的MediaStreamTrack集合中是否存在一个MediaStreamTrack为非ended状态;若MediaStream集合中不存在MediaStreamTrack或者所有的MediaStreamTrack均为ended状态,那么该MediaStream为inactive状态,active属性为false。
onaddtrack(EventHandler):事件处理函数句柄,当MediaStream调用addTrack()方法,成功添加新的track时,触发addtrack事件。
onremovetrack(EventHandler):事件处理函数句柄,,当MediaStream调用removeTrack()方法,成功删除MediaStream中已存在的一个track时,触发removetrack事件。
MediaStream的方法
getAudioTracks():返回流的轨道集合中所有表征音频轨道的MediaStreamTrack序列。MediaStreamTrack的kind属性为"audio",并且在两次调用getAudioTracks()返回的序列中轨道的排列顺序可能是不一致的。
getVideoTracks():返回流的轨道集合中所有表征视频轨道的MediaStreamTrack序列。MediaStreamTrack的kind属性为"video",并且在两次调用getVideoTracks()返回的序列中轨道的排列顺序可能是不一致的。
getTracks():返回流的轨道集合中所有轨道的列表,不管轨道的kind属性是"video"还是"audio",并且在两次调用getTracks()返回的序列中轨道的排列顺序可能是不一致的。
getTrackById():返回流的轨道集合中MediaStreamTrack的id属性与入参trackId相匹配的MediaStreamTrack,或者返回bull,如果没找到匹配的MediaStreamTrack。
addTrack():添加一个指定的MediaStreamTrack到MediaStream对象中,当该方法被调用时,内部将按如下步骤进行处理:
1) 如果指定的轨道已经在流中,则停止处理;
2)添加轨道到流中的集合中;
3)触发addtrack事件。
removeTrack():从MediaStream对象的轨道集合中删除指定的MediaStreamTrack,当该方法被调用时,内部将按如下步骤进行处理:
1) 如果指定的轨道不在流中,则停止处理;
2)删除轨道集合中指定的轨道;
3)触发removetrack事件。
clone方法:克隆流以及流中的所有轨道,该方法被调用时,内部将按如下步骤处理:
1)让克隆出的新的流对象streamClone是一个新构建的MediaStream对象;
2)让streamClone的id属性是一个新生成的值,与原来的流相区别;
3)克隆原来的流中的每个轨道,并将克隆的轨道添加到streamClone的轨道集合中;
4)返回这个新的MediaStream对象streamClone。
一个MediaStream对象可以赋给一个网页的media元素。MediaStream对象是不可预加载,不可seek的,表现为一个简单的,无无限时长的,线性媒体时间线。时间线从0开始,并随着MediaStream的播放而实时的线性递增。当MediaStream的播出暂停时,时间线不会递增。支持本规范的UA,HTMLMediaElement接口必须支持srcObject属性,该属性可以为播放MediaStream对象提供支持。以下几点为HTMLMediaElement元素的媒体提供者是MediaStream时所呈现出来的特性:
MediaStream的性质对关联HTMLMediaElement的属性行为以及可对其执行的操作施加了某些限制,如下所示:
Attribute Name | Attribute Type | Setter/Getter Behavior When Provider is a MediaStream | Additional considerations |
---|---|---|---|
preload |
DOMString |
读取: none . 设置: 忽略. |
MediaStream不支持预加载。 |
buffered |
TimeRanges |
buffered.length返回0 . |
MediaStream不支持预加载。因此,缓存保持为空的TimeRange |
currentTime |
double |
任意非负整数。初始化值为0,当媒体在播放时,实时地线性增加该值 |
该值为播放位置,单位s。任何尝试修改该值将被忽略。 |
seeking |
boolean |
false |
MediaStream不支持seek。因此该属性一直返回false。 |
defaultPlaybackRate |
double |
读取: 1.0 . 设置: ignored. |
MediaStream不支持seek。因此,该属性(倍速播放)一直返回1.0,任何尝试修改此属性会被忽略。因此不会触发ratechange事件 |
playbackRate |
double |
读取: 1.0 . 设置: ignored. |
MediaStream不支持seek。因此,该属性(倍速播放)一直返回1.0,任何尝试修改此属性会被忽略。因此不会触发ratechange事件 |
played |
TimeRanges |
played.length 返回1 .played.start(0)返回 0 .played.end(0)返回最新的 currentTime . |
MediaStream时间线总是由单个范围值组成,0~currentTime |
seekable |
TimeRanges |
seekable.length返回 0 . |
MediaStream不支持seek |
loop |
boolean |
true , false |
设置loop属性没有任何作用,因为MediaStream没有定义媒体数据的结尾,因此无法循环播放。 |
为了说明给定源(source)的更改如何影响各种Sinks,请考虑以下示例。 此示例仅使用宽度和高度这两个约束属性,但相同的原则适用于本规范中公开的所有约束属性。 图中,本地客户端从其本地摄像机获得了视频源, 源的宽度和高度设置分别为800像素和600像素。 本地客户端上的三个MediaStream对象包含使用同一deviceId的轨道(MediaStreamTrack),三个媒体流连接到三个不同的sink:
请注意,此时,本地客户端上的所有 Sinks 必须对源所提供的内容进行维度转换:Sink B缩小(scale down)视频,Sink A放大(scaling up)视频(导致质量下降),而Sink C也在略微缩放视频以便通过网络发送。 在远程客户端上,Sink Y缩小(scale down)视频,而Sink Z不应用任何缩放。
当本地客户端上的三个MediaStream中与该源(Home client video source)绑定的某个MediaStreamTrack需要更高的分辨率图像(1920x1200像素),从而调用轨道的applyConstraints()方法时,这个源的设置将受到影响,从而设置为1920x1200。如下图所示:
此时,请注意,源更改会立即影响本地客户端上的与该源关联的所有轨道和Sinks,但不会影响远程客户端上的Sinks(或Sources)。 变化如下:随着本地客户端源视频尺寸的增加,Sink A不再需要执行任何缩放,而Sink B必须比以前更进一步缩小。 Sink C(对等连接)现在必须按比例缩小视频到1024x768,以使传输保持与远程客户端不变。
上述示例没有展示的一种情况是:相等的合法设置请求可以发生在远程客户端这一侧。除了Sink Y和Sink Z会受到像上述Sink A,B,C一样受到的影响外,还会导致对等媒体对象之间(Remote client video source与Home client video sinks)重新进行媒体协商,从而改变Home client video sinks在其应用在本地客户端视频源上的转换(比如由缩小变为扩大)。这种改变并不会改变Sink A,Sink B和本地客户端的视频源的任何东西。
注意:规范并没有定义这样一个机制:远程客户端视频源(图中remote client's video source)的改变自动触发本地客户端视频源的改变。实现可能会选择这种source-to-sink的优化,但是仅在应用之间建立的约束范围之内,就像下面将要介绍的这个示例。
情景一描述了某个指定源上的改变将会影响到相关的Sinks消费者。然而,在某些情形下,对于Sink的改变会引发实现去调整源的设置。如下图所示,本地客户端视频源发送的视频流分辨率为1920x1200,并且视频源是未受约束的,因此就应用而言,确切的源尺寸是灵活可变的。两个媒体流对象MediaStream包含使用同一deviceId的轨道MediaStreamTrack,并且这两个媒体流对象MediaStream关联到两个不同的
当应用改变Sink A的大小到1200x768时,浏览器的媒体管线(media pipeline)将会识别到没有Sinks需要更高的视频源分辨率,此时,若不进行调整,不仅是源还是Sink A需要做一些不必要的工作。在此种情况下,如果没有其他约束强制源继续提供高分辨率的视频流,那么媒体管线(media pipeline)可能会去改变源的分辨率(如下图所示)。
如上图,本地客户端视频源的分辨率将改变为Sink A和Sink B中的较大者以优化播放。
然后上述没有展示的情况是,对于PeerConnections和其他类型的Sinks,也会执行相同的行为。
可能会出现这么一个情况:对一个轨道应用关联的源无法满足的约束,这种无法满足,可能是因为源本身无法满足约束,也可能是源已经被应用了相冲突的约束。当此种情况发生时,applyConstraints()返回的Promise将是rejected,并且任何新的约束将不会被应用,此时,源本身也就不需要做任何改变。
示例如下,两个媒体流对象MediaStream各自含有一个视频轨绑定同一个源。第一个轨道初始时没有应用任何约束,其连接到Sink N。Sink N大小为800x600,将源所提供的1024x768的视频流转换成800x600进行展示。另外一个轨道包含一个强制性的约束条件,即强制源关闭其补光模式。该轨道连接到Sink P,其宽高与源相同。
现在,第一个轨道添加一个强制约束,即源的补光模式强制开启。此时,源无法同时满足这两个强制性约束(补光模式无法同时开启又关闭)。这个状态是在第一个轨道上应用产生冲突的约束导致,因此,这个约束将应用失败,并且源上的设置不会改变,应用在另一个轨道上的约束也不会改变。