WebRTC 筆記 -- 1. getUserMedia()、MediaStream

WebRTC 功能使用的筆記紀錄。

WebRTC 就是一個W3C 訂製用來做影像、音訊溝通的標準,早期是由google提出的技術與功能,後來慢慢被W3C接受並且被各家瀏覽器作為標準API與界面。會需要WebRTC主要是因為早期要透過網頁來跟另一端的網頁做影像、音訊溝通的功能需要額外安裝一些plugin(如:flash, Java...等)但是就變成安裝這些plugin很容易遇到hack或是版本不同,除了這些之外不同的plugin在開發上面或是跨瀏覽器、作業系統與不同plugin之間的溝通都有很大的問題。所以才訂定這個標準讓所有瀏覽器可以達到不需要安裝任何Plugin、跨平台、跨瀏覽器就能達到視訊的功能。

個人的撰寫程式環境:


  • OS: Ubuntu 18.04 LTS
  • Angular :  6.1.0
  • Angular-cli : 6.1.2
  • Typescript : 2.9.2
以下的程式碼必須建立在會使用Angular、Promise與Typescript的基礎知識喔!
建議在筆電(webcam在筆電是基本配備)或是在桌機上面安裝一台簡單的Webcam才能有效運行WebRTC的功能喔!

主要的三個APIs:

  1. MediaStream
    用來存取資料串流,像是使用者的網路攝影機與麥克風。
  2. RTCPeerConnection
    影像或是音訊的呼叫具有加密與管理頻寬的功能。
  3. RTCDataChannel
    點對點(peer-to-peer) 通用資料的溝通。


MediaStream API:

用來代表同步的多媒體串流,例如:來自攝影鏡頭與麥克風的串流輸入的同步影像與音軌。
每個 MediaStream 擁有一個 input;這個input可能是一個被 getUserMedia()所建立的MediaStream。然而也會擁有一個 output 用來顯示影像或是傳送RTCPeerConnection並且單一個MediaStream可以同時附加到多個不同的輸出。

getUserMedia() :

getUserMedia() 這個方法傳入MediaStream 的Constraints 物件然後回傳一個Promise內含MediaStream的物件

每一個MediaStream都會有一個 label
例如:
           label: "Default - Built-in Audio Analog Stereo"

MediaStreamTracks 陣列也可以透過 getAudioTracks() getVideoTracks() 方法獲得。

e.g.:
navigator.mediaDevices.getUserMedia({audio: true, video: true}) .then( stream => { console.log(stream.getAudioTracks()); console.log(stream.getVideoTracks()); }) .catch( err => console.log(err));


上述程式碼中的getUserMedia傳入的就是 Constraints 而之後Promise內就是用getAudioTrack()getVideoTracks()來顯示音軌與影像的陣列。
getAudioTracks()與getVideoTracks()內容
getAudioTracks()與getVideoTracks()內容
可以通過設定srcObject的屬性將MediaStream附加到影像元素

Typescript file:
navigator.mediaDevices.getUserMedia({ audio: true, video: true }) .then(stream => { const videoDOM = <HTMLVideoElement>document.getElementById('video'); videoDOM.srcObject = stream; }) .catch(err => console.log(err));

HTML file:
<video id="video" autoplay></video>

以上的程式碼就是把Webcam的影像、聲音附加到網頁video的tag然後頁面就會顯示Webcam畫面與聲音。

不過這邊要注意一旦開啟webcam,例如:筆電內建的webcam會自動開啟webcam旁邊的LED燈,所以在不用的時候記得使用 track.stop() 來關閉webcam。

HTML file:
<video id="video" autoplay></video>
<button id="stopbtn" type="button" (click)="stopBtn()"> Stop </button>

Typescript file:
/** * 按鈕Stop的code. */ stopBtn() { const videoElement = <HTMLVideoElement>document.getElementById('video');
if (videoElement.srcObject) { (<MediaStream>videoElement.srcObject).getTracks() .forEach(stream => stream.stop()); } }

上述中的this.videoElement.srcObject要先轉型成MediaStream否則Typescript compiler會假設srcObject MediaStream | Blob | MediaSource其中一種,變成在編譯時會因為Blob不存在"getTracks()"的方法而導致有錯誤訊息喔

上述的程式碼可以在ng serve之後開啟browser來看到Webcam的影像與聲音Stream,並且透過按鈕來停止Stream。

REF:

-----------待續。

留言