实现方式:将音频文件数据裁剪,然后复制一份重新存储起来。
<body> <input type="file" onchange="printFile()"> <script> const audioCtx = new AudioContext(); function printFile() { var file = document.querySelector('input[type=file]').files[0]; var reader = new FileReader(); reader.onload = function (evt) { let audioData = evt.target.result; //创建环境 audioCtx.decodeAudioData(audioData, (buffer) => { //buffer就是我们要获取的数据 let channels = buffer.numberOfChannels; // 声道数 let rate = buffer.sampleRate; // 采样率 let startOffset = 0; // 截取起点 let endOffend = rate * 10; // 截取终点 let frameCount = endOffend - startOffset; // 截取的时长 // 创建同样的采样率,同样声道数量,长度是x秒的空的audioBuffer let newAudioBuffer = new AudioContext().createBuffer(channels, frameCount, rate); // 创建临时的Array存放复制的buffer数据 let tempArray = new Float32Array(frameCount); let offSet = 0; // 裁剪后放置的起点位置 // 声道的数据复制和写入 for (let index = 0; index < channels; index++) { buffer.copyFromChannel(tempArray, index, startOffset); newAudioBuffer.copyToChannel(tempArray, index, offSet); } handlePlayMusic(newAudioBuffer); }) }; reader.readAsArrayBuffer(file); } // 直接播放音乐 function handlePlayMusic(val) { var source = audioCtx.createBufferSource(); source.buffer = val source.connect(audioCtx.destination); source.start(); } // 处理buffer。将ArrayBuffer变成url function bufferToWave() { // 1:将buffer转成wav格式的 // 2:借助crunker库将buffer转成音频文件 } // 改变音频音量 function changeVolumn(val, volumn, channels, newAudioBuffer) { for(let index = 0; index < channels; index++){ const channelData = newAudioBuffer.getChannelData(index); for(let j = 0; j < channelData.length; j++){ channelData[j] = channelData[j] * volumn; // volunm [0,1] } } } </script> </body>
<body> <script> function printFile() { reader.onload = function () { crunker.fetchAudio("./test.mp3", "./background.mp3") .then(buffers => crunker.mergeAudio(buffers)) .then(merged => crunker.export(merged, "audio/mp3")) .then(output => crunker.download(output.blob)) .catch(error => { throw new Error(error); }); } } </script> </body>
crunker API:
const crunker = new Crunker(); // 获取到全部音频的buffer数据,buffers为数组 crunker.fetchAudio(url1,url2,url3,...) .then(buffers => {}) // 合成多个音频为一个buffer const resultBuffer = crunker.mergeAudio([buffer1,buffer2,buffer3,...]); // 按指定的顺序连接两个或多个音频缓冲区。返回:单个AudioBuffer对象。 const resultBuffer = crunker.concatAudio(arrayOfBuffers); // 导出blob和url对象 type为可选参数:‘audio/mp3’, ‘audio/wav’, ‘audio/ogg’ const blob = crunker.export(audioBuffers, type); // 直接下载 crunker.download(blob,fileName) // 播放 crunker.play(blob) // 如果用户浏览器不支持Web audio API ,自行定义代码. audio.notSupported(callback)
参考: