AudioContext 一些常用操作

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

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值