// 通过audio标签var sound, audio = new Audio();audio.addEventListener('canplay', function() { sound = context.createMediaElementSource(audio); sound.connect(context.destination);});audio.src = '/audio.mp3'; var v =document.getElementsByTagName('video')[0];var aCtx = new (window.AudioContext || window.webkitAudioContext)();var source = aCtx.createMediaElementSource(v); // 创建声音源处理器// var sourceNode = aCtx.createBufferSource();// 创建声音终点处理器// var destinationNode = aCtx.destination; // 创建声道分离处理器 此处的2是声道数 可以从a中获取var splitterNode = aCtx.createChannelSplitter(2); // 源连接声道分离处理器source.connect(splitterNode); // 创建左右声道频谱分析器var leftAnalyserNode = aCtx.createAnalyser();var rightAnalyserNode = aCtx.createAnalyser(); splitterNode.connect(leftAnalyserNode, 0)splitterNode.connect(rightAnalyserNode, 1) // 合并声道var mergerNode = aCtx.createChannelMerger(2);leftAnalyserNode.connect(mergerNode, 0, 0)rightAnalyserNode.connect(mergerNode, 0, 1)mergerNode.connect(aCtx.destination) // 获取左右声道频谱数据var leftBuff = new Uint8Array(leftAnalyserNode.frequencyBinCount);leftAnalyserNode.getByteTimeDomainData(leftBuff) var rightBuff = new Uint8Array(rightAnalyserNode.frequencyBinCount);rightAnalyserNode.getByteTimeDomainData(rightBuff) // 字节值的范围介于0-255之间,是的,映射到-1到+1,因此128为零。 (它不是伏特,而是全范围无单位值。) var rightBuff = new Float32Array(rightAnalyserNode.frequencyBinCount);rightAnalyserNode.getFloatFrequencyData(rightBuff) // 单位dB // 修改声音大小// 创建音量节点 var gainNode = aCtx.createGain();source.connect(gainNode);gainNode.connect(aCtx.destination);gainNode.gain.value=0.1 // 获取音量scriptProcessor = aCtx.createScriptProcessor(4096,2,2);source.connect(scriptProcessor);scriptProcessor.connect(aCtx.destination);// 开始处理音频scriptProcessor.onaudioprocess = (e) => { // 获得缓冲区的输入音频,转换为包含了PCM通道数据的32位浮点数组 const lBuffer = e.inputBuffer.getChannelData(0); const rBuffer = e.inputBuffer.getChannelData(1); // 获取缓冲区中最大的音量值 const lMaxVal = Math.max(...lBuffer); const rMaxVal = Math.max(...rBuffer); // 左右显示音量值 const lVol = Math.round(lMaxVal 100); const rVol = Math.round(rMaxVal 100); console.log(lVol,rVol);};
不需要上面那坨左右声道的时候,可以直接这样设置:
oAudio = document.getElementById('shakedown-audio-mp3'); // 创建音频上下文对象 oCtx = new AudioContext(); // console.log(oCtx); // 创建媒体源,除了audio本身可以获取,也可以通过oCtx对象提供的api进行媒体源操作 audioSrc = oCtx.createMediaElementSource(oAudio); //通过标签获取 //audioSrc = oCtx.createMediaStreamSource(stream); //使用多媒体流 // 创建分析机 analyser = oCtx.createAnalyser(); // 媒体源与分析机连接 audioSrc.connect(analyser); // 输出的目标:将分析机分析出来的处理结果与目标点(耳机/扬声器)连接 // analyser.connect(oCtx.destination);// 连接后会输出声音,不连接无声只获取音量 let voiceHeight = new Float32Array(analyser.frequencyBinCount); analyser.getFloatFrequencyData(voiceHeight);
这里主要是用了createScriptProcessor这个api,但是此api即将废弃。
另外一种方式:
// 获取音频分贝 this.audioContext = new (window.AudioContext || window.webkitAudioContext)() this.$refs.outputAudioWrap.innerHTML = `<audio id="outputAudio"></audio>` const audio = document.getElementById('outputAudio') // audio.src = require('@/assets/media/test_output.wav') audio.src = require('@/assets/media/squirrel.mp3') audio.loop = true audio.play() // 获取用户的 media 信息 // 将音频的声音输入这个对象 // 创建媒体源,除了audio本身可以获取,也可以通过audioContext对象提供的api进行媒体源操作 this.outputSource = this.audioContext.createMediaElementSource(audio) // 创建分析机 this.outputAnalyser = this.audioContext.createAnalyser() this.outputAnalyser.fftSize = 128 // 默认1024 // 媒体源与分析机连接 this.outputSource.connect(this.outputAnalyser) // 输出的目标:将分析机分析出来的处理结果与目标点(耳机/扬声器)连接 this.outputAnalyser.connect(this.audioContext.destination)// 连接后会输出声音,不连接无声只获取音量 this.getOutputVolume(this.outputSource) getOutputVolume () { var bufferLength = this.outputAnalyser.frequencyBinCount var dataArray = new Float32Array(bufferLength) this.outputAnalyser.getFloatFrequencyData(dataArray) let maxVolume = -Infinity for (let i = 4, ii = dataArray.length; i < ii; i++) { if (dataArray[i] > maxVolume && dataArray[i] < 0) { maxVolume = dataArray[i] } } let audioVolume = Math.round(Math.pow(10, maxVolume / 85) * 20) audioVolume = audioVolume < 0 ? 0 : audioVolume audioVolume = audioVolume > 10 ? 10 : audioVolume audioVolume = audioVolume * 10 audioVolume = audioVolume / 100 * this.outputVoiceSize this.outputVolume = audioVolume // 另外一种平滑的方式。 // var dataArray = new Uint8Array(bufferLength) // this.outputAnalyser.getByteFrequencyData(dataArray) // console.log('=====================') // const max2 = Math.max.apply(null, dataArray) // const middleIndex = Math.ceil(dataArray.length / 2) // const middleNum = Math.ceil(dataArray[middleIndex]) // const avgNum = dataArray.reduce((previous, current) => previous + current, 0) / dataArray.length // const percent = middleNum / max2 // console.log('percent', percent) // let volumeNum = percent * this.outputVoiceSize // volumeNum = volumeNum > 100 ? 100 : volumeNum // volumeNum = volumeNum ? volumeNum : 0 // this.outputVolume = volumeNum // console.log('this.outputVolume', this.outputVolume) this.outputRequestId = requestAnimationFrame(this.getOutputVolume) },