媒体流与轨道:MediaStream 与 MediaStreamTrack
媒体流与轨道MediaStream 与 MediaStreamTrack采集到的音视频用 MediaStream 封装里面包含多个 MediaStreamTrack。这篇讲流和轨道的关系、怎么操作轨道、怎么合并分流、怎么处理轨道事件以及实际开发中的常用技巧。大家好我是黒漂技术佬。getUserMedia 返回的是 MediaStream 对象里面装着视频轨、音频轨。流和轨道是 WebRTC 里最基础的数据结构搞懂它们才能灵活处理音视频。这篇讲 MediaStream 和 MediaStreamTrack 的详细用法添加移除轨道、克隆、事件、常用操作技巧。一、基本概念MediaStream媒体流一个媒体流对象可以包含多个轨道Track。MediaStream ├─ MediaStreamTrack视频轨 ├─ MediaStreamTrack音频轨 └─ ... 更多轨道MediaStreamTrack媒体轨道单一类型的媒体轨道要么是视频要么是音频。一个摄像头 一个视频轨一个麦克风 一个音频轨屏幕共享 一个视频轨可选的系统音频轨轨道的属性每个轨道有kind‘video’ 或 ‘audio’id唯一标识label设备名称enabled是否启用true/falsereadyState‘live’ 或 ‘ended’muted是否静音只读由系统决定二、MediaStream 常用操作创建空流conststreamnewMediaStream();// 空流后面加轨道从已有轨道创建conststreamnewMediaStream([videoTrack,audioTrack]);获取轨道// 所有轨道constallTracksstream.getTracks();// 只视频轨constvideoTracksstream.getVideoTracks();// 只音频轨constaudioTracksstream.getAudioTracks();// 按 ID 取consttrackstream.getTrackById(trackId);添加轨道stream.addTrack(videoTrack);stream.addTrack(audioTrack);移除轨道stream.removeTrack(videoTrack);克隆流constnewStreamstream.clone();克隆出的新流和原流独立轨道也是克隆的互不影响。流的活跃状态if(stream.active){console.log(流是活跃的);}所有轨道都结束了流就变成 inactive。三、MediaStreamTrack 常用操作开关轨道// 关闭画面变黑/静音track.enabledfalse;// 打开track.enabledtrue;enabled false 时轨道还在还占带宽只是发空数据。停止轨道track.stop();完全停止释放设备。停止后轨道就废了不能再用。获取轨道信息console.log(track.kind);// video / audioconsole.log(track.id);// 唯一IDconsole.log(track.label);// 设备名比如FaceTime HD Cameraconsole.log(track.readyState);// live / endedconsole.log(track.muted);// 是否被系统静音获取能力Capabilities设备支持什么参数constcapabilitiesvideoTrack.getCapabilities();console.log(capabilities);// {// width: { min: 320, max: 1920 },// height: { min: 240, max: 1080 },// frameRate: { min: 1, max: 60 },// ...// }获取当前约束Constraints当前用的什么参数constconstraintsvideoTrack.getConstraints();获取当前设置Settings实际生效的参数constsettingsvideoTrack.getSettings();console.log(settings.width,settings.height,settings.frameRate);注意getConstraints 是你请求的参数getSettings 是实际生效的参数可能不一样设备不支持的话会降级。应用新约束动态修改参数awaittrack.applyConstraints({width:640,height:480,frameRate:15});网络不好时降画质网络好时升回去都用这个。克隆轨道constnewTracktrack.clone();克隆一个一样的轨道独立控制。四、轨道事件onmute / onunmute轨道被系统静音/取消静音时触发track.onmute(){console.log(轨道被静音了);};track.onunmute(){console.log(轨道恢复了);};比如摄像头被其他程序占用了就会 mute。onended轨道结束时触发track.onended(){console.log(轨道结束了);};用户拔掉摄像头、调用 stop()、页面关闭都会触发。onoverconstrained约束条件设备满足不了时触发。五、流的事件onaddtrack / onremovetrack流里添加/移除轨道时触发stream.onaddtrack(event){console.log(添加了轨道:,event.track.kind);};stream.onremovetrack(event){console.log(移除了轨道:,event.track.kind);};onactive / oninactive流变成活跃/不活跃时触发。六、常用操作技巧1. 替换视频轨切换摄像头functionreplaceVideoTrack(stream,newVideoTrack){// 移除旧的constoldTrackstream.getVideoTracks()[0];if(oldTrack){stream.removeTrack(oldTrack);oldTrack.stop();}// 添加新的stream.addTrack(newVideoTrack);// 如果已经在 PeerConnection 里还要替换发送的轨道// sender.replaceTrack(newVideoTrack);}2. 静音/取消静音// 静音麦克风functionmuteAudio(stream){constaudioTrackstream.getAudioTracks()[0];if(audioTrack){audioTrack.enabledfalse;}}// 取消静音functionunmuteAudio(stream){constaudioTrackstream.getAudioTracks()[0];if(audioTrack){audioTrack.enabledtrue;}}3. 开关摄像头functiontoggleCamera(stream){constvideoTrackstream.getVideoTracks()[0];if(videoTrack){videoTrack.enabled!videoTrack.enabled;returnvideoTrack.enabled;}}4. 合并两个流把摄像头和屏幕共享合并到一个流functionmergeStreams(cameraStream,screenStream){constmergednewMediaStream();// 屏幕视频screenStream.getVideoTracks().forEach(tmerged.addTrack(t));// 摄像头音频或者两个都加看需求cameraStream.getAudioTracks().forEach(tmerged.addTrack(t));returnmerged;}5. 只取视频/只取音频// 从流里只提取视频轨生成新流functionvideoOnly(stream){returnnewMediaStream(stream.getVideoTracks());}// 只提取音频functionaudioOnly(stream){returnnewMediaStream(stream.getAudioTracks());}6. 拍照从视频轨抓帧functiontakePhoto(videoTrack){constcanvasdocument.createElement(canvas);constvideodocument.createElement(video);video.srcObjectnewMediaStream([videoTrack]);// 等视频就绪returnnewPromise(resolve{video.onloadedmetadata(){canvas.widthvideo.videoWidth;canvas.heightvideo.videoHeight;canvas.getContext(2d).drawImage(video,0,0);resolve(canvas.toDataURL(image/png));};});}七、视频轨道的特殊操作摄像头切换移动端asyncfunctionswitchCamera(currentStream){constcurrentTrackcurrentStream.getVideoTracks()[0];constfacingModecurrentTrack.getSettings().facingMode;constnewFacingModefacingModeuser?environment:user;constnewStreamawaitnavigator.mediaDevices.getUserMedia({video:{facingMode:newFacingMode},audio:true});// 停掉旧的currentStream.getTracks().forEach(tt.stop());returnnewStream;}画质动态调整根据网络情况动态改// 降画质asyncfunctionlowerQuality(track){awaittrack.applyConstraints({width:640,height:480,frameRate:15});}// 升画质asyncfunctionraiseQuality(track){awaittrack.applyConstraints({width:1280,height:720,frameRate:30});}配合 WebRTC 的带宽估计自动调画质。八、音频轨道的特殊操作音量检测用 Web Audio API 检测麦克风音量functiongetVolumeLevel(audioTrack){constaudioContextnewAudioContext();constsourceaudioContext.createMediaStreamSource(newMediaStream([audioTrack]));constanalyseraudioContext.createAnalyser();source.connect(analyser);constdataArraynewUint8Array(analyser.frequencyBinCount);functiongetVolume(){analyser.getByteFrequencyData(dataArray);letsum0;for(leti0;idataArray.length;i){sumdataArray[i];}returnsum/dataArray.length;}return{getVolume,audioContext};}可以做音量条、说话检测等功能。音频处理用 Web Audio API 可以加各种效果混响均衡器变声降噪处理完再通过 WebRTC 发出去。九、PeerConnection 中的轨道添加流旧 API还能用但不推荐pc.addStream(stream);添加轨道推荐新 API逐个轨道加pc.addTrack(videoTrack,stream);pc.addTrack(audioTrack,stream);第二个参数 stream 是关联的流对方收到时轨道会在同一个流里。替换轨道切换摄像头时用通话中切换摄像头不用重新协商constsenderpc.getSenders().find(ss.track.kindvideo);awaitsender.replaceTrack(newVideoTrack);replaceTrack 不用重新协商 SDP切换很快很平滑。接收端拿到轨道pc.ontrack(event){conststreamevent.streams[0];remoteVideo.srcObjectstream;};对方添加轨道后这边触发 ontrack 事件。十、常见坑坑 1enabled false 不省带宽很多人以为静音就不发数据了其实还在发只是发静音帧/黑屏帧。要省带宽得移除轨道或者用码率限制。坑 2stop 之后轨道就废了调用 stop() 后轨道就结束了不能再启用。要重新开得再 getUserMedia。坑 3克隆的轨道也要手动 stopclone() 出来的轨道是独立的原轨道 stop 了克隆的还在跑记得都要释放。坑 4流里可以有多个视频轨一个流可以加多个视频轨但不是所有播放器都支持显示多个。一般一个流一个视频轨一个音频轨。坑 5replaceTrack 不需要重新协商切换摄像头用 replaceTrack 就行不用重新 createOffer/Answer体验好很多。坑 6iOS 上轨道行为不一样iOS Safari 上页面切后台后视频轨会暂停回来可能要重新处理。十一、本篇小结MediaStream 容器装多个 MediaStreamTrackMediaStreamTrack 单个音/视频轨道是最小操作单元轨道操作enabled 开关、stop 停止、applyConstraints 改参数、clone 克隆流操作addTrack/removeTrack、clone、getTracks常用技巧切换摄像头、静音、合并流、分流、拍照、音量检测PeerConnection 中用 addTrack 添加replaceTrack 替换ontrack 接收注意enabled 不省带宽stop 后不可恢复克隆的轨道要手动释放下一篇讲RTCPeerConnection 连接建立SDP 协商、ICE 候选、完整的连接建立流程。我是黒漂技术佬。

