源码学习——crunker音频库

前言

前段时间做了一个合并音频的需求,当时用了crunker库快速完成了该需求,后面抽时间翻了下crunker源码,发现该库源码写的也非常清晰,主要是用Audio相关API完成的,简单易懂,本节我就来介绍一下crunker源码。

源码

crunker是利用音频API处理音频的库,有合并、导出、下载等功能,打开对应的github,找到src文件夹,crunker.ts文件就是各个方法的源码。

转换

fetchAudio 用于将音频文件转换为AudioBuffer;我们先明确AudioBuffer是什么?AudioBuffer就是内存中的音频资源,日常开发中我们拿到的音频一般是保存地址,说白了就是一段字符串,不可能进行二次操作,并且Web的Aduio API往往是对内存中的资源进行操作,所以我们先拿到音频资源。实现该方法分成了两步:

  1. 通过fetch请求文件地址,获取ArrayBuffer数据。
  2. new一个AudioContext,将ArrayBuffer转换成AudioBuffer。

步骤非常简单,但是我们最好了解用到的API,方便理解:

  • fetch:一个异步获取资源的API,返回一个promise对象。
  • AudioContext:音频上下文,可以处理音频,比如创建、解码等。
  • AudioContext.decodeAudioData:AudioContext的一个方法,用来解码ArrayBuffer,返回AudioBuffer。
  • ArrayBuffer:数据缓冲区,可以用来操作和存储二进制数据。

通过以上分析我们就能写出fetchAduio函数,这里我们就以单个录音地址为参数,源码中是接收录音地址数组为参数。

合并

mergeAudio可以用多个AudioBuffer数据合并成一个AduioBuffer,结合着fetchAudio它可以用合并多个音频文件,具体步骤如下:

  1. 使用createBuffer创建一个空白的AudioBuffer,用来存储合并后的AudioBuffer。
  2. 循环AudioBuffer数组,获取对应的音频通道数据。
  3. 循环音频通道数据,添加到空白AudioBuffer对应的通道中。 合并要复杂点,这里运用了两次循环,我们要清楚每次循环的目的是什么?在此之前我们还是要了解新的API:
  • AudioContext.createBuffer:创建空白AudioBuffer对象。
  • AudioBuffer.numberOfChannels:表示音频通道数,也就是我们说的声道,声道一般就是单声道(Mono)和立体声(Stereo),所以该值一般为1或者2。
  • AudioBuffer.getChannelData:获取各个通道中的PCM数据。
    注意,我们在创建AudioBuffer时传递的参数,比如声道数、时间必须是参数数组中的最大值,这样才能保证所有的音频数据被合并。

播放

play用来播放音频,接收一个AudioBuffer。播放的思路就很简单,创建音频源进行播放。用到的API如下:

  • AudioContext.createBufferSource创建音频源,可以接收AudioBuffer来进行播放。
  • connect:音频源方法,连接到目标节点。
  • start:音频源方法,播放音频。

总结

以上方法理解起来并不困难,用到的API都是Audio API,我相信大部分人不会专门去MDN翻看这些API,通过学习源码我们就能理解掌握,下次碰到Audio相关就会有相关思路,甚至慢慢写出复杂逻辑。上述案例是用js重构了一下,源码用的是ts,感兴趣的可以继续探索。

相关推荐
秋秋小事4 分钟前
React Hooks useContext
前端·javascript·react.js
Jinuss6 分钟前
Vue3源码reactivity响应式篇之reactive响应式对象的track与trigger
前端·vue3
striver_#7 分钟前
百度前端社招面经二
前端
xcnn_8 分钟前
前端入门——案例一:登录界面设计(html+css+js)
前端·css·html
ST.J8 分钟前
前端笔记2025
前端·javascript·css·vue.js·笔记
拉不动的猪9 分钟前
回顾vue中的Props与Attrs
前端·javascript·面试
Jerry1 小时前
使用 Material 3 在 Compose 中设置主题
前端
chéng ௹1 小时前
uniapp 封装uni.showToast提示
前端·javascript·uni-app
tuokuac1 小时前
nginx配置前端请求转发到指定的后端ip
前端·tcp/ip·nginx
程序员爱钓鱼1 小时前
Go语言实战案例-开发一个Markdown转HTML工具
前端·后端·go