测试环境 iphoneX 12.4
测试环境 小米 android 9
通过上边两张图可以看出差异 :
IOS中 在点击暂停录音之后,点击继续录音,调用继续录音事件, 会先执行一次继续录音事件再执行开始录音事件
而在android中, 在点击暂停录音之后,点击继续录音,调用继续录音事件, 会先执行一次继续录音事件再执行继续录音事件
在此处涉及到录音计时,平台差异导致定时器一直处于异常,调节时间超出开发预期,做以记录。
在语音播放上,编辑器不会触发语音播放完成事件,android与IOS真机器正常
html
<template> <view class="recording bg-mask" capture-catch:touchmove="preventTouchMove" v-if="show" @tap="close"> <view class="recording-panel flex flex-column justify-between padding-30 " :class="show ? 'show': ''" @tap.stop="returnHandle"> <view class="panel-hd padding-bottom-30"> <view class="time text-center text-32 text-blod">{{voicePath ? playTimeStr: timeStr}}</view> </view> <view class="panel-bd flex justify-between align-center text-26"> <view class="item text-center"> <button class="kiwi-btn bg-transparent" @click="again"> <view class="iconfont ic_zhong_lu mini"></view> </button> <view class="text padding-top-30">重录</view> </view> <view class="item text-center "> <button class="kiwi-btn bg-transparent " @click="startRecordOrPauseRecord"> <view class="iconfont animation-zoom" :class="recording==1 ? 'ic_zan_ting':'ic_bo_fang'"></view> </button> <view class="text padding-top-30">{{!voicePath &&recording==0 ? '开始录音' : !voicePath &&recording==1 ?'暂停录音':!voicePath &&recording==2 ?'继续录音':voicePath&&!voicePlaying ?'试听':voicePath&&voicePlaying ?'停止播放':''}}</view> </view> <view class="item text-center"> <button class="kiwi-btn bg-transparent" @click="endRecord"> <view class="iconfont ic_wan_cheng mini"></view> </button> <view class="text padding-top-30">{{voicePath ? '上传':'完成'}}</view> </view> </view> <view class="panel-fd padding-bottom-20"> <view class="text-center text-26 close" @click="close">取消</view> </view> </view> </view><!-- /.recording[录音] --> </template>
js
<script> const recorderManager = uni.getRecorderManager(); const innerAudioContext = uni.createInnerAudioContext(); // innerAudioContext.autoplay = true; export default { props: { show: {//是否显示录音弹出层 type: [Boolean, String], default: false } }, name: 'recording', data() { return { voicePath: '',//录音的临时地址 time:0 ,//录音时间 recording:0,//是否已在录音中 0未开始,1已开始 2暂停中 timeId:null,//定时器id voicePlaying:false,//是否在曲子播放中 oplayTime:0,//缓存播放时间, playTime:0,//播放时间, playTimeId:null,//播放时间定时器 recorderAgain:false,//重新录制 }; }, computed: { timeStr:function(){ //录音时长 let m = parseInt(this.time/60); m < 10&&(m = '0'+m) let s = this.time%60; s < 10&&(s = '0'+s) return m +' : '+ s; }, playTimeStr:function(){ //播放时长 let m = parseInt(this.playTime/60); m < 10&&(m = '0'+m) let s = this.playTime%60; s < 10&&(s = '0'+s) return m +' : '+ s; }, }, mounted() { let _this = this; recorderManager.onStop(function(res) { //结束录音 _this.playTime = _this.time;//缓存录制的时长到试听时间上 _this.oplayTime = _this.time;//缓存录制的时长到试听时间上 _this.time = 0;//时间清零 clearInterval(_this.timeId) _this.timeId = null _this.recording = 0 console.log(res); console.log('结束录音回调') if(!_this.recorderAgain){//非点击重录 _this.voicePath = res.tempFilePath; } }); recorderManager.onStart(function(res) { //开始录音 _this.recording = 1 _this.recorderAgain = false console.log('开始录音回调') clearInterval(_this.timeId) _this.timeId = setInterval(()=>{ _this.time = _this.time + 1 },1000) }); recorderManager.onPause(function(res) { //暂停录音 clearInterval(_this.timeId) _this.timeId = null _this.recording = 2 console.log('暂停录音回调') }); recorderManager.onError(function(res) { //录音出错 clearInterval(_this.timeId) _this.timeId = null console.log(res); console.log('录音出错回调') }); recorderManager.onResume(function(res) { //继续录音 _this.recording = 1 clearInterval(_this.timeId) _this.timeId = setInterval(()=>{ _this.time = _this.time + 1 },1000) console.log('继续录音回调') }); innerAudioContext.onPlay(() => {//播放录音 _this.voicePlaying = true _this.playTimeId = setInterval(()=>{ _this.playTime = _this.playTime - 1 },1000) console.log('开始播放'); }); innerAudioContext.onPause(() => {//暂停播放 _this.voicePlaying = true clearInterval(_this.playTimeId) _this.playTimeId = null console.log('暂停播放'); }); innerAudioContext.onStop(() => {//停止播放 _this.voicePlaying = false _this.playTime = _this.oplayTime; clearInterval(_this.playTimeId) _this.playTimeId = null console.log('停止播放'); }); innerAudioContext.onEnded(() => {//播放完成 _this.voicePlaying = false _this.playTime =_this.oplayTime; clearInterval(_this.playTimeId) _this.playTimeId = null console.log('播放完成停止'); }); }, methods: { returnHandle:function(){//遮罩层内部弹窗区域点击拦截关闭事件 return ; }, again:function(){ this.time = 0; this.playTime = 0; this.voicePath = '' this.recorderAgain = true clearInterval(this.playTimeId) clearInterval(this.timeId) this.playTimeId = null this.timeId = null if(this.recording != 0){ this.endRecord()//停止录音 } if(this.voicePlaying){ this.stopVoice();//停止播放 } }, startRecordOrPauseRecord:function(){//开始录制或继续录制或者暂停录制 if(!this.voicePath){//无有录音 if(this.recording ==0){//开始录音 this.startRecord() }else if(this.recording ==1){//暂停录音 this.pauseRecord() }else if(this.recording ==2){//继续录音 this.resumeRecord() } }else{//已有录音出发语音播放 if(!this.voicePlaying){//开始播放 this.playVoice() }else{ this.stopVoice() } } }, preventTouchMove: function() { return; }, close: function() { this.$bus('closeRecording', null); console.log('取消') }, startRecord: function() { console.log('开始录音'); const options = { duration: 600000, sampleRate: 44100, numberOfChannels: 1, encodeBitRate: 192000, format: 'aac', // frameSize: 50 } recorderManager.start(options); }, endRecord: function() { if(this.voicePath){//上传录音 this.$base.defaults.toast('上传完成') this.$bus('closeRecording', null); return false } console.log('录音结束'); console.log(this.recording) if(this.recording != 0){ recorderManager.stop(); }else{ console.log('未开始无需结束'); } }, pauseRecord: function() { console.log('暂停录音'); recorderManager.pause(); }, resumeRecord: function() { console.log('继续录音'); recorderManager.resume(); }, playVoice: function() { console.log('播放录音'); if (this.voicePath) { innerAudioContext.src = this.voicePath; innerAudioContext.play(); } }, pauseVoice:function(){ console.log('暂停播放'); innerAudioContext.pause(); }, stopVoice:function(){ console.log('停止播放'); innerAudioContext.stop(); } } } </script>
css
<style scoped lang="scss"> .recording { width: 100%; position: fixed; bottom: 0; top: 0; left: 0; right: 0; } .recording-panel { position: absolute; bottom:-550upx; left: 0; right: 0; width: 100%; height: 500upx; background: #fff; border-top-left-radius: 40upx; border-top-right-radius: 40upx; padding-bottom: constant(safe-area-inset-bottom); padding-bottom: env(safe-area-inset-bottom); transition: all ease .8s; &.show{ bottom:0; } } .panel-bd { .item { width: 33.3333%; } .kiwi-btn { height: 180upx; } .iconfont { height: 180upx; width: 180upx; line-height: 180upx; border-radius: 180upx; background: #ffa521; color: #fff; margin: 0 auto; font-size: 50upx; font-weight: 900; &.mini { height: 100upx; width: 100upx; line-height: 100upx; border-radius: 100upx; background: #89b8ff; color: #fff; font-size: 30upx; } } } .close { color: #CCCCCC; } .animation-zoom{ animation: all ease .8s; } </style>