【源GitHub仓库】 | 【Gitee镜像库】本文档中默认使用github.io部署的链接,如果无法访问,请直接下载仓库源码到本地然后双击打开html文件访问。
支持在大部分已实现getUserMedia的移动端、PC端浏览器麦克风录音、实时处理,主要包括:Chrome、Firefox、Safari、iOS 14.3+、Android WebView、腾讯Android X5内核(QQ、微信、小程序WebView)、Electron、大部分2021年后更新的Android手机自带浏览器、2024年后更新的Android版UC内核(UC、支付宝、钉钉);不支持:~~老旧国产手机自带浏览器、老旧iOS(11.0-14.2)上除Safari外的其他任何形式的浏览器~~。
支持在非浏览器环境中使用部分功能(如nodejs、各种使用js来构建的程序),使用RecordApp可在微信小程序、uni-app中直接录音。
支持对任意MediaStream进行音频录制、实时处理,包括:getUserMedia返回的流、WebRTC中的remote流、audio、video标签的captureStream方法返回的流、自己创建的流 等等。
提供多个插件功能支持,拥有丰富的音频可视化、变速变调处理、语音识别、音频流播放等;搭配上强大的实时处理支持,可用于各种网页应用:从简单的录音,到复杂的实时语音识别(ASR),甚至音频相关的游戏,都能从容应对;提供转码支持,允许将录制的buffers数据或任意pcm数据转码成你需要的格式(参考rec.mock方法)。
主要用于语音录制,因此仅对单声道进行支持(未适配双声道),支持超长时间录音(参考rec.buffers);默认输出mp3格式,另外可选wav、pcm、g711a、g711u、ogg、amr、webm(beta)格式,支持任意格式扩展(前提有相应编码器);使用recorder.mp3.min.js(150kb)即可录制mp3,使用recorder.wav.min.js(25kb)即可录制wav;均支持实时转码和实时传输。
音频文件的上传和播放:可直接使用常规的Audio HTML标签来播放完整的音频文件,参考文档下面的【快速使用】部分,有上传和播放例子;上传了的录音直接将音频链接赋值给audio.src即可播放;本地的blob音频文件可通过URL.createObjectURL来生成本地链接赋值给audio.src即可播放,或者将blob对象直接赋值给audio.srcObject(兼容性没有src高)。实时的音频片段文件播放,可以使用本库自带的BufferStreamPlayer插件来播放,简单高效,或者采用别的途径播放。
如需录音功能定制开发,网站、App、小程序、前端后端开发等需求,请加本文档下面的QQ群,联系群主(即作者),谢谢~
Recorder H5 : [ H5在线测试 ] [ H5 QuickStart ] [ H5 vue ] [ H5 ts ] [ 旧版本测试 ]
Recorder App : [ RecordApp测试 ] [ App QuickStart ] [ App vue ] [ Android、iOS App源码 ] [ 微信小程序源码 ] [ uni-app源码 ]
工具集 : [ Recorder代码运行和静态分发 ] [ PCM转WAV播放测试和转码 ] [ 无用户操作测试 ] [ Can I Use查看浏览器支持情况 ]
Android Demo App : 下载APK(40kb,删除.zip后缀, 源码)
iOS Demo App :下载源码 自行编译
欢迎加QQ群:①群 781036591、②群 748359095、③群 450721519,纯小写口令:recorder