相关新闻

连接器SI仿真精度提升:CST背景材料与边界条件3大关键参数设置

连接器SI仿真精度提升:CST背景材料与边界条件3大关键参数设置

CST连接器信号完整性仿真精度提升:背景材料与边界条件的三大黄金法则在高速数字电路和射频系统设计中,连接器的信号完整性(SI)仿真已成为产品开发流程中不可或缺的一环。作为电磁仿真领域的标杆工具,CST Studio Suite凭借其多物理场耦合能力和…

2026/7/7 1:01:47 阅读更多 →
如何用BilibiliCommentScraper高效获取B站视频完整评论数据?

如何用BilibiliCommentScraper高效获取B站视频完整评论数据?

如何用BilibiliCommentScraper高效获取B站视频完整评论数据? 【免费下载链接】BilibiliCommentScraper B站视频评论爬虫 Bilibili完整爬取评论数据,包括一级评论、二级评论、昵称、用户ID、发布时间、点赞数 项目地址: https://gitcode.com/gh_mirrors…

2026/7/7 1:01:47 阅读更多 →
深度解析:Windows平台ADB Fastboot驱动自动化安装工具的技术实现与应用

深度解析:Windows平台ADB Fastboot驱动自动化安装工具的技术实现与应用

深度解析:Windows平台ADB Fastboot驱动自动化安装工具的技术实现与应用 【免费下载链接】Latest-adb-fastboot-installer-for-windows A Simple Android Driver installer tool for windows (Always installs the latest version) 项目地址: https://gitcode.com/…

