zoukankan      html  css  js  c++  java
  • 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; 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: {  { 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: {  { exact: 640 }, height: { exact: 480 } }
      };
      startPlay(c640);
    };
    
    document.querySelector('#b1280').onclick = () => {
      const c1280 = {
        video: {  { 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 = {
           { exact: e.target.value },
          aspectRatio: {
            exact: video.videoWidth / video.videoHeight
          }
        };
      } else {
        constraints = {  { 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视频分辨率设置

    一个软件工程师的记录
  • 相关阅读:
    进阶之路 | 奇妙的Drawable之旅
    进阶之路 | 奇妙的Animation之旅
    进阶之路 | 奇妙的四大组件之旅
    Laravel
    Laravel 入门
    面试:给我说说你平时是如何优化MySQL的?
    EXPLAIN 查看 SQL 执行计划
    常见的图文布局
    常见的图文布局
    CSS3 的 filter(滤镜) 属性
  • 原文地址:https://www.cnblogs.com/rustfisher/p/15655442.html
Copyright © 2011-2022 走看看