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就沒有音頻的輸出,音頻視頻設備就是一個音頻設備。

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

我們看constraints參數約束

切換攝像頭,每次改變選擇 的時候就會觸發start方法

'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;

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章