MediaStreamTrack.getSettings().width/height:它告诉你的是“当前输出尺寸”,而非“摄像头物理分辨率”
在WebRTC开发中,一个常见的误解是:MediaStreamTrack.getSettings()返回的width和height就是摄像头的物理分辨率。其实不然。它返回的,更像是该视频轨道(track)**当前正在生效的配置参数快照**。这里的width和height,代表浏览器**经过协商后最终采用的视频输出尺寸**。
关键点在于:这个值不等于摄像头传感器的最大能力,也不保证一定能稳定输出这个尺寸。它受到你设定的约束条件(constraints)、设备自身的硬件能力、甚至系统当前的负载等多重因素影响,并且可能随着后续调用applyConstraints()而动态变化。

getSettings() 返回的 width/height 究竟是什么?
当你调用track.getSettings()时,得到的是这个MediaStreamTrack对象运行时的一个设置“定格”。举个例子:如果你通过getUserMedia获取视频流时,指定了约束条件如{ width: { ideal: 1280 }, height: { ideal: 720 } },而设备恰好支持,那么getSettings().width很可能就是1280,height是720。
但这里有个“但书”:它也可能是设备在匹配你的约束后,实际选中的另一个值,比如640×480,或者1920×1080。这完全取决于约束匹配的最终结果。
所以,我们可以总结几个核心要点:
- 它反映的是**当前生效的输出尺寸**,而不是摄像头的极限能力。
- 如果你没有显式设置宽高约束,这个值可能是
undefined,或者是浏览器采用的某个默认值(比如常见的640×480)。 - 这个值在track的整个生命周期中并非一成不变,比如你动态调整约束并应用后,它就会更新。
如何正确获取信息:结合 getCapabilities() 与 getSettings()
想要更全面地了解你的摄像头“能做什么”和“正在做什么”,最好的方法是配合使用几个API:
立即学习“前端免费学习笔记(深入)”;
track.getCapabilities():查看设备硬件支持的分辨率范围(width/height的min/max/step)。这是它的“能力清单”。track.getSettings():查看当前实际使用的宽高。这是它的“实时状态”。track.getConstraints():查看你上次通过applyConstraints()设置的目标参数。注意,这只是“目标”,不一定已经生效。
来看一段示例代码,理解它们之间的关系:
const stream = await na vigator.mediaDevices.getUserMedia({ video: true });
const videoTrack = stream.getVideoTracks()[0];
console.log('当前设置:', videoTrack.getSettings());
// 输出可能类似:{ width: 1280, height: 720, ... }
console.log('设备能力:', videoTrack.getCapabilities());
// 输出可能类似:{ width: { min: 640, max: 1920, step: 1 }, height: { ... }, ... }
console.log('当前约束:', videoTrack.getConstraints());
// 输出可能类似:{ width: { ideal: 1280 }, height: { ideal: 720 } }
需要注意的兼容性与常见陷阱
虽然getSettings()在现代浏览器中已得到广泛支持(Chrome 52+、Firefox 50+、Safari 11+、Edge 79+),但在实际使用中仍有几个“坑”需要留意:
- 对音频轨道调用此方法,返回的对象通常是空的,或者根本不包含
width/height字段。 - 当轨道已经停止(
track.readyState === 'ended')时,调用getSettings()可能返回空对象,甚至抛出错误。 - 在一些老旧的安卓WebView或定制浏览器中,即使轨道工作正常,返回的宽高值也可能是
undefined。 - 仅靠
getSettings()无法获取帧率(frameRate)、编码格式、是否启用HDR等高级参数,这些信息需要查看返回对象中的其他字段。
进阶:如何动态监听分辨率变化?
如果你的应用需要响应分辨率的自动切换(例如在网络条件降级后,浏览器可能会自动缩放输出),该怎么办?一个直接的想法是监听track.onended事件,或者在调用applyConstraints()后轮询getSettings()。
但更可靠的方式其实是:在调用applyConstraints()并等待其Promise解析(resolve)之后,立即读取getSettings()。这时获取到的尺寸信息,最能代表约束应用后的实际状态。
示例代码如下:
await videoTrack.applyConstraints({
width: { exact: 640 },
height: { exact: 480 }
});
// 约束应用完成后,立即读取
console.log('应用后实际尺寸:', videoTrack.getSettings()); // 此时的数据更可信
