by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=11026 鑫空间-鑫生活
本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可以联系授权。
如今的Web越来越强,几乎常见的音视频开发需求都能使用纯JS搞定了。
这里介绍一个不太常见的使用场景的技术实现。
啥呢,就是音频的音量调整,并转换成新文件。
如果仅仅是调整播放的音量,那很简单。
如果你使用的是 <audio>
元素,直接改变volume
属性就好了。
audio.volume = 0.5;
over~
如果没有audio元素,而是使用的Web Audio API,希望在 AudioBuffer 层面设置播放的音量,则可以使用GainNodes实现。
假设我们有个在线的MP3音频叫做“bgmusic.mp3”,则可以这么处理。
// 定义一个AudioContext对象 // 因为 Web Audio API都是源自此对象 const audioContext = new AudioContext(); // 创建一个gainNode对象 // 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.start(0);
您可以狠狠地点击这里体验效果:使用gainNode改变音频播放音量demo
上面的是原音频,音量还是很猛的。
点击下面的按钮,则会听到轻很多的声音,这个音量的降低就是GainNodes实现的。
然而,GainNodes降低音量仅仅是在播放层面的控制,并不是改变原始的音频音量大小。
所以,如果现在有个需求,希望可以下载这个音量减小后的音频,那使用gainNode API 实现的方法就无效,此时,需要借助其他的方法。
音频的本质是波,现实世界的波是连续的,但是音频却不是,本质上是一个一个的点采样来的。
如下图所示:
例如在1s内打48000个点,那么采样率就是48000。
采样率越高,音频质量越好,音频文件的体积也就越大。
所以,想要改变音频原始的音量,可以获取到音频每个点的采样数据,然后和音量对应的比例相乘就好了。
OK,原理清楚了,那该怎么实现呢?
嗯……想了下,还是直接放代码吧,没多少人对ArrayBuffer,AudioBuffer,AudioData等概念有兴趣的。
就是这个,拿去复制粘贴吧。
// 音量 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; } } });
此时,newAudioBuffer
就是音量降低到20%时候的audioBuffer数据。
我们可以使用此数据进行音频的播放,或者编码,或者下载,都可以。
这个以前其实分享过,纯JS合成音频,或者说AudioBuffer数据转音频,目前只支持wav格式(哪怕后缀是mp3,其实也是wav格式)。
// 转换 AudioBuffer 为 Wave 格式的 Blob 地址 function bufferToWave(abuffer, len) { // 略,详见下面的演示页面 }
您可以狠狠地点击这里:MP3音频在线音量降低并下载demo
点击按钮后,执行类似下面的JS代码:
const blob = bufferToWave(newAudioBuffer, newAudioBuffer.length);
就可以get到音量降低后的音频了,你也可以选择下载此音频。
本文只是开胃菜,下一篇文章,我们会更进一步,看看如何借助 Web Audio API 实现音频的拼接与合并。
噢啦,将捏。
“将捏”是再见的意思。
表示本文正文内容到此为止了。
要是本文的内容对你的工作或学习帮了大忙,想要聊表谢意,可以等什么时候京东搞活动的时候,入手我的《CSS世界》三部曲……之一就可以了。
当然,也欢迎点赞或。
😋 😛 😝 😜 🤪
本文为原创文章,欢迎分享,勿全文转载,如果实在喜欢,可收藏,永不过期,且会及时更新知识点及修正错误,阅读体验也更好。
本文地址:https://www.zhangxinxu.com/wordpress/?p=11026
(本篇完)