之前是在做一个electron项目中需要去检测音量,检测音量不是为了证明音量本身,而是去看看麦克风是否正常响应。
如图所示:这是一个模仿腾讯会议的音量检测的UI
在浏览器中是无法获取真实设备的电平输入的,所以此方法是通过后去音频数据来计算出音量,并非系统实际音量
使用场景
- 在web端对麦克风进行检测,看看麦克风是否有效
- 在electron、Capacitor等以web交互为主开发的应用都可以支持(比如:electron应用)
1
2
3import { ref } from 'vue'
4
5
6 * 实时获取麦克风音量
7 * 此方法是通过后去音频数据来计算出音量,并非系统实际音量
8 * @param _audioContext 如果传入AudioContext,则使用它,否则新建一个音频来获取音量大小
9 * @returns
10 */
11export const useVolume = () => {
12 const audioContext = ref<AudioContext | null>()
13 const analyser = ref<AnalyserNode | null>(null)
14 const isStart = ref<boolean>(false)
15
16 const volume = ref<number>(0)
17
18
19 * 开启音量检测
20 * @param _source 数据源
21 * @param _audioContext audio上下文 (用于在录音的过程中同时去检测,这样就不需要再次创建多一个audio上下文)
22 * @param deviceId 麦克风设备ID,用于指定检测那个麦克风的音量
23 */
24 const startVolumeCheck = async (
25 _source?: MediaStreamAudioSourceNode | null,
26 _audioContext?: AudioContext | null,
27 deviceId?: string | null,
28 ) => {
29 if (!audioContext.value) {
30 if (_audioContext) {
31 audioContext.value = _audioContext
32 } else {
33 audioContext.value = new AudioContext()
34 }
35 }
36
37 isStart.value = true
38 const mediaOptions = deviceId
39 ? { audio: { deviceId: deviceId } }
40 : { audio: true }
41 let source = _source
42 if (!source) {
43 const stream = await navigator.mediaDevices.getUserMedia(mediaOptions)
44 source = audioContext.value.createMediaStreamSource(stream)
45 }
46
47 analyser.value = audioContext.value.createAnalyser()
48 analyser.value!.fftSize = 32
49 source.connect(analyser.value!)
50
51
52 const bufferLength = analyser.value!.frequencyBinCount
53 const dataArray = new Uint8Array(bufferLength)
54
55
56 function updateVolume() {
57 analyser.value!.getByteFrequencyData(dataArray)
58
59 let sum = 0
60 for (let i = 0; i < bufferLength; i++) {
61 sum += dataArray[i]
62 }
63 volume.value = Math.floor((sum / bufferLength / 255) * 100)
64
65 if (isStart.value) {
66 requestAnimationFrame(updateVolume)
67 } else {
68 volume.value = 0
69 }
70 }
71
72
73 updateVolume()
74 }
75
76
77 const stopVolumeCheck = () => {
78 isStart.value = false
79 analyser.value?.disconnect()
80 }
81
82 return {
83 startVolumeCheck,
84 stopVolumeCheck,
85 volume,
86 isStart,
87 }
88}
提示:在检测麦克风之前,需要获取麦克风权限,并且获取到你正在使用的麦克风
个人笔记记录 2021 ~ 2025