动态切换摄像头或麦克风需用 mediastreamtrack.applyconstraints() 更新已有轨道约束,先 enumeratedevices 获取 deviceid,再对 videotracks[0] 或 audiotracks[0] 应用 {deviceid: {exact: "xxx"}};须预先获取权限、处理异步失败、兼容旧浏览器回退至 getusermedia 重建流。

在Web应用中动态切换摄像头或麦克风,核心是通过 MediaStreamTrack 的 applyConstraints() 方法更新轨道约束,而非重新调用 navigator.mediaDevices.getUserMedia()。关键在于:先获取设备列表,再找到目标设备的 deviceId,最后对已激活的音视频轨道施加新约束。
获取可用媒体设备并识别前后摄像头
调用 navigator.mediaDevices.enumerateDevices() 获取所有输入设备,过滤出 videoinput 类型,并通过 label 或 getCapabilities().facingMode 判断朝向:
-
注意:部分浏览器(如 Safari)可能不暴露
label,需依赖facingMode; -
facingMode值为"user"(前置)、"environment"(后置),但仅在设备支持且已获得权限后才可读取; - 建议先请求一次权限(如
getUserMedia({video: true})),再枚举设备以确保能力信息完整。
对已有视频轨道切换摄像头
假设已有一个活跃的 MediaStream,从中取出 videoTracks[0],然后调用 applyConstraints 设置目标 deviceId:
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
- 约束对象形如
{deviceId: {exact: "xxx..."}},使用exact确保匹配指定设备; - 切换过程是异步的,需处理
Promise的then和catch,失败常见原因包括设备被占用、权限被拒或设备已断开; - 无需停止旧轨道或创建新流,切换后画面自动更新,
onmute/onunmute可监听状态变化。
切换麦克风需单独处理音频轨道
音频轨道切换逻辑与视频一致,但要注意:
- 必须针对
audioTracks[0]调用applyConstraints,不能作用于视频轨道; - 若当前流未开启音频(
audio: false),需先用getUserMedia({audio: true})获取音频轨道并添加到流中; - 某些系统(如 macOS)可能限制同时访问多个麦克风,切换前建议
track.stop()旧音频轨道再启用新设备。
兼容性与降级处理
并非所有浏览器都支持动态 deviceId 切换(如旧版 Firefox 对 applyConstraints 的 deviceId 支持有限):
- 可检测
track.getCapabilities().deviceId是否存在,判断是否支持精确设备选择; - 不支持时,回退方案是
stream.getTracks().forEach(t => t.stop()),再调用getUserMedia重建流; - 始终监听
devicechange事件,在用户插拔设备后刷新可用列表。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










