這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 1. 背景 一般業務也很少接觸攝像頭,有也是現成的工具庫掃個二維碼。難得用一次,記錄下踩坑。 2.調用攝像頭的方法 2.1. input <!-- 調用相機 --> <input type="file" accept="image/*" ...
這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助
1. 背景
一般業務也很少接觸攝像頭,有也是現成的工具庫掃個二維碼。難得用一次,記錄下踩坑。
2.調用攝像頭的方法
2.1. input
<!-- 調用相機 --> <input type="file" accept="image/*" capture="camera"> <!-- 調用攝像機 --> <input type="file" accept="video/*" capture="camcorder"> <!-- 調用錄音機 --> <input type="file" accept="audio/*" capture="microphone">
這個就不用多說了,缺點就是沒辦法自定義界面,它是調用的系統原生相機界面。
2.2. mediaDevices
由於我需要自定義界面,就像下麵這樣:
所以我選擇了這個方案,這個api
使用起來其實很簡單:
<!-- 創建一個video標簽用來播放攝像頭的視屏流 --> <video id="video" autoplay="autoplay" muted width="200px" height="200px"></video> <button onclick="getMedia()">開啟攝像頭</button>
async getMedia() { // 獲取設備媒體的設置,通常就video和audio const constraints = { // video配置,具體配置可以看看mdn video: { height: 200, wdith: 200, }, // 關閉音頻 audio: false }; this.video = document.getElementById("video"); // 使用getUserMedia獲取媒體流 // 媒體流賦值給srcObject this.video.srcObject = await window.navigator.mediaDevices.getUserMedia(constraints); // 直接播放就行了 this.video.play(); }
可以看到這個效果。
// 截圖拍照 takePhoto() { const video = document.getElementById("video"); // 藉助canvas繪製視頻的一幀 const canvas = document.getElementById("canvas"); const ctx = canvas.getContext('2d'); ctx.drawImage(this.video, 0, 0, 300, 300); }, // 停止 stopMedia() { // 獲取媒體流 const stream = this.video.srcObject; const tracks = stream.getTracks(); // 停止所有軌道 tracks.forEach(function (track) { track.stop(); }) this.video.srcObject = null; }
3.坑
如果你複製我的代碼,在localhost
上肯定能運行,但是你想在手機上試試的時候就會發現很多問題。
3.1. 需要https
由於瀏覽器的安全設置,除了localhost
和https
連接,你都沒辦法獲取到navigator.mediaDevices
,列印出來是undefined
。如果要在手機上測試,你要麼用內網穿透代理一個https
,要麼部署在https
功能變數名稱的伺服器上測試。
3.2. 設置前後攝像頭
預設是使用user
設備,也就是前攝像頭,想要使用後攝像頭也是有配置的,
async getMedia() { // ... let constraints = { video: { height: 200, wdith: 200, // environment設備就是後置 facingMode: { exact: "environment" }, }, audio: false }; // ... }
3.3. 設置顯示區域大小
我的需求是鋪滿整個設備,所以我想當然的直接把video
樣式寬高設置成容器大小:
#video { width: 100%; height: 100%; } async getMedia() { // .... // 將寬高設置成容器大小 const pageSize = document.querySelector('.page').getBoundingClientRect() let constraints = { video: { height: pageSize.height, width: pageSize.width, facingMode: { exact: "environment" }, }, audio: false }; //.... }
發現這個視頻橫著而且沒有鋪滿屏幕。
通過輸出video
的信息可以看到,設備返回的視頻流寬高是反的:
所以配置換一下就行了:
let constraints = { video: { height: pageSize.width, width: pageSize.height, }, };