getUserMedia/WebRTC助力跨瀏覽器攝像頭捕獲影像

概覽

隨着Firefox支持getUserMedia,三個主要的桌面瀏覽器能夠實現無需使用插件即可從攝像頭中獲取數據。因爲現在仍處於初期階段,所以瀏覽器之間的實現略有不同。下面的例子展示如何應對這些不同,並用一個腳本來幫助你做這些繁重的工作,但是首先必須瞭解這三款瀏覽器都是怎麼工作的。



getUserMedia 是通過在about:config中將 media.peerconnection.enabled option 設置爲 true 啓用的.


開始編碼時會遇到各種差異,不過沒關係,現在就讓我們一起來一步一步看怎麼解決這些問題。成功使用getUserMedia將按如下步驟爲大家一一介紹:


1. 一點HTML5小知識
2. 特徵檢測
3. 視頻流
4. 準備就緒
5. 最後一點小提示
深吸一口氣哦,好戲即將開始…


一點HTML5小知識

在這個簡短的教程中,我們的主要任務是只是爲了將一個動態圖像顯示在一個頁面中。視頻都是普通視頻,所以第一步是在HTML文件中引入一個簡單的<video>元素:



就這樣。沒有控制,沒有源碼,什麼都沒有。

在JavaScript中,需要得到關聯到<video>元素,我們可以這樣做(或者用一個id):





特徵檢測

在我們檢查getUserMedia支持時事情就變得有趣起來。我們絕對不會使用不可靠的用戶代理去做嗅探 – 絕不,我們將用檢查navigator.getUserMedia對象這種最簡單的方式來實現。它是在Firefox和Chrome對前綴中,所以在所有的瀏覽器中將其分配到一個共同的對象會非常的方便。比如爲window.URL對象採用這種方式,以便稍後使用。

navigator.getUserMedia= navigator.getUserMedia|| navigator.webkitGetUserMedia|| navigator.mozGetUserMedia|| navigator.msGetUserMedia;window.URL= window.URL|| window.webkitURL|| window.mozURL|| window.msURL;


然後實際存在性的檢查如下:

if(navigator.getUserMedia){// Call the getUserMedia method here}else{ console.log('Native device media streaming (getUserMedia) not supported in this browser.');// Display a friendly "sorry" message to the user.}

如果getUserMedia支持,我們需要爲它傳遞三個參數 – 一個選項對象,一個成功的回調函數和一個錯誤回調函數。需要注意的是錯誤回調函數在Firefox是必須的,但在Opera和Chrome是可選的。選項參數是一個JSON風格的對象,指定是否要使用音頻,視頻或兩者都將使用。下面的示例代碼僅適用於視頻:
navigator.getUserMedia({video:true}, successCallback, errorCallback);


使用攝像機請求時的對話框

Firefox中的對話框


Chrome中的對話框

Opera中的對話框




視頻流

到目前爲止,一切都很好,讓我們看看接下來會發生什麼。成功回調函數接收一個參數,包含攝像頭的視頻流,我們需要將該視頻流發送到我們的<video>元素。爲此,我們設定它的src屬性,但有幾件事情要牢記:

Firefox使用mozSrcObject的屬性,而Opera和Chrome使用src屬性。
Chrome使用createObjectURL的方法,而Firefox和Opera直接發送視頻流。

在Firefox中,video.mozSrcObject最初爲null,而不是未定義的,所以我們可以靠這個來檢測Firefox的支持(hat tip to Florent)。一旦視頻流知道去哪兒了,我們就可以告訴視頻流播放了。



準備就緒

基本工作準備完畢。添加一個簡單的錯誤回調函數,我們就擁有了一個可以工作的跨瀏覽器的腳本,它看起來像這樣:

(注:此爲部分截圖,源碼看這裏


在GitHub上獲取


爲了方便大家學習跨網絡瀏覽器的方式訪問getUserMedia,我們把一個可以工作的例子放在了GitHub上:GumWrapper

最後一個小提示


如果你想要使用照相機流做更炫的事情,比如捕獲靜止圖像或添加奇炫的效果,你可能會希望將數據傳輸到在畫布背景下。您可以使用drawImage()來實現,在這種情況下,你需要視頻的尺寸。這些都可以通過的video.videoWidth和video.videoHeight屬性來活動,但要小心 - 他們只當瀏覽器有這些跟視頻流相關的信息時才能設置。這意味着你必須監聽某些事件,然後才能獲取這些屬性。有如下相關的事件,它們總是按以下順序觸發:

1. play
2. loadedmetadata
3. loadeddata
4. playing


Video.play()方法被調用後,play事件被觸發,但是在視頻開始播放之前有可能會有輕微的延遲。這就是palying事件被觸發的情況,但請注意,當流或視頻播放時,它在Firefox中會多次觸發。在此之前,有一些數據事件,首先是隻對metadata,但是在Firefox中它並不包括視頻尺寸。因此,最可靠的可偵聽事件是loadeddata的事件 – 你肯定能知道視頻流的寬度和高度。你可以這樣編寫代碼:


順便說一句,你也可以使用流的尺寸做進一步的錯誤檢查,例如檢查是否寬度和高度都大於0。這將避免出現某些問題,如用戶的網絡攝像頭被破壞或根本就沒有插上。

這樣就大功告成啦。我敢肯定,隨着技術的成熟,瀏覽器之間的差異會消失。在目前的情況下,上面的代碼應該可以根據你的需要幫助您。


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