getTracks() 返回一个类数组的 MediaStreamTrack 列表,是同步获取的实时轨道快照,每个元素为 MediaStreamTrack 实例,非 Promise、非字符串、非配置对象。
getTracks() 是 MediaStream 实例上的方法,它返回一个 Array(确切说是 Array-like 的 TrackList),每个元素都是 MediaStreamTrack 实例。不是字符串、不是配置对象,更不是 Promise —— 它是同步返回的实时轨道快照。
常见错误现象:有人用 await stream.getTracks(),结果报错 “stream.getTracks is not a function” 或 “Promise expected”,其实只是因为误以为它是异步方法,或者把 MediaStream 和 MediaDevices.getUserMedia() 混为一谈。
getTracks() 本身不触发权限请求,也不触发设备采集 —— 它只读取已有流中已激活的轨道kind 过滤直接遍历 getTracks() 返回的列表,检查每个 MediaStreamTrack 的 kind、id、label 和 enabled 状态是最常用做法。注意:label 在非本地流(如远端 RTCPeerConnection 接收的流)中常为空字符串,不能作为唯一标识。
const tracks = stream.getTracks();tracks.forEach(track => { console.log({ id: track.id, kind: track.kind, // "audio" 或 "video" label: track.label, // 可能为空 enabled: track.enabled, // 是否启用(可被 mute) muted: track.muted // 是否静音(仅对音频有意义?错 —— video 也有 muted,但语义不同) });});
track.muted 表示该轨道是否被“静音”(音频)或“黑屏”(视频),由应用层控制,和 enabled 独立 —— enabled=false 表示轨道被禁用(不传输),muted=true 表示仍在传输但内容被压制getUserMedia 可能产生多个同名 label 的轨道,必须用 id 做唯一判别label 的填充较保守,尤其在 iframe 或非安全上下文中虽然 getTracks() 是底层通用接口,但实际开发中几乎总是优先用 getVideoTracks() 和 getAudioTracks() —— 它们返回过滤后的数组,语义清晰、代码意图明确,且避免手动 filter(t => t.kind === 'video') 的冗余。
立即学习“前端免费学习笔记(深入)”;
stream.getVideoTracks() 返回所有 kind === 'video' 的 MediaStreamTrack,空数组表示无视频轨道stream.getAudioTracks() 同理,且在 WebRTC 场景中常用于判断是否收到远端音频(例如:连接建立后检查 remoteStream.getAudioTracks().length > 0)getTracks() 做了简单过滤,没有额外开销getTracks() 返回的是**当时快照**,不代表轨道会一直存在。比如用户调用 track.stop()、或远端主动 removeTrack、甚至系统资源回收(如后台标签页冻结),都会导致轨道从流中移除 —— 此时再调用 getTracks() 就不再包含它。
getTracks() 结果长期使用;需要实时信息,就得每次调用stream.onremovetrack 事件比轮询更可靠,但注意该事件在 Chrome 中曾长期不触发(已修复),Safari 支持较晚,建议降级为周期性检查 getTracks().length 变化MediaStreamTrack 做操作前(如 track.enabled = false),先用 track.readyState === 'live' 判断是否仍有效,否则可能静默失败最常被跳过的细节是:你以为拿到的 track 还活着,其实它已经被 stop 或脱离流了 —— readyState 和 ended 属性才是唯一可信的状态依据。