司項目需要調用攝像頭,看了一下html5文檔,主要是使用html5的getUserMedia()API,寫一個例子來記錄具體的使用方法。
<html> <body> <!-- 用于展示攝像頭視頻流 --> <video id="video" autoplay style="width: 480px;height: 320px"></video> <div> <button id="capture" onclick="handleClickCapture()">拍照</button> </div> <!-- 展示拍攝的照片 --> <canvas id="canvas" width="480" height="320"></canvas> <script> var video = document.getElementById('video'); var capture = document.getElementById('capture'); var ctx = document.getElementById('canvas').getContext('2d'); /** * 調用用戶媒體設備 * @param constraints 配置信息 * @param success 成功回調函數 * @param error 失敗回調函數 */ function getUserMediaToPhoto(constraints,success,error) { if(navigator.mediaDevices.getUserMedia){ navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error); }else if (navigator.webkitGetUserMedia) { navigator.webkitGetUserMedia(constraints,success,error); }else if(navigator.mozGetUserMedia){ navigator.mozGetUserMedia(constraints,success,error); }else if(navigator.getUserMedia){ navigator.getUserMedia(constraints,success,error); } } /** * 成功回調函數 * @param stream 視頻流 */ function success(stream){ var CompatibleURL = window.URL || window.webkitURL; try { video.src = CompatibleURL.createObjectURL(stream); } catch (e) { video.srcObject = stream; } video.play(); } /** * 失敗回調 * @param error 錯誤對象 */ function error(error) { console.log('無法訪問媒體設備', error); } if(navigator.mediaDevices.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.getUserMedia){ getUserMediaToPhoto({video:{width:480,height:320}},success,error); }else{ alert('不支持訪問用戶媒體設備'); } /** * 拍照按鈕點擊事件 */ function handleClickCapture() { ctx.drawImage(video,0,0,480,320); } </script> </body> </html>
實現了基本的攝像頭調用和拍照,實現思路非常簡單,基本上只是在調用api,唯一惡心的地方在于api版本比較多,不得不多做一些判斷。具體的api介紹、使用和參數可以查看MediaDevices.getUserMedia()。
外小哥利用了幾行代碼直接訪問了手機的相機功能,這聽起來是一件很新鮮的事情。究竟是怎么實現的呢?感興趣的話,可以繼續了解下去哦。
這位國外小哥是從事網頁開發的工程師,海外網友都叫他Austin Gil。
既然是從事網頁開發設計的,對HTML、java、CSS等相關網頁語言都很熟悉了。
Austin Gil采用了最簡單的網頁語言,僅用HTML,實現了在網頁上點擊按鈕就能夠直接打開手機前置鏡頭來拍照。也可以調用手機后置鏡頭,開啟錄像模式。
整個編譯過程,利用了HTML的capture屬性,設置幾個input參數和加上幾行代碼就搞定了,不費吹灰之力。
雖然用JavaScript或其它的方法也可以實現,但比起別的方法,這樣能夠便捷地獲取用戶相機權限,而且不用擔心安全問題。
很多人都想知道相關代碼,接下來會提到的,一起來看看吧。
教你使用HTML打開相機:
首先創建一個index.html文檔,配合HTML的accpet屬性,來指定不同標簽所要capture的文件的具體屬性。
Austin Gil設置了“environment”和“user”兩個標簽。
點擊“environment”,可以調用相機的后置鏡頭,且可以錄像;
點擊“user”,可以打開相機前置鏡頭拍照。
具體代碼如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<style>
* {
font-size: 1.5rem;
}
</style>
</head>
<body>
<label for="environment">Capture environment:</label>
<br>
<input
type="file"
id="environment"
capture="environment"
accept="video/*"
>
<br><br>
<label for="user">Capture user:</label>
<br>
<input
type="file"
id="user"
capture="user"
accept="image/*"
>
</body>
</html>
從這些代碼中,我們可以捕獲到一個信息,就是沒有提示用戶是否打開訪問相機的權限,網頁就直接調用了相機。
問題是,這樣操作,沒有安全風險嗎?
當很多人提出疑惑的時候,Austin Gil做出了解釋:無額外風險。
瀏覽器其實并不能真正控制手機相機APP,即便是這樣操作可以直接訪問,但也只不過是能輕松上傳相機生成的新文件而已。
簡單來說,就是對于用戶而言,瀏覽器通過HTML只能打開手機攝像頭。如果要把照片、視頻展示到網站上,或是想要保存下來,還得用到JavaScript的MediaDevices API。
這樣操作是比純用JavaScript更安全的。
因為運用JavaScript,在用戶允許訪問相機后,瀏覽器就能直接控制攝像頭了。
而在Web 3.0標準之后,規定網頁不能直接訪問用戶的手機鏡頭。
PS:現在主要用的是Web 5的標準。
最后是兼容性,據悉在這方面并不是很好。
Austin Gil指出,這種直接通過HTML指令打開用戶攝像頭的方式目前還存在不足,比如兼容性不太好。
如下圖所示:
紅色模塊:不支持
綠色模塊:支持
棕色模塊:部分支持
灰色:未知
很多網友在好奇心的驅使下,測試了調用手機相機的代碼。也有前端小哥進行了測試,結果如下:
點擊environment和user按鈕,在MacBook上分別可以打開視頻格式和圖片格式的文件;而在iPhone上,使用百度等瀏覽器,真的可以直接打開前置和后置攝像頭!
好咯,本期內容就分享到這里了~
PC 端網頁調用攝像頭的場景想必大家并不陌生,打開一個網址,開啟攝像頭開始筆試/視頻聊天/直播等。
而在移動端網頁調用攝像頭的場景你見得多嗎?我想答案應該是不多吧(在下見識淺薄)。
H5 相較于native app 一直被詬病的就有調用手機原生能力差這一點。
但需求總是會突如其來,做與不做?
其實,做與不做都不應該影響你去貯備相關知識、做較為充分的調研。市面上類似的技術實現不多,不代表不能做。真的不能做,也至少得知道原因吧?
也許在你探尋的過程中,就會有不一樣的發現。
方案一就是 webRTC,也正是 PC 端的實現方案。
WebRTC (Web Real-Time Communications) 是一項實時通訊技術,它允許網絡應用或者站點,在不借助中間媒介的情況下,建立瀏覽器之間點對點(Peer-to-Peer)的連接,實現視頻流和(或)音頻流或者其他任意數據的傳輸。WebRTC包含的這些標準使用戶在無需安裝任何插件或者第三方的軟件的情況下,創建點對點(Peer-to-Peer)的數據分享和電話會議成為可能。 —— MDN-WebRTC_API
核心的API為:navigator.mediaDevices.getUserMedia
Can I Use:看一下這個 API 的兼容情況
https://caniuse.com/?search=GetUserMedia
本瓜結合網上代碼,小做修改,放到了線上。
在線測試地址:https://tuaran.site/static/webrtc.html
貼下關鍵代碼
<body>
<div>H5調前置攝像頭DEMO</div>
<video id="video" width="480" height="320" muted controls autoplay="autoplay">
</video>
<div>
<button id="capture">拍照</button>
</div>
<canvas id="canvas" width="480" height="320"></canvas>
<script>
//訪問用戶媒體設備的兼容方法
function getUserMedia(constraints, success, error) {
if (navigator.mediaDevices.getUserMedia) {
//最新的標準API
navigator.mediaDevices.getUserMedia({
'audio':{ echoCancellation: false },
'video':{ 'facingMode': "user" }//調用前置攝像頭,后置攝像頭使用video: { facingMode: { exact: "environment" } }
})
.then(success)
.catch(error)
} else if (navigator.webkitGetUserMedia) {
//webkit核心瀏覽器
navigator.webkitGetUserMedia(constraints, success, error)
} else if (navigator.mozGetUserMedia) {
//firfox瀏覽器
navigator.mozGetUserMedia(constraints, success, error);
} else if (navigator.getUserMedia) {
//舊版API
navigator.getUserMedia(constraints, success, error);
}
}
let video = document.getElementById('video');
let canvas = document.getElementById('canvas');
let context = canvas.getContext('2d');
function success(stream) {
//兼容webkit核心瀏覽器
let CompatibleURL = window.URL || window.webkitURL;
//將視頻流設置為video元素的源
console.log(stream);
//video.src = CompatibleURL.createObjectURL(stream);
video.srcObject = stream;
video.play();
}
function error(error) {
console.log(`訪問用戶媒體設備失敗${error.name}, ${error.message}`);
}
if (navigator.mediaDevices.getUserMedia || navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia) {
//調用用戶媒體設備, 訪問攝像頭
getUserMedia({ video: { width: 480, height: 320 } }, success, error);
} else {
alert('不支持訪問用戶媒體');
}
document.getElementById('capture').addEventListener('click', function () {
context.drawImage(video, 0, 0, 480, 320);
})
</script>
</body>
用 video 播放視頻,如果想要實現截屏,則用 canvas 進行繪制。
從上圖和實踐中可以得出,WebRTC調起攝像頭的方案 PC 端支持良好,但移動端瀏覽器支持不一。 國內的安卓機自置瀏覽器大部分為低版本的 chrome 內核分支,加殼嵌套,更新緩慢。iOS 對于 Vedio 標簽屬性的兼容也不盡如人意。
這里安利一個第三方庫 tracking.js
它上面有關于 face_camera 的 demo 正用的此解決方案。
調用前置攝像頭代碼實現:
<input class="phone_input" type="file" accept="video/* capture="user" />
https://caniuse.com/?search=capture
同樣把代碼放到了線上,在線測試地址 https://tuaran.site/static/capture.html
PC 不支持,iOS 支持良好,少部分 Android 機存在兼容差異(部分8.0以上安卓機無法調起前置,會調起后置)。
WebRTC | capture |
PC 支持 | PC 不支持 |
移動端兼容性混亂 | 移動端兼容性較優 |
可自定義視頻分辨率/窗口大小等(直播流) | 無法自定義(本地全屏錄制) |
代碼實現復雜 | 代碼實現簡單 |
綜上:在移動端網頁調起攝像頭,WebRTC 方案兼容性較差,但可自定義程度很高,可操作視頻流、設定分辨率、調整窗口大小等,實現近似 app 調用攝像頭的效果,但相應的實現難度就高、兼容也相對復雜;而 capture 方案兼容性較好,但只是調用原生的相機進行一段視頻錄制,可自定義程度不高。如果視頻過大,壓縮等也將是一個問題。如何平衡二者?可以在兼容的情況下使用前者,不兼容的情況下使用后者,瀏覽器才是最終的答案。
本瓜相信 H5 一定將會有更多更好的能力!
我是掘金安東尼: 一名人氣前端技術博主(文章 100w+ 閱讀量)
終身寫作者(INFP 寫作人格)
堅持與熱愛(簡書打卡 1000 日)
我能陪你一起度過漫長技術歲月嗎(以夢為馬)
覺得不錯,給個三連吧(這是我最大的動力 ) b( ̄▽ ̄)d
*請認真填寫需求信息,我們會在24小時內與您取得聯系。