SOURCE

const audioSrc = [
    './assets/1.wav',
    './assets/2.wav'
];
// AudioContext
const audioContext = new AudioContext();
// 基于src地址获得 AudioBuffer 的方法
const getAudioBuffer = (src) => {
    return new Promise((resolve, reject) => {
        fetch(src).then(response => response.arrayBuffer()).then(arrayBuffer => {
            audioContext.decodeAudioData(arrayBuffer).then(buffer => {
                resolve(buffer);
            });
        })
    })
}
const arrBufferList = await Promise.all(audioSrc.map(src => getAudioBuffer(src)));
// 拼接音频的方法
const concatAudio = (arrBufferList) => {
    // 获得 AudioBuffer
    const audioBufferList = arrBufferList;
    // 最大通道数
    const maxChannelNumber = Math.max(...audioBufferList.map(audioBuffer => audioBuffer.numberOfChannels));
    // 总长度
    const totalLength = audioBufferList.map((buffer) => buffer.length).reduce((lenA, lenB) => lenA + lenB, 0);

    // 创建一个新的 AudioBuffer
    const newAudioBuffer = audioContext.createBuffer(maxChannelNumber, totalLength, audioBufferList[0].sampleRate);
    // 将所有的 AudioBuffer 的数据拷贝到新的 AudioBuffer 中
    let offset = 0;

    audioBufferList.forEach((audioBuffer, index) => {
        for (let channel = 0; channel < audioBuffer.numberOfChannels; channel++) {
            newAudioBuffer.getChannelData(channel).set(audioBuffer.getChannelData(channel), offset);
        }

        offset += audioBuffer.length;
    });

    return newAudioBuffer;
}
// concatAudio(arrBufferList);

// 合并音频的方法
const mergeAudio = (arrBufferList) => {
    // 获得 AudioBuffer
    const audioBufferList = arrBufferList;
    // 最大播放时长
    const maxDuration = Math.max(...audioBufferList.map(audioBuffer => audioBuffer.duration));
    // 最大通道数
    const maxChannelNumber = Math.max(...audioBufferList.map(audioBuffer => audioBuffer.numberOfChannels));
    // 创建一个新的 AudioBuffer
    const newAudioBuffer = audioContext.createBuffer(maxChannelNumber, audioBufferList[0].sampleRate * maxDuration, audioBufferList[0].sampleRate);
    // 将所有的 AudioBuffer 的数据合并到新的 AudioBuffer 中
    audioBufferList.forEach((audioBuffer, index) => {
        for (let channel = 0; channel < audioBuffer.numberOfChannels; channel++) {
            const outputData = newAudioBuffer.getChannelData(channel);
            const bufferData = audioBuffer.getChannelData(channel);

            for (let i = audioBuffer.getChannelData(channel).length - 1; i >= 0; i--) {
                outputData[i] += bufferData[i];
            }

            newAudioBuffer.getChannelData(channel).set(outputData);
        }
    });

    return newAudioBuffer;
}
// mergeAudio(arrBufferList);


const audioContext = new AudioContext();
// gainNode可以对音频输出进行一些控制
const gainNode = audioContext.createGain();
// 音量设置为20%
gainNode.gain.value = 0.2;
// 这个很有必要,建立联系
gainNode.connect(audioContext.destination);
// 创建AudioBufferSourceNode
let source = audioContext.createBufferSource();
// 获取音频资源
// fetch('./bgmusic.mp3')
//   .then(res => res.arrayBuffer())
//   .then(buffer => audioContext.decodeAudioData(buffer))
//   .then(audioBuffer => {
//     source.buffer = audioBuffer;
//     source.connect(gainNode);
//   });
source.buffer = mergeAudio(arrBufferList);
source.connect(gainNode);
source.start(0);
console 命令行工具 X clear

                    
>
console