web技術分享| WebRTC控制攝像機平移、傾斜和縮放

anyRTC發表於2022-03-10

MediaDevices.getUserMedia() 會提示使用者給予使用媒體輸入的許可,媒體輸入會產生一個 MediaStream ,裡面包含了請求的媒體型別的軌道。此流可以包含一個影片軌道(來自硬體或者虛擬影片源,比如相機、影片採集裝置和螢幕共享服務等等)、一個音訊軌道(同樣來自硬體或虛擬音訊源,比如麥克風、A/D轉換器等等),也可能是其它軌道型別。

它返回一個 Promise 物件,成功後會 resolve 回撥一個 MediaStream 物件。若使用者拒絕了使用許可權,或者需要的媒體源不可用, promise reject 回撥一個   PermissionDeniedError 或者 NotFoundError

引數

  • constraints

    constraints 引數是一個包含了 video audio 兩個成員的 MediaStreamConstraints 物件,用於說明請求的媒體型別。必須至少一個型別或者兩個同時可以被指定。如果瀏覽器無法找到指定的媒體型別或者無法滿足相對應的引數要求,那麼返回的Promise物件就會處於rejected[失敗]狀態, NotFoundError 作為rejected[失敗]回撥的引數。

const constraints = {

   video: {
       pan: true,
       tilt: true,
       zoom: true
   }
};

async function init(e) {
   try {
       const stream = await navigator.mediaDevices.getUserMedia(constraints);
       handleSuccess(stream);
       e.target.disabled = true;
   } catch (e) {
       handleError(e);
   }
};

document.querySelector('#showVideo').addEventListener('click', e => init(e));
  • getVideoTracks() 方法 返回代表此流中影片軌道 MediaStream 的物件序列 。 MediaStreamTrack

    • 一組 MediaStreamTrack 物件,媒體流中包含的每個影片軌道都有一個物件。影片軌道是那些 kind 屬性為的軌道 video 。如果流不包含影片軌道,則該陣列為空。

  • getCapabilities 方法返回一個   MediaTrackCapabilities 物件,此物件表示每個可調節屬性的值或者範圍,該特性依賴於平臺和user agent.

  • getSettings() 方法返回一個 MediaTrackSettings 物件,該物件包含 current 的每個可約束屬性的當前值 MediaStreamTrack

  • applyConstraints() 方法將一組約束應用於軌道;這些約束讓網站或應用程式為軌道的可約束屬性(例如幀速率、尺寸、回聲消除等)建立理想值和可接受的值範圍。

function handleSuccess(stream) {

     const video = document.querySelector('video');
     const videoTracks = stream.getVideoTracks();
     video.srcObject = stream;

     const capabilities = videoTracks[0].getCapabilities();
     const settings = videoTracks[0].getSettings();
     for (const ptz of ['pan', 'tilt', 'zoom']) {
       if (!(ptz in settings)) {
         continue;
       }
       const input = document.querySelector(`input[name=${ptz}]`);
       input.min = capabilities[ptz].min;
       input.max = capabilities[ptz].max;
       input.step = capabilities[ptz].step;
       input.value = settings[ptz];
       input.disabled = false;
       input.event => {
             try {
               const constraints = {advanced: [{[ptz]: input.value}]};
               await videoTracks[0].applyConstraints(constraints);
             } catch (err) {
               console.error('applyConstraints() failed: ', err);
             }
       };
     }
}

function handleError(error) {
 console.log(`getUserMedia error: ${error.name}`, error);
}
<style>

   div.label {
       display: inline-block;
       font-weight: 400;
       margin: 0 0.5em 0 0;
       width: 3.5em;
   }
   video {
       background: #222;
       margin: 0 0 20px 0;
       width: 500px;
       height: 400px;
   }
</style>
       
<body>
   <video id="gum-local" autoplay playsinline></video>
   <button id="showVideo">Open camera</button>

   <div>
       <div>Pan:</div>
       <input name="pan" type="range" disabled>
   </div>
   <div>
       <div>Tilt:</div>
       <input name="tilt" type="range" disabled>
   </div>
   <div>
       <div>Zoom:</div>
       <input name="zoom" type="range" disabled>
   </div>
</body>


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70013909/viewspace-2869106/,如需轉載,請註明出處,否則將追究法律責任。

相關文章