WebRTC打開本地攝像頭

本文使用WebRTC的功能,打開電腦上的攝像頭,並且把攝像頭預覽到的圖像顯示出來。
純網頁實現,能支持除IE外的多數瀏覽器。手機瀏覽器也可用。

引入依賴

我們需要引入adapter-latest.js

<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>

這個WebRTC adapter曾是WebRTC中的一部分,但現在被移出來了。
我們會用到它提供的功能。

html

我們在界面上先擺放一些控件。

<div id="container">
    <video id="video-local" autoplay playsinline></video>
    <button id="showVideo">打開攝像頭</button>
    <button id="stopVideo">關閉攝像頭</button>
    <p>顯示攝像頭預覽的內容,網頁上由元素video來呈現。</p>
    <p>點擊打開攝像頭按鈕後,瀏覽器會詢問是否允許,請點擊“允許”。</p>
    <div id="errorMsg"></div>
    <div id="tipMsg"></div>
</div>
  • video 用來顯示預覽的視頻
  • 兩個button用來控制開啓和關閉
  • 再放幾個顯示信息的地方

js

先設置一下,我們只使用視頻

const constraints = window.constraints = {
  audio: false,
  video: true
};

在網頁上顯示一些信息,便於調試。

function showErrMsg(msg, error) {
  const errorElement = document.querySelector('#errorMsg');
  errorElement.innerHTML += `<p>${msg}</p>`;
  if (typeof error !== 'undefined') {
    console.error(error);
  }
}

function showMsg(msg) {
    const msgEle = document.querySelector('#tipMsg');
    msgEle.innerHTML += `<p>-> ${msg}</p>`;
    console.log(msg);
}

完整代碼在main.js中。css可自行定義。

打開攝像頭

要打開攝像頭,使用MediaDevices.getUserMedia()方法

async function openCamera(e) {
  try {
    showMsg('正在打開攝像頭');
    const stream = await navigator.mediaDevices.getUserMedia(constraints);
    showMsg('獲取到了stream');
    gotStream(stream);
    e.target.disabled = true;
  } catch (err) {
    onErr(err);
  }

MediaDevices.getUserMedia()方法在用戶允許後,按照請求,拿到stream。
stream可以包含視頻或音頻。前面的設定裏,我們只使用視頻。

如果用戶拒絕了使用攝像頭申請,或者申請的媒體不可用,即表現爲被拒絕。
用戶拒絕會報NotAllowedError,找不到符合要求的設備會報NotFoundError DOMException

方法的文檔MediaDevices.getUserMedia()

顯示視頻

獲取到stream後,讓video顯示視頻

function gotStream(stream) {
  const videoEle = document.querySelector('video');
  const videoTracks = stream.getVideoTracks();
  showMsg(`正在使用的設備: ${videoTracks[0].label}`);
  window.stream = stream;
  videoEle.srcObject = stream;
}

document.querySelector('video')直接獲取html上的video控件。
把stream直接交給videoEle.srcObject

停止視頻流

要停止視頻,我們可以從video元素入手,拿到stream,然後把裏面的track停掉。

function stopVideo(e) {
    showMsg("停止視頻");
    const videoElem = document.querySelector('video');
    const stream = videoElem.srcObject;

    document.querySelector('#showVideo').disabled = false; // 允許開啓

    if(stream == null) {
        return;
    }
    const tracks = stream.getTracks();
  
    tracks.forEach(function(track) {
      track.stop();
    });
    videoElem.srcObject = null;
}

stream.getTracks()方法拿到所有的軌道(track),遍歷一遍全部關掉。
最後,把videoElem.srcObject設置爲null,它與前面的stream解除關聯,方便將它釋放。

參考 MediaStreamTrack-stop

小結

示例使用的WebRTC的功能。顯示的是本地攝像頭的視頻,不涉及傳輸。拿到視頻流後交給video來顯示。
getUserMedia是示例中最關鍵的方法。以後的示例都會用到它。

參考

效果預覽

簡易效果請參考 open-camera | rustfisher

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章