天天看點

WebRTC音視訊資料采集 六、第五節 視訊參數調-音頻限制

今天我們介紹的是音頻相關的限制,以及手機web端切換前後攝像頭

volume

第一個是與音量相關的,這個數值是從0到1.0,0就是靜音 ,1.0就是最大音量。

sampleRate

第二個是采樣率,在音頻裡面有很多采樣率,四萬八,三萬二,一萬六,八千等,根據自己的需要設定就好了。

sampleSize

第三個是采樣大小,每一個采樣大小是由多少位表示,一般情況下我們都是用16位,也就是兩個位元組。

echoCancellation

第四個是回音,就是我們在開啟采集 資料之後,是否要開啟回音消除,在我們實時直播的過程中,回音消除是 一個非常重要的功能,當雙方通信的時候 ,如果有回音傳過來,對這個通話品質會造成極大的影響,設定可以通過true或false來開啟或關閉回音消除。

autoGainControl

第五個是自動增益,在我原有的錄制的聲音的基礎上是否給他增加這個音量,它增加的範圍也是有一定範圍的,這也是一個用 true或false設定的,也就是開始或者關閉。

noiseSuppression

第六個是降噪,就是我們在采集資料的時候是否要開啟降噪功能 。

latency

第七個表示 延遲大小,當我直播過程中,我們音視訊,這裡latency設定小的話,就表示它的 視訊傳輸試試通信的時候它的延遲就會小,延遲小的後果就是當你網絡狀況不好的時候,它就會出現卡頓甚至花屏等品質問題。但是它的好處是我們雙方可以實時通信,一般是低于500毫秒,這是非常好的一個品質了。當然最好的是200毫秒以内,從采集到編碼到傳輸到對方接受且解碼再到渲染整個過程中是200毫秒以内是最好的 。我們正常通話應該是這樣一個延遲。我們感受500毫秒還可以,再往上800毫秒 就比較大了。

如果你的latency設定的大,它的好處是你的畫面比你聲音更平滑,但是它這種及時性,就是說如果做實時通信的話 ,就會很麻煩,你說了一句話,你過了一秒多,對方才聽到,在回答你又過了一秒。這種互動的話就沒法忍受了。

channelCount

第八個表示單聲道還是雙聲道,一般情況下我們會使用單聲道,如果是對于一些樂器,都是雙聲道,這樣的話音質才更好。

deviceID

第九個是devideID就是當我有多個輸入輸出裝置的時候,我可以進行裝置的切換 ,比如在手機上當我改變了devideID之後,我從前置攝像頭就可以切換到後置攝像頭。

groupID

第十個是groupID,它代表 是同一個實體裝置,我們之前 說過,對于 音頻來說,音頻的輸入輸出是同一個實體裝置,不同浏覽器其實它的實作是不一樣的,那麼對于chrome來說它分成了音頻的輸入輸出,對于FireFOX和safari就沒有音頻的輸出,音頻視訊裝置就是一個音頻裝置。

當然限制也可以寫成最大最小的範圍限制,這些 都可以設定,這樣它就是一個動态的,它會在這個範圍内選擇一個最好的,不是說攝像的時候實時變化 ,是說它選擇的時候會在這個範圍内選擇一個最好的。幀率他是可以根據網絡的情況去調整的。

WebRTC音視訊資料采集 六、第五節 視訊參數調-音頻限制
'use strict'

var audioSource = document.querySelector('select#audioSource');
var audioOutput = document.querySelector('select#audioOutput');
var videoSource = document.querySelector('select#videoSource');
// 擷取video标簽
var videoplay = document.querySelector('video#player');

// deviceInfos是裝置資訊的數組
function gotDevices(deviceInfos){
  // 周遊裝置資訊數組, 函數裡面也有個參數是每一項的deviceinfo, 這樣我們就拿到每個裝置的資訊了
  deviceInfos.forEach(function(deviceinfo){
    // 建立每一項
    var option = document.createElement('option');
    option.text = deviceinfo.label;
    option.value = deviceinfo.deviceId;
  
    if(deviceinfo.kind === 'audioinput'){ // 音頻輸入
      audioSource.appendChild(option);
    }else if(deviceinfo.kind === 'audiooutput'){ // 音頻輸出
      audioOutput.appendChild(option);
    }else if(deviceinfo.kind === 'videoinput'){ // 視訊輸入
      videoSource.appendChild(option);
    }
  })
}

// 擷取到流做什麼, 在gotMediaStream方面裡面我們要傳人一個參數,也就是流,
// 這個流裡面實際上包含了音頻軌和視訊軌,因為我們通過constraints設定了要采集視訊和音頻
// 我們直接吧這個流指派給HTML中指派的video标簽
// 當時拿到這個流了,說明使用者已經同意去通路音視訊裝置了
function gotMediaStream(stream){  
  videoplay.srcObject = stream; // 指定資料源來自stream,這樣視訊标簽采集到這個資料之後就可以将視訊和音頻播放出來
  // 當我們采集到音視訊的資料之後,我們傳回一個Promise
  return navigator.mediaDevices.enumerateDevices();
}

function handleError(err){
  console.log('getUserMedia error:', err);
}
function start() {
// 判斷浏覽器是否支援
if(!navigator.mediaDevices ||
  !navigator.mediaDevices.getUserMedia){
  console.log('getUserMedia is not supported!');
}else{
  // 擷取到deviceId
  var deviceId = videoSource.value; 
  // 這裡是限制參數,正常情況下我們隻需要是否使用視訊是否使用音頻
  // 對于視訊就可以按我們剛才所說的做一些限制
  var constraints = { // 表示同時采集視訊金和音頻
    video : {
      width: 640,  // 寬帶
      height: 480,  // 高度
      frameRate:15, // 幀率
      facingMode: 'enviroment', //  設定為後置攝像頭
      deviceId : deviceId ? deviceId : undefined // 如果deviceId不為空直接設定值,如果為空就是undefined
    }, 
    audio : {
      noiseSuppression: true, // 降噪
      echoCancellation: true // 回音消除
    },
  }
  //  從指定的裝置中去采集資料
  navigator.mediaDevices.getUserMedia(constraints)
    .then(gotMediaStream)  // 使用Promise串聯的方式,擷取流成功了
    .then(gotDevices)
    .catch(handleError);
}
}

start();

// 當我選擇攝像頭的時候,他可以觸發一個事件,
// 當我調用start之後我要改變constraints
videoSource.onchange = start;