WebRTC 是一些列用於實時通信的 API 集合,使用 WebRTC API 可以快速搭建實時音視頻應用。WebRTC 雖然是 web API,但是它也提供了 native 工具庫,在 native 程序中引入 WebRTC 可以實現多端通信。因此 WebRTC 是實時音視頻應用必備的底層技術。
瀏覽器的 WebRTC API 提供了三部分能力:
- MediaDevices
- PeerConnections
- DataChannels
其中 MediaDevices 負責數據採集,PeerConnections 負責音視頻流傳輸,DataChannels 提供了數據通道。
本篇為 WebRTC 系列第一篇,這篇文章主要看一下 MediaDevices 部分。與其他 native 端不同,在 WebRTC 之前瀏覽器沒有調用攝像頭麥克風等用戶媒體的能力,因此對瀏覽器端 WebRTC 而言,MediaDevices 是必不可少的一部分。
在瀏覽器中我們通過 window.navigator.mediaDevices 來獲取 MediaDevices 對象,看下 mediaDevices 對象上的幾個重要方法:
【免費】FFmpeg/WebRTC/RTMP/NDK/Android音視頻流媒體高級開發-學習視頻教程-騰訊課堂
C++音視頻開發學習資料:點擊莬費領取→音視頻開發(資料文檔+視頻教程+面試題)(FFmpeg+WebRTC+RTMP+RTSP+HLS+RTP)
getUserMedia
getUserMedia 是 WebRTC 中最重要的 API,它給瀏覽器訪問用戶音視頻的能力,它是瀏覽器訪問用戶媒體信息的唯一方式,因此即使在非實時音視頻場景,只要涉及到用戶攝像頭和麥克風的操作都離不開這個 API。
使用 getUserMedia:
navigator.mediaDevices.getUserMedia({ audio: true, video: true })
調用 API 後瀏覽器會向用戶請求需要的攝像頭麥克風權限,此函數會返回 Promise,當用戶同意授權後開始採集,resolve 採集到的 MediaStream,想要在本地預覽 MediaStream 很簡單,只需要創建一個 video 標籤,把 MediaStream 賦值給 video 的 srcObject 即可:
<video id="preview"></video>
<script>
const preview = document.getElementById('preview');
navigator.mediaDevices.getUserMedia({ video: true, audio: true }).then(
stream => preview.srcObject = stream;
);
</script>
getUserMedia 的參數是 MediaStreamConstraints 類型,它可以指定採集到流的條件,可以只採集音頻或視頻軌道,可以指定視頻大小,指定採集設備等,詳見文檔。
採集到的 MediaStream 對象實際上是由多條軌道(tracks)組成的,video、audio 分別有自己的軌道,使用 getVideoTracks,getAudioTracks 可以分別獲取視頻音頻軌道,也可以使用 getTracks 獲取全部軌道。
音視頻軌道對象為 MediaStreamTrack,在音視頻應用中,雖然我們最終看到的是以一個帶有音頻和視頻的 video 資源,但是實際上從採集到處理音視頻都是分開的,因此在這裡我們可以對音視頻的處理和發送都是針對 MediaStreamTrack 對象來做的,我們可以把 track 數據傳入其他處理程序如 MediaStreamTrackProcessor 等,也可以把 track 傳入 PeerConnections 進行發送。
getDisplayMedia
getDisplayMedia 用於屏幕錄製或共享的場景,它採集的是用戶屏幕的數據,桌面、應用、標籤頁等都可以作為採集對象,採集到的數據封裝位一個 MediaStream 對象,可供後續處理。getDisplayMedia 的使用方法和 getUserMedia 非常相似:
<video id="preview"></video>
<script>
const preview = document.getElementById('preview');
navigator.mediaDevices.getDisplayMedia({ video: true, audio: true }).then(
stream => preview.srcObject = stream;
);
</script>
這裡依舊使用一個 video 作為預覽窗口,當調用 getDisplayMedia 時瀏覽器會彈出共享內容選擇窗口,當用戶選擇共享區域後 resolve 採集到的 MediaStream ,這裡比較特殊的一點是 getDisplayMedia 至少需要有一個 video 軌道數據。之後拿到 MediaStream 對象就可以根據需要執行後續的操作。
【免費】FFmpeg/WebRTC/RTMP/NDK/Android音視頻流媒體高級開發-學習視頻教程-騰訊課堂
C++音視頻開發學習資料:點擊莬費領取→音視頻開發(資料文檔+視頻教程+面試題)(FFmpeg+WebRTC+RTMP+RTSP+HLS+RTP)
enumerateDevices
enumerateDevices 可以獲取可用的媒體輸入和輸出設備列表信息,在實際應用中,用戶設備上看有多個攝像頭和麥克風,這時可以通過 enumerateDevices 拿到全部的設備信息,每個設備有一個 id 標識,這個 id 可以作為 getUserMedia 的參數傳入來指定採集設備。
devicechange
devicechange 是一個事件,可以通過 ondevicechange 或 addEventlistener 來監聽,當用戶的設備信息發生變化時會觸發,可以在 devicechange 後重新獲取設備列表更新設備信息。
以上幾個就是 mediaDevices 中比較重要的方法。mediaDevices API 是構建多媒體應用的基礎 API,它們提供了瀏覽器訪問攝像頭麥克風和屏幕錄製的能力,給 web 端應用帶來了更多可能。