HTML5的權限愈來愈大了,瀏覽器能夠直接調用攝像頭、麥克風了,好激動啊。咱們要用純潔的HTML代碼造出本身的天地。html
本篇介紹的栗子 都是在chrome 47 版本以上的,低版本的可能會出現白屏和錯誤。前端
隨着Chrome版本的升高,安全性問題也愈來愈被重視,較新版本的Chrome瀏覽器在調用一些API時須要頁面處在安全環境中。本篇文章所介紹的API函數,都須要在安全環境中執行。若是處在非安全環境下 ( http頁面 ) 這些API就會有意想不到的問題。html5
好比 getUserMedia()
就會報出警告,並執行出錯。而在設備枚舉enumerateDevices()
時,雖然不會報錯,可是他隱藏了設備label。nginx
getUserMedia() no longer works on insecure origins. To use this feature, you should consider switching your application to a secure origin, such as HTTPS. See https://goo.gl/rStTGz for more details.web
根據谷歌的意思,經常使用的安全環境有以下chrome
https 開頭的地址頁面服務器
若是你作了一個視頻測試的頁面,想嘚瑟給局域網的其餘人,可是又沒有域名證書怎麼辦?
這時候只能經過修改其餘人的hosts文件了
好比你的測試服務器IP地址是192.168.2.18,那麼其餘人的hosts文件修改以下:微信
#localhost 127.0.0.1 localhost 192.168.2.18
當使用別人的Chrome瀏覽器訪問 http://localhost/[getUserMedi...時,就會順利的執行這些API了。
可是移動端的瀏覽器並不認localhost,就算你修改了hosts ,移動端的瀏覽器根本不理你,解析都不解析。
因此想在手機上測試,只能老老實實申請個證書了。
在開啓攝像頭以前,先要把可使用的麥克風和攝像頭 ( 輸入設備 ) 列出來,若是沒有這兩樣設備也就沒法繼續。
代碼以下:
<label for="audioDevice"> 錄音設備: </label> <select id="audioDevice"> </select> <br> <label for="videoDevice"> 錄影設備: </label> <select id="videoDevice"> </select> <script> navigator.mediaDevices.enumerateDevices().then(function (data) { data.forEach(function (item) { if(item.kind=="audioinput"){ //麥克風 document.getElementById("audioDevice").innerHTML += "<option value='"+ item.deviceId +"'>" + item.label + " </option> " }else if(item.kind=="videoinput"){ //攝像頭 document.getElementById("videoDevice").innerHTML += "<option value='"+ item.deviceId +"'>" + item.label + " </option> " } }) },function (error) { console.log(error); }) </script>
效果以下圖,和瀏覽器本身獲取的如出一轍。
注意:上圖的實例中,瀏覽器地址欄最右邊的攝像頭標識是須要使用 getUserMedia()
函數時纔會出現。
<script> var getUserMedia = navigator.webkitGetUserMedia; //Chrome瀏覽器的方法 getUserMedia.call(navigator, { video:true, // 開啓音頻 audio:true // 開啓視頻 }, function(stream){ console.log(stream); // 成功獲取媒體流 }, function(error){ //處理媒體流建立失敗錯誤 }); </script>
這時候能夠經過瀏覽器給出的菜單下拉選擇設備。
咱們能夠經過代碼來指定使用哪一個攝像頭和麥克風設備。
也能夠經過代碼設置視頻的寬、高和幀率。
代碼以下:
<video id="video" autoplay></video> <!-- 必定要有 autoplay --> <script> var getUserMedia = navigator.webkitGetUserMedia ; getUserMedia.call(navigator, { "audio":{ "mandatory":{ "sourceId":"" // 指定設備的 deviceId } }, "video":{ "optional":[ {"minWidth":400}, {"maxWidth":400}, // 數字類型,固定寬度 {"minHeight":220}, {"maxHeight":220}, // 數字類型,固定高度 {"frameRate":"12"} // 幀率 ],"mandatory":{ "sourceId":"" // 指定設備的 deviceId } } }, function(stream){ //綁定本地媒體流到video標籤用於輸出 document.getElementById("video").src = URL.createObjectURL(stream); }, function(error){ //處理媒體流建立失敗錯誤 }); </script>
輸出的視頻流經過blob對象連接綁定到video標籤輸出。
這個deviceId
就是從上文設備枚舉 enumerateDevices()
獲取到的。
兩種設備,若是有一個deviceId
填寫不正確,就會報出一個DevicesNotFoundError
的錯誤。並且一旦指定了設備後,瀏覽器本身的設備選擇就會變成灰色不可選。
視頻的寬高,並不會由於填寫的數值比例不合法而失真。
好比你設定了寬度30,高度100,那麼他會從視頻中心截取 30x100 的畫面,而不是把原畫面擠壓到這個30x100的尺寸。
效果以下:
若是您的預覽一片漆黑,或者只有一個小黑點,那麼說明您的攝像頭正在被佔用...
吐槽:這個getUserMedia()
函數的參數,w3的官方文檔連接以下:
https://www.w3.org/TR/mediaca...
但是Chrome並無遵循它,並且差距還挺大...
Chrome瀏覽器是大力推廣webm的視頻格式的。能夠用MediaRecorder.isTypeSupported("video/webm")
來測試是否支持這種類型的編碼。若是返回true,那麼咱們錄製的視頻就能夠被保存爲這種指定的格式。若是不指定,那麼將會使用瀏覽器自動指定的文件格式。文檔原話以下
If this paramater is not specified, the UA will use a platform-specific default format.
可是這個默認值卻沒法直接獲取,全靠猜...
咱們使用 MediaRecorder
來錄製視頻,參數是經過getUserMedia()
獲取的媒體流。
經過綁定ondataavailable
事件,來獲取視頻片斷數據,並在內存中累積。
錄製的開始和結束分別使用 start
和stop
函數。
執行start
以後會週期性觸發ondataavailable
事件。
執行stop
以後會中止觸發ondataavailable
事件。
錄製結束後,把累計的片斷數據保存爲blob對象,並從瀏覽器下載存爲視頻文件。
代碼以下:
<script> var getUserMedia = navigator.webkitGetUserMedia ; var g_stream = null, g_recorder = null; function startPreview(){ getUserMedia.call(navigator, { video:true, audio:true }, function(stream){ g_stream = stream; }, function(error){ }); } function stopRecording(){ g_recorder.stop(); } function startRecording(){ var chunks = []; g_recorder = new MediaRecorder(g_stream,{mimeType:"video/webm"}); g_recorder.ondataavailable = function(e) { chunks.push(e.data); } g_recorder.onstop = function(e) { var blob = new Blob(chunks, { 'type' : 'video/webm' }); var audioURL = URL.createObjectURL(blob); window.open(audioURL); } g_recorder.start(); } </script>
注意:本例並無填寫視頻文件頭,因此保存出來的視頻文件沒有時間軌,沒法快進和跳躍。能夠用格式工廠轉
「莫基了」上面有一個錄製音頻的例子 傳送門
這篇文章的DEMO請戳 這裏
相關閱讀
多屏互動——H5中級進階
前端,想說愛你不容易!
無需Flash實現圖片裁剪——HTML5中級進階
做者信息
做者來自力譜宿雲 LeapCloud 團隊_UX成員:王詩詩 【原創】
力譜宿雲 LeapCloud 團隊首發:https://blog.maxleap.cn/archi...
歡迎關注微信訂閱號:MaxLeap_yidongyanfa