代碼較多 看第二份調用代碼 裏面有註釋
關鍵步驟
1、將成功調用麥克風後的 媒體軌道保存 (第二份代碼)
2、 關閉的時候便利軌道數組 逐個關閉 (第三份代碼)
封裝部分 直接調用
封裝代碼 、
/*
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree.
*/
export default class SoundMeter {
instant: number;
script: any;
clip: number;
slow: number;
context: any;
mic: any;
constructor(context: any) {
this.context = context;
this.instant = 0.0;
this.slow = 0.0;
this.clip = 0.0;
this.script = context.createScriptProcessor(2048, 1, 1);
var that = this;
this.script.onaudioprocess = function (event: { inputBuffer: { getChannelData: (arg0: number) => any; }; }) {
var input = event.inputBuffer.getChannelData(0);
var i;
var sum = 0.0;
var clipcount = 0;
for (i = 0; i < input.length; ++i) {
sum += input[i] * input[i];
if (Math.abs(input[i]) > 0.99) {
clipcount += 1;
}
}
that.instant = Math.sqrt(sum / input.length);
that.slow = 0.95 * that.slow + 0.05 * that.instant;
that.clip = clipcount / input.length;
};
}
connectToSource = (stream: any, callback: (arg0: null) => void) => {
console.log('SoundMeter connecting');
try {
this.mic = this.context.createMediaStreamSource(stream);
this.mic.connect(this.script);
// necessary to make sample run, but should not be.
this.script.connect(this.context.destination);
if (typeof callback !== 'undefined') {
callback(null);
}
} catch (e) {
console.error(e);
if (typeof callback !== 'undefined') {
callback(e);
}
}
}
stop = () => {
this.mic.disconnect();
this.script.disconnect();
}
}
調用
useEffect(() => {
const mic = () => {
let constraints = {
audio: true,
video: false,
};
//調用開啓麥克風
navigator.mediaDevices
.getUserMedia(constraints)
.then(handleSuccess)
.catch(handleError);
};
const handleSuccess = (stream: any) => {
window.MSStream = stream;
//成功調用麥克風後 媒體輸入會產生一個MediaStream,裏面包含了請求的媒體類型的軌道
// 將此軌道保存 後面關閉的時候回用到
setSource(window.MSStream);
soundMeter.connectToSource(stream, function (e: any) {
if (e) {
console.log(e);
return;
}
//組件卸載需要清除定時器 使用useRef()
intervalRef.current = setInterval(function () {
// 設置展示數據 就是取得 音量
setVoice(Number(soundMeter.instant.toFixed(2)) * 100);
}, 200);
});
};
const handleError = (error: any) => {
console.log('navigator.getUserMedia error: ', error);
};
if (micResult.support === 'success') {
mic();
} else {
//判斷音頻流是存在
soundMeter.mic && soundMeter.stop();
clearInterval(intervalRef.current);
}
return () => {
clearInterval(intervalRef.current);
};
//根據是成果否調用到麥克風硬件 觸發是否監聽 麥克風音量
}, [micResult, soundMeter]);
關閉監聽
調用完後直接切換組件,監聽音量會一直存在 瀏覽器上方會展示話筒
所以需要關閉瀏覽器
const init = useCallback(() => {
if(! window.MSStream) return
// 首次進入卸載 會導致下面報錯 所以需要return
// 獲取到上面的 媒體軌道信息數組 遍歷關閉
source && source.getTracks().forEach(function (track: { stop: () => void }) {
track.stop();
});
}, [source]);