1┃音影片直播系統之瀏覽器中通過WebRTC訪問攝影機

一、WebRTC的由來

  • 對於前端開發小夥伴而言,如果用 JavaScript 做音影片處理

  • 在以前是不可想像的,因為首先就要考慮瀏覽器的性能是否跟得上音影片的採集

  • 但是 Google 作為國際頂尖科技公司,就喜歡做一些常人無法想像的事情

  • 2011 年,Google 創立了 WebRTC 項目,其願景就是可以在瀏覽器之間快速地實現音影片通訊。

  • 隨著時間的發展,在瀏覽器之間進行實時音影片通訊已經已經變很成熟了

 

二、1對1音影片通話結構

  • 從上圖結構圖可以看出,1對1的影片通話結構大體上可以分為四個部分

  • 兩個 WebRTC 終端:這裡可以看成是兩個瀏覽器,主要負責音影片採集、編解碼、NAT 穿越、音影片數據傳輸

  • Signal(信令)伺服器:負責信令處理,如點擊靜音,關閉攝影機,進入房間等指令操作

  • STUN/TURN 伺服器:負責獲取 WebRTC 終端在公網的 IP 地址,以及 NAT 穿越失敗後的數據中轉

 

三、瀏覽器同時採集音影片

  • 瀏覽器中採集音影片設備非常簡單

  • 只需要使用 getUserMedia(constraints) 方法即可

  • 傳入的 constraints 是配置參數,可以單獨配置是否採集音影片

  • 但是IE8以下的瀏覽器不兼容該影片採集方法

// 同時採集音視和影片
const mediaStreamContrains = {
 	video: true,
 	audio: true
};

var promise = navigator.mediaDevices.getUserMedia(mediaStreamContrains);

 

四、幀率降噪功能配置

  • frameRate:可以配置影片幀率

  • width:設置影片寬度,ideal代表理想寬度

  • height:設置影片高度,ideal代表理想高度

  • aspectRatio:代表寬高比

  • 對於音頻則是開啟迴音消除、降噪、自動增益等操作

const mediaStreamContrains = {
 video: {
 		frameRate: {min: 20},
 		width: {min: 640, ideal: 1280},
 		height: {min: 360, ideal: 720},
		aspectRatio: 16/9
 },
 audio: {
 		echoCancellation: true, // 開啟迴音消除
 		noiseSuppression: true, // 降噪
 		autoGainControl: true // 自動增益
 }
};

var promise = navigator.mediaDevices.getUserMedia(mediaStreamContrains);

 

五、採集影片數據

  • 採集攝影機的內容並在瀏覽器上播放

  • 需要注意的是,一定要在https協議或者本地localhost域名下才可以調用

  • 我們通過調用 getUserMedia 方法,將影片數據載入到 video 標籤中進行播放

  • 如果video標籤想要播放流媒體數據,需要將數據掛在到 srcObject 屬性上,該屬性和普通的 src 屬性互斥

  • 如果是第一次請求 Camera,瀏覽器會向用戶彈出提示窗口,讓用戶決定是否可以訪問攝影機

  • 如果用戶允許訪問,且設備可用,則調用 gotLocalMediaStream 方法

<!DOCTYPE html>
<html>
<head>
    <title>Realtime communication with WebRTC</title>
</head>
<style>
    video {
        width: 800px;
        height: 450px;
    }
</style>
<body>
    <h1>Realtime communication with WebRTC </h1>
    <video autoplay playsinline></video>
    <script>
        'use strict';

        const mediaStreamContrains = {
            video: true
        };

        const localVideo = document.querySelector('video');

        function gotLocalMediaStream(mediaStream) {
            localVideo.srcObject = mediaStream;
        }

        function handleLocalMediaStreamError(error) {
            console.log('navigator.getUserMedia error: ', error);
        }

        navigator.mediaDevices.getUserMedia(mediaStreamContrains).then(
            gotLocalMediaStream
        ).catch(
            handleLocalMediaStreamError
        );
    </script>
</body>
</html>

 

六、獲取瀏覽器設備資訊

  • 以手機為例,它一般會包括前置攝影機和後置攝影機麥克風、相機、耳機等。我們可以根據自己的需要,選擇打開不同的設備

  • WebRTC 是否提供了的 enumerateDevices 介面,可以查詢自己機子上都有哪些音影片設備

  • deviceInfo中有三個比較重要的屬性

  • deviceID:設備的唯一標識

  • label:設備名稱,用戶已被授予訪問媒體設備的許可權(要想授予許可權需要使用 HTTPS 請求),否則 label 欄位始終為空。

  • kind:設備種類,可用於識別出是音頻設備還是影片設備,是輸入設備還是輸出設備

// 判斷瀏覽器是否支援這些 API
if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {
    console.log("enumerateDevices() not supported.");
    return;
}

// 枚舉 cameras and microphones.
navigator.mediaDevices.enumerateDevices()
    .then(function (deviceInfos) {
        // 列印出每一個設備的資訊
        deviceInfos.forEach(function (deviceInfo) {
            console.log(deviceInfo.kind + ": " + deviceInfo.label +
                " id = " + deviceInfo.deviceId);
        });
    })
    .catch(function (err) {
        console.log(err.name + ": " + err.message);
    });

七、方法參數配置

  • ​ 方法 getUserMedia 的配置參數