// 通过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)    },