2026/7/7 0:57:45 阅读更多 →

最新新闻

6G:愿景、应用场景、架构与关键技术

6G:愿景、应用场景、架构与关键技术

6G:愿景、应用场景、架构与关键技术本文面向从事通信和信息技术的工程师与研究人员,系统梳理未来6G移动通信系统的主要方向。在5G的基础上,6G将进一步提升性能,引入新的业务场景,并与计算、控制和感知深度融合。文中包…

2026/7/7 2:04:05 阅读更多 →
计算机毕业设计之基于大数据的抖音音乐播放数据分析可视化

计算机毕业设计之基于大数据的抖音音乐播放数据分析可视化

基于大数据的抖音音乐播放数据分析可视化利用海量数据资源为用户提供个性化音乐推荐的服务平台。通过分析用户的听歌历史、喜好偏好、社交网络互动等多个维度数据,运用机器学习和数据挖掘技术,为用户提供精准、高效的音乐推荐。收集用户在抖音平台上的听…

2026/7/7 2:00:03 阅读更多 →
EhViewer安全架构深度解析:多层次防护机制的技术实现

EhViewer安全架构深度解析:多层次防护机制的技术实现

EhViewer安全架构深度解析:多层次防护机制的技术实现 EhViewer作为一款基于Material Design 3重构的漫画浏览应用,在提供流畅用户体验的同时构建了完善的安全防护体系。我们深入分析其安全架构,探讨如何在移动应用环境中实现Cookie管理、数据…

