本文使用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
解除關聯,方便將它釋放。
小結
示例使用的WebRTC的功能。顯示的是本地攝像頭的視訊,不涉及傳輸。拿到視訊流後交給video
來顯示。
getUserMedia
是示例中最關鍵的方法。以後的示例都會用到它。
參考
效果預覽
完整的效果請參考
open-camera