Web Audio - 初识

548 阅读3分钟

什么是Web Audio

Web端播放音频,最常用的处理是利用html5的audio标签来实现音频的播放与交互。而Web Audio 则是提供了一整套Api接口,用于在Web上实现更复杂的音频控制和处理。比如:允许开发者来自选音频源,对音频添加特效,使音频可视化,添加空间效果,等等。Web Audio并不会取代audio标签,它其是应该算是audio标签的一个补充。Web前端开发中如何在二者之间选择,往往取决于具体的应用场景。如果你只是想控制一个简单的音轨的播放,audio标签或许是一个更好更快的选择

Web Audio的几个概念

在探索如何使用Web Audio之前,我们先了解几个关键概念:

音频上下文 AudioContext

音频节点 AudioNode

音频节点连接 connect

音频源 source

音频输出 destination

AudioContext

音频上下文,在做音频处理之前,需要创建1个AudioContext对象,后续所有音频的控制和处理,都在AudioContext的基础上进行。

AudioNode

音频节点,一个音频处理模块,Web Audio对音频的处理,遵循模块化准则,每一个AudioNode就是一个独立的音频处理模块。多个AudioNode在AudioContext的控制下,串联形成一张音频处理流程图。

connect

上面提到的,Web Audio的音频处理流程,往往是由多个AudioNode串联形成一张处理流程图。而AudioNode之间就是通过connect方法进行连接,将处理后的音频由一个节点,链接交由下一个节点处理。

source & destination

音频节点(AudioNode)按照功能,可以简单划分为3种类型,音频源节点、音频输出节点、中间处理节点。其中音频源节点,用来接收音频输入,处于整个音频处理流程的头部,而音频输出节点则是输出和播放音频,处于音频处理流程的尾部。中间处理节点则是对音频在中间环境进行控制、效果处理等操作。 所以一个典型的Web Audio音频处理流程如下图:

img5.jpg

Web Audio简单使用

下面,用一个简单的例子,实践一下Web Audio处理音频的完整流程;我们用俩个mp3(超级玛丽和蜡笔小新的插曲)来体验下Web Audio Api。

<div>    
  <div id="audioWrap">
    <audio id="cjml" src="./cjml.mp3" controls></audio>
    <audio id="lbxx" src="./lbxx.mp3" controls></audio>
  </div>
</div>


/* 这里需要一个Web服务器来托管html和mp3文件,可以基于node.js或者nginx来搭建本地Web服务;
 * MediaElementSourceNode无法基于file:// 协议也发布跨域处理音频
 */

const audioCjml = document.querySelector('#cjml');
const audioLbxx = document.querySelector('#lbxx');
// 创建音频上下文
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
// 创建俩个音频源节点
const source1 = audioCtx.createMediaElementSource(audioCjml); // 超级玛丽

const source2 = audioCtx.createMediaElementSource(audioLbxx); // 蜡笔小新
// GainNode音频节点用于控制音频声音
const gainNode = audioCtx.createGain();

// 音频播放
audioCjml.onplay = function () {      
  // value的值范围在0-1之间,最小音量0,最大音量1
  gainNode.gain.value = 1;
  // 将蜡笔小新.mp3连接至gainNode节点
  source1.connect(gainNode);
  // gainNode再连接至音频输出
  gainNode.connect(audioCtx.destination);
}

audioLbxx.onplay = function () {
  gainNode.gain.value = 0.4;
  source2.connect(audioCtx.destination);
  setTimeout(() => {
    gainNode.gain.value = 1;
    audioLbxx.pause();
    audioLbxx.currentTime = 0;
    source2.disconnect(audioCtx.destination);        
  }, 7000);
}

这个示例很简单,超级玛丽作为背景音乐,插入一个GainNode节点来控制背景乐的音量。当插播蜡笔小新时,降低超级玛丽的音量,蜡笔小新播放结束后在再恢复音量。小编通过这个demo来初步接触Web Audio处理音频的流程。Api更多更丰富的功能,MDN上有全面的介绍,可以进行更加深入的了解学习。