你可以通过阅读和运行QuickStart.html文件来快速入门学习,直接将QuickStart.htmlcopy到你的(https、localhost)网站中,无需其他文件,就能正常开始测试了;注意:需要在https、localhost等安全环境下才能进行录音。
https环境搭建最佳实践:建议给自己的域名申请一个泛域名通配符证书(*.xxx.com),然后线上、本地开发均可使用此证书;本地开发环境直接分配一个三级域名(dev.xxx.com、local.xxx.com、192-168-1-123.xxx.com)解析A记录到电脑局域网的IP地址(192.168.1.123、127.0.0.1),方便本地开发跨端调试(本地如何配置https请针对自己的开发环境自行搜索,很容易)。
获取泛域名通配符证书推荐:在线免费申请(ZeroSSL、Let’s Encrypt);不建议自己生成根证书来签发域名证书,一个是流程复杂,每个设备均要导入根证书,致命的是很多现代浏览器不再信任用户目录下导入的根证书(Android)。
如果必须http访问,Chrome中可尝试打开
chrome://flags/#unsafely-treat-insecure-origin-as-secure,启用Insecure origins treated as secure,把你的地址含端口配置进去,然后重启浏览器。
Recorder的所有js文件均为手动引入(内部不会自动引用),因此未被你引入的文件均可删除来精简源码大小。
方式一:使用script标签引入
在需要录音功能的页面引入压缩好的recorder.xxx.min.js文件即可(CDN:JsDelivr、unpkg)
<script src="https://github.com/xiangyuecn/Recorder/raw/1.3.25011100/recorder.mp3.min.js"></script>
或者直接使用源码(src内的为源码、dist内的为压缩后的),可以引用src目录中的recorder-core.js+相应类型的实现文件,比如要mp3录音:
<script src="https://github.com/xiangyuecn/Recorder/raw/1.3.25011100/src/recorder-core.js"></script>
<script src="https://github.com/xiangyuecn/Recorder/raw/1.3.25011100/src/engine/mp3.js"></script>
<script src="https://github.com/xiangyuecn/Recorder/raw/1.3.25011100/src/engine/mp3-engine.js"></script>
<script src="https://github.com/xiangyuecn/Recorder/raw/1.3.25011100/src/extensions/waveview.js"></script>
方式二:通过import/require引入
通过 npm 进行安装 npm install recorder-core --registry=https://registry.npmmirror.com/ ,如果直接clone的源码下面文件路径调整一下即可
//必须引入的核心,换成require也是一样的。注意:recorder-core会自动往window下挂载名称为Recorder对象,全局可调用window.Recorder,也许可自行调整相关源码清除全局污染
import Recorder from 'recorder-core' //注意如果未引用Recorder变量,可能编译时会被优化删除(如vue3 tree-shaking),请改成 import 'recorder-core',或随便调用一下 Recorder.a=1 保证强引用
//引入相应格式支持文件;如果需要多个格式支持,把这些格式的编码引擎js文件放到后面统统引入进来即可
import 'recorder-core/src/engine/mp3'
import 'recorder-core/src/engine/mp3-engine' //如果此格式有额外的编码引擎(*-engine.js)的话,必须要加上
//以上三个也可以合并使用压缩好的recorder.xxx.min.js
//比如 import Recorder from 'recorder-core/recorder.mp3.min' //已包含recorder-core和mp3格式支持
//可选的插件支持项,把需要的插件按需引入进来即可
import 'recorder-core/src/extensions/waveview'
//ts import 提示:npm包内已自带了.d.ts声明文件(不过是any类型)
这里假设只录3秒,录完后立即播放,在线编辑运行此代码>>。录音结束后得到的是Blob二进制文件对象,可以下载保存成文件、用FileReader读取成ArrayBuffer或者Base64给js处理,或者参考下一节上传示例直接上传。
``` javascript
//简单控制台直接测试方法:在任意(无CSP限制)页面内加载需要的js,加载成功后再执行一次本代码立即会有效果
//①加载Recorder+mp3:await import("https://unpkg.com/recorder-core/recorder.mp3.min.js"); console.log("import ok")
//②可视化插件和显示:await import("https://unpkg.com/recorder-core/src/extensions/waveview.js"); console.log("import ok"); div=document.createElement("div");div.innerHTML='
';document.body.prepend(div);
var rec,processTime,wave; /调用open打开录音请求好录音权限/ var recOpen=function(success){//一般在显示出录音按钮或相关的录音界面时进行此方法调用,后面用户点击开始录音时就能畅通无阻了 rec=Recorder({ //本配置参数请参考下面的文档,有详细介绍 type:"mp3",sampleRate:16000,bitRate:16 //mp3格式,指定采样率hz、比特率kbps,其他参数使用默认配置;注意:是数字的参数必须提供数字,不要用字符串;需要使用的type类型,需提前把格式支持文件加载进来,比如使用wav格式需要提前加载wav.js编码引擎 ,onProcess:function(buffers,powerLevel,bufferDuration,bufferSampleRate,newBufferIdx,asyncEnd){ //录音实时回调,大约1秒调用12次本回调,buffers为开始到现在的所有录音pcm数据块(16位小端LE) //可利用extensions/sonic.js插件实时变速变调,此插件计算量巨大,onProcess需要返回true开启异步模式 //可实时上传(发送)数据,配合Recorder.SampleData方法,将buffers中的新数据连续的转换成pcm上传,或使用mock方法将新数据连续的转码成其他格式上传,可以参考文档里面的:Demo片段列表 -> 实时转码并上传-通用版;基于本功能可以做到:实时转发数据、实时保存数据、实时语音识别(ASR)等 processTime=Date.now();
//可实时绘制波形(extensions目录内的waveview.js、wavesurfer.view.js、frequency.histogram.view.js插件功能)
wave&&wave.input(buffers[buffers.length-1],powerLevel,bufferSampleRate);
}
});
rec.open(function(){//打开麦克风授权获得相关资源
//rec.start() 此处可以立即开始录音,但不建议这样编写,因为open是一个延迟漫长的操作,通过两次用户操作来分别调用open和start是推荐的最佳流程
//创建可视化,指定一个要显示的div
if(Recorder.WaveView)wave=Recorder.WaveView({elem:".recwave"});
success&&success();
},function(msg,isUserNotAllow){//用户拒绝未授权或不支持
console.log((isUserNotAllow?"UserNotAllow,":"")+"无法录音:"+msg);
});
};
/开始录音/ function recStart(){//打开了录音后才能进行start、stop调用 rec.start();
//【稳如老狗WDT】可选的,监控是否在正常录音有onProcess回调,如果长时间没有回调就代表录音不正常
var wdt=rec.watchDogTimer=setInterval(function(){
if(!rec || wdt!=rec.watchDogTimer){ clearInterval(wdt); return } //sync
if(Date.now()<rec.wdtPauseT) return; //如果暂停录音了就不检测:puase时赋值rec.wdtPauseT=Date.now()*2(永不监控),resume时赋值rec.wdtPauseT=Date.now()+1000(1秒后再监控)
if(Date.now()-(processTime||startTime)>1500){ clearInterval(wdt);
console.error(processTime?"录音被中断":"录音未能正常开始");
// ... 错误处理,关闭录音,提醒用户
}
},1000);
var startTime=Date.now(); rec.wdtPauseT=0; processTime=0;
};
/结束录音/ function recStop(){ rec.watchDogTimer=0; //停止监控onProcess超时 rec.stop(function(blob,duration){
//简单利用URL生成本地文件地址,注意不用了时需要revokeObjectURL,否则霸占内存
//此地址只能本地使用,比如赋值给audio.src进行播放,赋值给a.href然后a.click()进行下载(a需提供download="xxx.mp3"属性)
var localUrl=(window.URL||webkitURL).createObjectURL(blob);
console.log(blob,localUrl,"时长:"+duration+"ms");
rec.close();//释放录音资源,当然可以不释放,后面可以连续调用start;但不释放时系统或浏览器会一直提示在录音,最佳操作是录完就close掉
rec=null;
//已经拿到blob文件对象想干嘛就干嘛:立即播放、上传、下载保存
/*** 【立即播放例
$ claude mcp add Recorder \
-- python -m otcore.mcp_server <graph>