2026/7/7 1:58:02 阅读更多 →
【小白笔记】VS Code安装附加选项逐行解释

【小白笔记】VS Code安装附加选项逐行解释

VS Code安装附加选项逐行解释 一、附加快捷方式 创建桌面快捷方式(D) 勾选后安装完成,电脑桌面会出现VS Code图标,双击就能打开软件;不勾选只能从开始菜单找。 二、其他(推荐全部勾选,开发更方便)将“通过C…

2026/7/7 1:52:00 阅读更多 →
OpenSPARC T1 vs T2 架构对比:8核32线程与8核64线程的微架构演进分析

OpenSPARC T1 vs T2 架构对比:8核32线程与8核64线程的微架构演进分析

OpenSPARC T1与T2架构深度对比:从8核32线程到8核64线程的技术跃迁在开源处理器的发展历程中,OpenSPARC T1和T2无疑占据着里程碑式的地位。这两款由Sun公司开源的多核多线程处理器,不仅为学术界提供了宝贵的研究素材,也为工业界的设…

2026/7/7 1:52:00 阅读更多 →
AI之后,核聚变迎来第二个“加速器”?

AI之后,核聚变迎来第二个“加速器”?

如果说过去几年人工智能改变的是计算能力,那么核聚变领域正在发生的变化,则是工程控制能力的升级。 近期,国内高温超导托卡马克实验装置实现了1337秒(约22分钟)的等离子体稳态运行,刷新了商业高温超导托卡马克的公开纪录。这一成绩本身并不意味着已经实现可控核聚变发电…

2026/7/7 1:52:00 阅读更多 →

日新闻

鸿蒙新特性:图片画廊与轮播导航——构建沉浸式图片浏览体验

鸿蒙新特性:图片画廊与轮播导航——构建沉浸式图片浏览体验

图片浏览是移动应用中最高频的场景之一。从社交应用的照片流到电商平台的商品图集,从旅游应用的景点相册到摄影作品展示——用户对图片浏览的体验要求不断提高:流畅的切换动画、直观的缩略图导航、便捷的收藏操作、自动播放模式。HarmonyOS NEXT ArkUI 虽…

2026/7/7 0:05:16 阅读更多 →
24V DC-DC降压芯片PW2312B/PW2815,SOT23-6到SOP8-EP方案对比

24V DC-DC降压芯片PW2312B/PW2815,SOT23-6到SOP8-EP方案对比

24V稳压芯片完整选型指南 PW8600 PW75XX PW2815 PW2312B LDODC/DC全方案 一、24V稳压方案概述 24V直流电源在工业自动化、门禁系统、电梯控制、汽车电子、LED驱动、监控设备等场景中应用极广,是最常见的中压直流母线电压。要将24V母线稳定降压至下游MCU、传感器…

2026/7/7 0:05:16 阅读更多 →
RAG+知识图谱混合检索与Graph RAG核心对比

RAG+知识图谱混合检索与Graph RAG核心对比

做企业RAG落地的团队,往往容易卡在一容易踩坑的选型难题: 当需求单纯靠向量RAG搞不定、单纯靠知识图谱也搞不定,必须同时依赖「文本语义理解 实体关系推理」时,到底是做「向量图谱混合检索」就够了,还是必须上「Grap…

2026/7/7 0:07:19 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/6 8:11:50 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/6 8:11:52 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/6 6:52:56 阅读更多 →

月新闻