改变audio采样数据改变音频音量实例页面
回到相关文章 »效果:
原始音频
//zxx: 原始音频音量较大,播放前请注意周围环境
生成新的音频
代码:
HTML代码:
<h4>原始音频</h4> <audio src="./bgmusic.mp3" controls></audio> <h4>生成新的音频</h4> <button id="button">生成20%音量音频</button> <div id="output" class="output"></div>
JS代码:
// 音量 const volume = 0.2; // 定义一个AudioContext对象 // 因为 Web Audio API都是源自此对象 const audioContext = new AudioContext(); // 降低音量后的audioBuffer数据 let newAudioBuffer = null; // 获取音频资源 fetch('./bgmusic.mp3') .then(res => res.arrayBuffer()) .then(buffer => audioContext.decodeAudioData(buffer)) .then(audioBuffer => { newAudioBuffer = new AudioBuffer({ length: audioBuffer.length, numberOfChannels: audioBuffer.numberOfChannels, sampleRate: audioBuffer.sampleRate }); for (let channel = 0; channel < audioBuffer.numberOfChannels; channel += 1) { const channelData = audioBuffer.getChannelData(channel); const copiedChannelData = newAudioBuffer.getChannelData(channel); for (let sample = 0; sample < channelData.length; sample += 1) { copiedChannelData[sample] = channelData[sample] * volume; } } }); // Convert AudioBuffer to a Blob using WAVE representation function bufferToWave(abuffer, len) { var numOfChan = abuffer.numberOfChannels, length = len * numOfChan * 2 + 44, buffer = new ArrayBuffer(length), view = new DataView(buffer), channels = [], i, sample, offset = 0, pos = 0; // write WAVE header // "RIFF" setUint32(0x46464952); // file length - 8 setUint32(length - 8); // "WAVE" setUint32(0x45564157); // "fmt " chunk setUint32(0x20746d66); // length = 16 setUint32(16); // PCM (uncompressed) setUint16(1); setUint16(numOfChan); setUint32(abuffer.sampleRate); // avg. bytes/sec setUint32(abuffer.sampleRate * 2 * numOfChan); // block-align setUint16(numOfChan * 2); // 16-bit (hardcoded in this demo) setUint16(16); // "data" - chunk setUint32(0x61746164); // chunk length setUint32(length - pos - 4); // write interleaved data for(i = 0; i < abuffer.numberOfChannels; i++) channels.push(abuffer.getChannelData(i)); while(pos < length) { // interleave channels for(i = 0; i < numOfChan; i++) { // clamp sample = Math.max(-1, Math.min(1, channels[i][offset])); // scale to 16-bit signed int sample = (0.5 + sample < 0 ? sample * 32768 : sample * 32767)|0; // write 16-bit sample view.setInt16(pos, sample, true); pos += 2; } // next source sample offset++ } // create Blob return new Blob([buffer], {type: "audio/wav"}); function setUint16(data) { view.setUint16(pos, data, true); pos += 2; } function setUint32(data) { view.setUint32(pos, data, true); pos += 4; } } // 点击按钮播放 button.onclick = function () { const blob = bufferToWave(newAudioBuffer, newAudioBuffer.length); const blobUrl = URL.createObjectURL(blob); output.innerHTML = `<audio src="${blobUrl}" controls></audio> <p><a href="${blobUrl}" download="bgmusic-volume-down.wav">下载该音频</a></p> `; };