前言
最近项目有一个录音功能 之前就有人反馈录音的结尾总是被截断 但是当时开发周期比较紧张 现在回过头来详细测试了几个机型的实际情况 在两个平台上 确实有表现不一直的地方 导致录音结尾被截断
现象
测试机型:
安卓端:MI 8 SE/ MI 9
IOS端:iphone7/iphone8P
录音相关API:RecorderManager
https://developers.weixin.qq.com/miniprogram/dev/api/media/recorder/RecorderManager.html
假如我们需要录一段固定5秒时长的音频
wxml代码:
<button ontap="record">{{str}}button>
<view style=“height:30rpx;width:100%;”>view> <button ontap=“play”>播放录音button>
js代码
const app = getApp()
const recorderManager = wx.getRecorderManager();
const InnerAudioContext = wx.createInnerAudioContext();
InnerAudioContext.autoplay = false;
var gettimestamp = function(){
return Math.ceil(new Date().getTime());//获取当前时间戳
}
Page({
data: {
str:"开始录音",
src:false,
},
record(){
if(this.lock){
console.log('recording')
return;
}
this.lock = true;
recorderManager.onStart(()=>{
this.timestamp2 = gettimestamp();//recorderManager系统提供的开始录音时间点
this.setData({
str:"正在录音..."
})
//业务及页面表现相关代码
})
recorderManager.onStop((res)=>{
//业务及页面表现相关代码
this.lock = false;
this.setData({
str:"录音完毕 重新录音"
})
InnerAudioContext.src=res.tempFilePath;
console.log( '从点击录音按钮的时间点到现在经过时间:', gettimestamp() - this.timestamp1 )
console.log( '从开始录音回调事件时间点到现在经过时间:', gettimestamp() - this.timestamp2 )
})
this.timestamp1 = gettimestamp();//点击录音按钮的时间点
recorderManager.start({
format: "wav",
duration: 5*1000,
})
},
play(){
if(!this.data.src){
wx.showToast({
icon:"none",
title: '还未录音',
})
return;
}
InnerAudioContext.play();
}
})
代码片段:https://developers.weixin.qq.com/s/EXMrulmW7Rji
这时候运行代码 我们看到控制台打印结果 从点击录音按钮的时间点到现在经过时间 和 从开始录音回调事件时间点到现在经过时间 不同 这一点在IOS上和安卓上有明显差异
IOS上的时间差 要比 安卓上大得多!而且从 从开始录音回调事件时间点到现在经过时间 与 我们设置的5秒并不是完全一致的 这个时间间隔总会大于5秒 而且视设备而定 性能越差的设备 多出的时间间隔越长
另外 我们可以刻意在开头和结尾说不同的内容 会发现安卓和IOS的表现不一致 IOS的结尾被截断了 按钮的文字变化也要慢一些 其实在文字变成 录音结束之前 设备录音就已经结束了
也就是说 在IOS设备上 使用 recorderManager.start() 的 duration 属性 会截断一部分录音 实际录音文件会小于5秒 那怎么办呢?
对IOS兼容
我们开始根据平台改良我们的代码 不设置 recorderManager.start() 的 duration 字段 使其为默认值 在 recorderManager.onStart() 通过延时5秒使用 recorderManager.stop() 来结束音频录音
这时候 recorderManager.onStop() 会捕获结束音频事件
改造后的record方法:
record(){
if(this.lock){
console.log('recording')
return;
}
this.lock = true;
recorderManager.onStart(()=>{
//业务及页面表现相关代码
this.timestamp2 = gettimestamp();//recorderManager系统提供的开始录音时间点
this.setData({
str:"正在录音..."
})
this.settimeout = setTimeout(()=>{
let stopaction = setTimeout(() => {
recorderManager.stop();
clearTimeout(stopaction)
}, 5*1000)
})
})
recorderManager.onStop((res)=>{
//业务及页面表现相关代码
this.lock = false;
this.setData({
str:"录音完毕 重新录音"
})
InnerAudioContext.src=res.tempFilePath;
console.log( '从点击录音按钮的时间点到现在经过时间:', gettimestamp() - this.timestamp1 )
console.log( '开始录音回调事件时间点到现在经过时间:', gettimestamp() - this.timestamp2 )
})
this.timestamp1 = gettimestamp();//点击录音按钮的时间点
recorderManager.start({
format: "wav",
})
},
代码片段:https://developers.weixin.qq.com/s/Z8NI1lmz7Sjx
测试改造后的代码 在IOS好了 顺利的录到了结尾
但是! 可但是! 但可是!IOS的结尾补上了 安卓这边又出问题了 安卓这边明显多出了那段时间间隔 这段时间和IOS那边补上的正好相同 真是拆了东墙补西墙
没办法只能上终极手段了 通过判断平台 对两个平台做兼容
最终解决方案
通过 wx.getSystemInfoSync() 获取设备所属的平台 改造record方法
record(){
let systemparams = wx.getSystemInfoSync();
if(this.lock){
console.log('recording')
return;
}
this.lock = true;
recorderManager.onStart(()=>{
//业务及页面表现相关代码
this.timestamp2 = gettimestamp();//recorderManager系统提供的开始录音时间点
this.setData({
str:"正在录音..."
})
if (systemparams.platform == 'ios') {
let stopaction = setTimeout(() => {
recorderManager.stop();
clearTimeout(stopaction)
}, 5*1000)
}
})
recorderManager.onStop((res)=>{
//业务及页面表现相关代码
this.lock = false;
this.setData({
str:"录音完毕 重新录音"
})
InnerAudioContext.src=res.tempFilePath;
console.log( '从点击录音按钮的时间点到现在经过时间:', gettimestamp() - this.timestamp1 )
console.log( '开始录音回调事件时间点到现在经过时间:', gettimestamp() - this.timestamp2 )
})
this.timestamp1 = gettimestamp();//点击录音按钮的时间点
if (systemparams.platform == 'ios') {
recorderManager.start({
format: "wav",
});
} else {
recorderManager.start({
format: "wav",
duration: 1000 * 5
});
}
},
代码片段:https://developers.weixin.qq.com/s/XNOizlm87pj8
注意
上面是录一段定长的音频 如果是要录制不定时长的需求 只需兼容安卓端的情况即可 倘若不在乎安卓端结尾多出的部分 其实也不影响实际效果
结语
归根结底 两个平台上出现差异的原因主要是两个平台行对API的封装方法不同 也可能因为两个平台提供的API存在限制不能达到一致的效果
如果有其他建议 或 demo中出现问题 欢迎指正
以上是关于录音功能在两个平台的差异及解决方法 觉得不错点个赞吧