Recorder | RecordApp
在线测试,RecordApp
源码在/src/app-support目录,当前/app-support-sample
目录为参考配置的演示目录。RecordApp
由Recorder
提供基础支持,所以Recorder
的源码也是属于RecordApp
的一部分。
demo_ios目录内包含IOS App测试源码,和核心文件 RecordAppJsBridge.swift ;clone后用xcode
打开后编译运行(没有Mac OS? 装个黑苹果 )。本demo为swift代码,兼容IOS 9.0+,已测试IOS 12.3。
demo_android目录内包含Android App测试源码,和核心文件 RecordAppJsBridge.java ;目录内 app-debug.apk.zip 为打包好的debug包(40kb,删掉.zip后缀),或者clone后自行用Android Studio
编译打包。本demo为java代码,兼容API Level 15+,已测试Android 9.0。
https://jiebian.life/web/h5/github/recordapp.aspx
此demo页面为代理页面(源),受微信JsSDK的域名限制,直接在github.io
上访问将导致JsSDK
无法调用。
- 在小程序页面内,找任意一个文本输入框,输入
::apitest
,然后点一下别的地方让输入框失去焦点,此时会提示命令已处理
。 - 重启小程序,会发现丑陋的控制台已经显示出来了,在控制台命令区域输入
location.href="/web/h5/github/recordapp.aspx"
并运行。 - 不出意外就进入了上面这个在线测试页面,开始愉快的测试吧。
Android微信H5、WebView支持录音,无需特殊兼容,因此上面特意针对IOS微信。
<!-- 可选的独立配置文件,提供这些文件时可免去修改app.js源码。
注意:使用时应该使用自己编写的文件,而不是使用这个参考用的文件 -->
<!-- 可选开启native支持的相关配置 -->
<script src="app-support-sample/native-config.js"></script>
<!-- 可选开启ios weixin支持的相关配置 -->
<script src="app-support-sample/ios-weixin-config.js"></script>
<!-- 在需要录音功能的页面引入`app-support/app.js`文件(src内的为源码、dist内的为压缩后的)即可。
app.js会自动加载Recorder和编码引擎文件,应确保app.js内BaseFolder目录的正确性。
(压缩时可以把所有支持文件压缩到一起,会检测到组件已自动加载)
(**注意:需要在https等安全环境下才能进行录音**) -->
<script src="src/app-support/app.js"></script>
然后使用,假设立即运行,只录3秒,会自动根据环境使用Native录音、微信JsSDK录音、H5录音
//var dialog=createDelayDialog(); 开启可选的弹框伪代码,需先于权限请求前执行,因为回调不确定是同步还是异步的
//请求录音权限
RecordApp.RequestPermission(function(){
//dialog&&dialog.Cancel(); 如果开启了弹框,此处需要取消
RecordApp.Start({type:"mp3",sampleRate:16000},function(){//mp3格式,指定采样率,其他参数使用默认配置;注意:是数字的参数必须提供数字,不要用字符串;需要使用的type类型,需提前把支持文件到Platforms.Default内注册
setTimeout(function(){
RecordApp.Stop(function(blob,duration){//到达指定条件停止录音
console.log((window.URL||webkitURL).createObjectURL(blob),"时长:"+duration+"ms");
//已经拿到blob文件对象想干嘛就干嘛:立即播放、上传
},function(msg){
console.log("录音失败:"+msg);
});
},3000);
},function(msg){
console.log("开始录音失败:"+msg);
});
},function(msg,isUserNotAllow){//用户拒绝未授权或不支持
//dialog&&dialog.Cancel(); 如果开启了弹框,此处需要取消
console.log((isUserNotAllow?"UserNotAllow,":"")+"无法录音:"+msg);
});
//我们可以选择性的弹一个对话框:为了防止当移动端浏览器使用Recorder H5录音时存在第三种情况:用户忽略,并且(或者国产系统UC系)浏览器没有任何回调
/*伪代码:
function createDelayDialog(){
if(Is Mobile){//只针对移动端
return new Alert Dialog Component
.Message("录音功能需要麦克风权限,请允许;如果未看到任何请求,请点击忽略~")
.Button("忽略")
.OnClick(function(){//明确是用户点击的按钮,此时代表浏览器没有发起任何权限请求
//此处执行fail逻辑
console.log("无法录音:权限请求被忽略");
})
.OnCancel(NOOP)//自动取消的对话框不需要任何处理
.Delay(8000); //延迟8秒显示,这么久还没有操作基本可以判定浏览器有毛病
};
};
*/
参考Recorder中的示例。
欢迎加QQ群:781036591,纯小写口令:recorder
由于IOS上除了Safari
可以H5录音外,其他浏览器、WebView均不能进行H5录音,Android和PC上情况好很多;可以说是仅为兼容IOS上的微信而生。
据艾瑞移动设备指数2019年7月29日数据:苹果占比23.29%
位居第一,华为以19.74%
排名第二。不得不向大厂低头,于是就有了此最大限度的兼容方案;由于有些开发者比较关心此问题,于是就开源了。
当IOS
哪天开始全面支持getUserMedia
录音功能时,本兼容方案就可以删除了,H5原生录音一把梭。
RecordApp
单纯点来讲就是为了兼容IOS的,使用的复杂性比Recorder
高了很多,到底用哪个,自己选
支持 | Recorder | RecordApp |
---|---|---|
PC浏览器 | √ | √ |
Android Chrome Firefox | √ | √ |
Android微信(含小程序) | √ | √ |
Android Hybrid App | √ | √ |
Android其他浏览器 | 未知 | 未知 |
IOS Safari | √ | √ |
IOS微信(含小程序) | √ | |
IOS Hybrid App | √ | |
IOS其他浏览器 | ||
开发难度 | 简单 | 复杂 |
第三方依赖 | 无 | 依赖微信公众号 |
本功能并非拿来就能用的,需要对源码进行调整配置,可参考app-support-sample目录内的配置文件。
使用本功能虽然可以最大限度的兼容Android
和IOS
,但使用app-ios-weixin-support.js需要后端提供支持,如果使用app-native-support.js需要App端提供支持,具体情况查看这两个文件内的注释。
如果不能得到上面相应的支持,并且坚决要使用相关功能,那将会很困难。
- 会自动加载
Recorder
,因此Recorder
支持的功能,RecordApp
基本上都能支持,包括语音通话聊天。 - 优先使用
Recorder
H5进行录音,如果浏览器不支持将使用IOS-Weixin
选项。 - 默认开启
IOS-Weixin
支持,用于支持IOS中微信H5
、小程序WebView
的录音功能,参考ios-weixin-config.js接入配置。 - 可选手动开启
Native
支持,用于支持IOS、Android上的Hybrid App录音,默认未开启支持,参考native-config.js开启Native
支持配置,实现自己App的JsBridge
接口调用;本方式优先级最高。
IOS-Weixin
不支持实时回调,因此当在IOS微信上录音时,实时音量反馈、实时波形、实时转码等功能不会有效果;并且微信素材下载接口下载的amr音频音质勉强能听(总比没有好,自行实现时也许可以使用它的高清接口,不过需要服务器端转码)。IOS-Weixin
使用的微信JsSDK
单次调用录音最长为60秒,底层已屏蔽了这个限制,超时后会立即重启接续录音,因此当在IOS微信上录音时,超过60秒还未停止,将重启录音,中间可能会导致短暂的停顿感觉。demo_ios
中swift代码使用的AVAudioRecorder
来录音,由于录音数据是通过这个对象写入文件来获取的,可能是因为存在文件写入缓存的原因,数据并非实时的flush到文件的,因此实时发送给js的数据存在300ms左右的滞后;AudioQueue
、AudioUnit
之类的更强大的工具文章又少,代码又多,本质上是因为不会用,所以就成这样了。Android WebView
本身是支持录音的(古董版本就算啦),仅需处理网页授权即可,但Android里面使用网页的录音权限问题可能比原生的权限机制要复杂,为了简化js端的复杂性(出问题了好甩锅),不管是Android还是IOS都实现一下可能会简单很多;另外Android和IOS的音频编码并非易事,且不易更新,使用js编码引擎大大简化App的逻辑;因此就有了Android版的Hybrid App Demo。
请求录音权限,如果当前环境不支持录音或用户拒绝将调用错误回调;调用RecordApp.Start
前需先至少调用一次此方法;请求权限后如果不使用了,至少要调用一次Stop
来清理资源。
success
: fn()
有权限时回调
fail
: fn(errMsg,isUserNotAllow)
没有权限或者不能录音时回调,如果是用户主动拒绝的录音权限,除了有错误消息外,isUserNotAllow=true
,方便程序中做不同的提示,提升用户主动授权概率
开始录音,需先调用RecordApp.RequestPermission
。
注:开始录音后如果底层支持实时返回PCM数据,将会回调set.onProcess
事件方法,并非所有平台都支持实时回调,可以通过RecordApp.Current.CanProcess()
方法来检测。
set配置默认值:
{
type:"mp3"//最佳输出格式,如果底层实现能够支持就应当优先返回此格式
sampleRate:16000//最佳采样率hz
bitRate:16//最佳比特率kbps
onProcess:NOOP//如果当前环境支持实时回调(RecordApp.Current.CanProcess()),接收到录音数据时的回调函数:fn(buffers,powerLevel,bufferDuration,bufferSampleRate),此回调和Recorder的回调行为完全一致
}
注意:此对象会被修改,因为平台实现时需要把实际使用的值存入此对象
IOS-Weixin底层会把从微信素材下载过来的原始音频信息存储在set.DownWxMediaData中。
success
: fn()
打开录音时回调
fail
: fn(errMsg)
开启录音出错时回调
结束录音和清理资源。
success
: fn(blob,duration)
结束录音时回调,blob:Blob
录音数据audio/mp3|wav...
格式,duration
: 123
音频持续时间。
fail
: fn(errMsg)
录音出错时回调
对底层平台进行识别和加载相应的类库进行初始化,RecordApp.RequestPermission
只是对此方法进行了一次封装,并且多了一个权限请求而已。如果你只想完成功能的加载,并不想调起权限请求,可手动调用此方法。此方法可以反复调用。
success
: fn()
初始化成功回调
fail
: fn(errMsg)
初始化失败回调
开启了Native
支持时,会有这个方法,用于原生App实时返回pcm数据。
此方法由Native Platform底层实现来调用,在开始录音后,需调用此方法传递数据给js。
pcmDataBase64
: Int16[] Base64
当前单声道录音缓冲PCM片段Base64编码,正常情况下为上次回调本接口开始到现在的录音数据
sampleRate
缓冲PCM的采样率
为RecordApp.Install
初始化后识别到的底层平台,取值为RecordApp.Platforms
之一。
识别的底层平台是否支持实时返回PCM数据,如果返回值为true,set.onProcess
将可以被实时回调。
支持的平台列表,目前有三个:
Native
: 原生App平台支持,底层由实际的JsBridge
提供,此平台默认未开启IOS-Weixin
: IOS微信浏览器
、小程序web-view
支持,底层使用的微信JsSDK
+
Recorder
,此平台默认开启Default
: H5原生支持,底层使用的Recorder H5
,此平台默认开启且不允许关闭
底层平台为RecordApp.Platforms
中定义的值。
每个底层平台都实现了三个方法,Native
在app-native-support.js中实现了,IOS-Weixin
在app-ios-weixin-support.js中实现了,Default
在app.js中实现了。
本底层具体的权限请求实现,参数和RecordApp.RequestPermission
相同。
本底层具体的开始录音实现,参数和RecordApp.Start
相同。
本底层具体的开始录音实现,参数和RecordApp.Stop
相同。
每个底层平台都有一个platform.Config
配置,这个配置是根据平台的需要什么我们这里面就要给什么。另外还有一个全局配置RecordAppBaseFolder
。
文件基础目录,用来定位加载类库,此目录可以是/src/
或者/dist/
,目录内应该包含recorder-core.js、engine
等。实际取值需自行根据自己的网站目录调整,或者加载app.js
前,设置此全局变量。
可提供一个回调函数用来配置RecordApp
,在app.js
内代码执行完毕时回调,免得RecordAppBaseFolder
要在app.js
之前定义,其他配置又要在之后定义的麻烦。使用可以参考app-support-sample/ios-weixin-config.js配置。
无需手动配置。
可以参考app-support-sample/native-config.js中的演示有效的配置。
需提供IsApp
、JsBridgeRequestPermission
、JsBridgeStart
、JsBridgeStop
方法,具体情况请查阅src/app-support/app.js内有详细的说明。
可以参考app-support-sample/ios-weixin-config.js中的演示有效的配置。
需提供WxReady
、DownWxMedia
方法,具体情况请查阅src/app-support/app.js内有详细的说明。
WxReady
: 对使用到的微信JsSDK进行签名,至少要包含startRecord,stopRecord,onVoiceRecordEnd,uploadVoice
接口。签名操作需要后端支持。DownWxMedia
: 对微信录音素材进行下载,下载操作需要后端支持。
以上两个方法都是公众(订阅)号开发范畴,需要注册开通相应的微信服务账号。
如果这个库有帮助到您,请 Star 一下。
你也可以选择使用支付宝或微信给我捐赠: