代码较多 看第二份调用代码 里面有注释
关键步骤
1、将成功调用麦克风后的 媒体轨道保存 (第二份代码)
2、 关闭的时候便利轨道数组 逐个关闭 (第三份代码)
封装部分 直接调用
封装代码 、
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
);
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
;
setSource(window
.MSStream
);
soundMeter
.connectToSource(stream
, function (e
: any
) {
if (e
) {
console
.log(e
);
return;
}
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
source
&& source
.getTracks().forEach(function (track
: { stop
: () => void }) {
track
.stop();
});
}, [source
]);