Hi, 👋 ! 如果您发现有什么错误的地方,点这里可以提 issue,🤝🤝
by poplark
一般PC上摄像头的分辨率都能支持到 720P,我们创建一条 720P 的视频流,并拿到视频轨道,可以用以下代码实现:
let vt: MediaStreamTrack;
const constraints: MediaStreamConstraints = {
video: {
width: 1280,
height: 720,
frameRate: 20
}
}
navigator
.mediaDevices
.getUserMedia(constraints)
.then((stream) => {
vt = stream.getVideoTracks()[0];
})
.catch((err) => {
console.log(`创建流失败`);
});
一切正常的情况下,如果想改变这条视频轨道的分辨率,可以这样实现:
vt.applyConstraints({width: 640, height: 360, frameRate: 20});
同样的,一般情况下,如果刚开始创建时使用的是 360P 的分辨率,后面改成 720P 的,这样也可以:
vt.applyConstraints({width: 1280, height: 720, frameRate: 20});
这里也说了,是一般情况下,这个一般情况是限制在没有其他流占用摄像头。
有这样一个场景,页面中展示摄像头的画面,假设这个画面对应的流是 A,另有个设置功能,譬如设置弹出框,里面可以调节摄像头分辨率、多个摄像头时还可以切换,那么这里需要有个预览流,假设是 B
,在这种场景下,如果创建 A 时视频使用的约束条件为 { width: 640, height: 360, frameRate: 20 }
的话,在创建 B 时,如果使用的约束条件为 {width: 1280, height: 720, frameRate: 20}
,那么这时候,你将会发现 B 的视频的分辨率并不会是 720P
的,这就出现了 VideoTrack 的约束条件不生效 的现象。
上面的场景再调整一下,假设创建 A 时视频使用的约束条件为 { width: 640, height: 360, frameRate: 20 }
的话,在创建 B 时使用的约束条件也为 {width: 640, height: 360, frameRate: 20}
,那么假如你现在想改变 A 的分辨率 a.applyConstraints({width: 1280, height: 720, frameRate: 20})
,这时候,你将会发现 A 的视频的分辨率也不会是 720P
的,这也出现了 VideoTrack 的约束条件不生效 的现象。
简单解释一下,如果已经有流按某一约束条件访问了摄像头,那么后面再创建流时,将受第一条流的约束条件影响。而且如果摄像头并不为一条流独占(整个浏览器没有创建其他流,不单单是同一个页面内),它将无法重启摄像头,进而有可能无法改变分辨率之类的设置。这里的有可能会发生在分辨率从小改成大,而从大改到小则没影响,我理解这类似于软解,不重启摄像头,直接软件处理降低了分辨率。
tags: webrtc - MediaStreamTrack - MediaStreamConstraints