webAudio
学习文章
1.AudioContext: 音频上下文,音频上下文可以共用
this.audioContext = new AudioContext();
this.audioContext = new (globalThis.AudioContext || globalThis.webkitAudioContext || globalThis.mozAudioContext)();
2.音频节点 AudioNode是一个基类,作为音频路由图中的基本单位,依赖于AudioContext
音频节点分为三种:
1.Source Node:能产生音频的节点,只有输出,没有输入。
2.Process Node:对音频进行处理的节点,有输入(可能有多个)和输出。
3.Destination Node:通常为音频播放设备,如扬声器。(audioContext.destination)
AudioContext的destination属性返回一个AudioDestinationNode表示 context 中所有音频(节点)的最终目标节点,一般是音频 渲染设备,比如扬声器。
decodeAudioData():产生音频的AudioBuffer
decodeAudioData()方法可用于异步解码音频文件中的 ArrayBuffer
public async loadAudioBuffer(audioName: string): Promise<AudioBuffer> {
let path = this.audioRootPath + audioName;
let audioBuffer = this.audioAssets.get(path);
if (audioBuffer != null) return audioBuffer;
let loadPromise = new Promise<AudioBuffer>((resolve, reject) => {
resources.load(path, AudioClip, (error, asset) => {
if (error) return reject('load audio failed:' + audioName + error);
this.decodeAudioData(asset._nativeAsset as any).then((audioBuffer) => {
if (audioBuffer == null) return reject('decoding error:' + path);
this.audioAssets.set(path, audioBuffer);
resolve(audioBuffer);
});
});
});
this.audioAssets.set(path, loadPromise);
return loadPromise;
}
public decodeAudioData(audioData: ArrayBuffer): Promise<AudioBuffer> {
return new Promise((resolve) => {
const promise = this.audioContext.decodeAudioData(audioData, resolve, (err) => {
console.warn('failed to load Web Audio', err);
})
promise?.catch((reason) => console.warn('failed to load Web Audio', reason, audioData));
});
}
createBufferSource():音频源节点,创建一个新的AudioBufferSourceNode接口
createBufferSource() 该接口可以通过AudioBuffer 对象来播放音频数据。AudioBuffer对象可以通过AudioContext.createBuffer 来创建或者通过 AudioContext.decodeAudioData成功解码音轨后获取。
const source = this.audioContext.createBufferSource();
source.buffer = audioBuffer;
source.connect(this.musicGain);// 音频源节点连接到声音节点
this.musicGain.connect(this.audioContext.destination);// 声音节点连接到destination进行播放
source.loop = true;
source.start(0, startOffset);
this._music = source;
createGain():声音节点
this.musicGain = this.audioContext.createGain();
this.musicGain.connect(this.audioContext.destination);
createAnalyser():可以对音频信号进行实时的快速傅立叶变换(FFT)得到音频的时域/频域数据,拿到时域/频域的数据后,可以实现时域分析、频域分析、音频可视化动效等。
1 const analyser = audioContext.createAnalyser();
2 analyser.fftSize = 2048; // 指定要进行FFT的采样数据的窗口大小,2的整数倍
3 const dataArray = new Uint8Array(analyser.frequencyBinCount);
4 analyser.getByteTimeDomainData(dataArray);
5 //analyser.getByteFrequencyData(dataArray);
//analyser.frequencyBinCount是时域/频域数据的长度,它是fftSize的一半(因为实时音频信号的傅立叶变换具有对称性,只需要获取一半数据即可),通过analyser.getByteTimeDomainData(dataArray)或者getByteFrequencyData方法将数据填充到8位无符号整型数组中