WebRTC视频分辨率设置

WebRTC视频分辨率设置

前面我们能够打开摄像头。getUserMedia()时会传入参数,在参数里我们可以指定宽高信息。通过宽高参数控制输出的视频分辨率。

html#

在页面上摆放一些元素,下面是主要部分

<div id="container">    <div id="buttons">        <button id="stop">停止</button>        <button id="b320">320x240</button>        <button id="b240-320">240x320</button>        <button id="b640">640x480</button>        <button id="b1280">1280x720</button>        <button id="b1920">1920x1080</button>        <button id="b2048">2048x1152</button>    </div>    <div id="videoblock" style="display: none">        <p id="dimensions" style="height: 1em;"></p>        <video playsinline autoplay style="background: none;height: auto;width: auto;"></video>        <div id="width">            <label>Width <span></span>px:</label>            <input type="range" min="0" max="7680" value="0">        </div>        <input id="isFullWidth" type="checkbox">视频宽度100%<br>        <input id="aspectlock" type="checkbox">锁定宽高比<br>    </div>    <p id="msg" style="display: none;"></p></div><script src="../js/adapter-latest.js" async></script> <!-- 使用本地的适配器 --><script src="js/main.js" async></script>
  • button 一些按钮用来选择分辨率
  • videoblock 用来显示视频,默认隐藏
  • dimensions 用来现实视频的一些信息
  • video 宽高先设置为auto
  • #width input 滑动选择视频的宽度
  • isFullWidth 让video宽度为100%
  • msg 显示错误信息

js#

拿到一些元素

const dimensionsInfo = document.querySelector('#dimensions');const video = document.querySelector('video');let stream;const videoblock = document.querySelector('#videoblock'); // 视频区域const messagebox = document.querySelector('#msg');const widthInput = document.querySelector('div#width input');const widthOutput = document.querySelector('div#width span');const aspectLock = document.querySelector('#aspectlock');const fullWidSetting = document.querySelector('#isFullWidth');

启动视频#

先把拿到流的处理方法写出来

function gotStream(mediaStream) {  stream = window.stream = mediaStream; // 给控制台  video.srcObject = mediaStream;  messagebox.style.display = 'none';  videoblock.style.display = 'block';  const track = mediaStream.getVideoTracks()[0];  const constraints = track.getConstraints();  console.log('当前constraints: ' + JSON.stringify(constraints));  if (constraints && constraints.width && constraints.width.exact) {    widthInput.value = constraints.width.exact;    widthOutput.textContent = constraints.width.exact;  } else if (constraints && constraints.width && constraints.width.min) {    widthInput.value = constraints.width.min;    widthOutput.textContent = constraints.width.min;  }}

拿到视频流后,track.getConstraints()获取信息,显示出当前信息并修改ui。

以按钮320为例

document.querySelector('#b320').onclick = () => {  const c320 = {    video: { width: { exact: 320 }, height: { exact: 240 } }  };  startPlay(c320);};function startPlay(constraints) {  stopStream();  clearMsg();  videoblock.style.display = 'none';  navigator.mediaDevices.getUserMedia(constraints)    .then(gotStream)    .catch(e => {      showErrMsg('getUserMedia报错 ' + e, JSON.stringify(constraints));    });}function stopStream() {  if (stream) {    stream.getTracks().forEach(track => {      track.stop();    });  }}
  • 定义配置c320,设定宽为320,高伟240
  • 先把视频停下来
  • 调用getUserMedia并把参数配置传进去

还可以监听video的变化

let currentWidth = 0;let currentHeight = 0;// 显示视频尺寸信息function displayVideoDimensions(whereSeen) {  if (video.videoWidth) {    dimensionsInfo.innerText = '实际video尺寸: ' + video.videoWidth +      'x' + video.videoHeight + 'px.';    if (currentWidth !== video.videoWidth ||      currentHeight !== video.videoHeight) {      console.log(whereSeen + ': ' + dimensionsInfo.innerText);      currentWidth = video.videoWidth;      currentHeight = video.videoHeight;    }  } else {    dimensionsInfo.innerText = '拿不到video的宽度';  }}// 载入meta信息video.onloadedmetadata = () => {  displayVideoDimensions('loadedmetadata');};// 修改了尺寸video.onresize = () => {  displayVideoDimensions('resize');};

载入信息或者尺寸改变的时候显示出来。

定义了多种常见的分辨率

document.querySelector('#b640').onclick = () => {  const c640 = {    video: { width: { exact: 640 }, height: { exact: 480 } }  };  startPlay(c640);};document.querySelector('#b1280').onclick = () => {  const c1280 = {    video: { width: { exact: 1280 }, height: { exact: 720 } }  };  startPlay(c1280);};

滑动调整#

我们放置了一个inputtype="range",它可以左右滑动。滑动的时候我们改变视频设置的宽度。宽度信息也显示在界面上。

widthInput.onchange = onConstraintChange;function onConstraintChange(e) {  widthOutput.textContent = e.target.value;  const track = window.stream.getVideoTracks()[0];  let constraints;  if (aspectLock.checked) {    constraints = {      width: { exact: e.target.value },      aspectRatio: {        exact: video.videoWidth / video.videoHeight      }    };  } else {    constraints = { width: { exact: e.target.value } };  }  clearMsg();  console.log('使用配置 ' + JSON.stringify(constraints));  track.applyConstraints(constraints)    .then(() => {      console.log('配置成功');      displayVideoDimensions('applyConstraints');    })    .catch(err => {      showErrMsg('配置失败 ', err.name);    });}

改变的宽度写在constraints里,注意需要指定exact参数。
window.stream.getVideoTracks()[0]获取到track(视频轨)。
调用track.applyConstraints(constraints)让修改后的参数生效。同样这里可以监听配置是否成功。

点不同的按钮,可以看到视频的尺寸不同。

在电脑显示器上测试,选择尺寸过大时,会报错OverconstrainedError。

小结#

本次示例也是getUserMedia()方法的使用。前面打开摄像头我们只指定了video: true。在这个示例里我们指定了宽高信息。并以此控制输出的视频分辨率。
视频正在显示的时候,也可以用track.applyConstraints方法来修改视频的分辨率。

效果#

网页效果预览

原文链接WebRTC视频分辨率设置

推荐阅读