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