1┃音視訊直播系統之瀏覽器中通過WebRTC訪問攝像頭

autofelix發表於2022-05-10

一、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 的配置引數

 

相關文章