#uni-app 实现语音播放功能demo
== 思路 1==
- 从消息列表中筛选出单独的语音列表,
- 在消息列表中添加字段,语音列表的index和消息列表中的index对应
- 语音列表添加标识,区分播放状态和展示状态
- 消息列表展示,点击事件传入语音列表的index
- audio对象处理语音播放和切换事件(样式和语音)
- 切换、暂停等事件添加
== 思路 2==
- 从消息列表中的语音信息添加字段,表示当前的语音状态(展示/播放)
- 消息列表展示,点击事件传入消息列表的index
- 遍历消息列表中的语音信息,处理选中的效果
- audio对象处理语音播放事件
== 思路 1的实现==
<template>
<view>
<view v-for="(v,i) in chatRecordList" :key="i">
<view class="chatitem" >
<view class="d-flex d-left time">
<label>测试测试 {{v.createTime}}</label>
</view>
<view class="d-flex d-left">
<view class="patientimg">
<image src="../../static/images/default-doctor.png" mode="aspectFit"></image>
</view>
<view class="contentleft" v-if="v.msgType==1">
<label v-html='v.content'></label>
</view>
<view class="contentleft" v-if="v.msgType==2">
<view class="display:inline-block" @click="playAudio(v.audioIndex)">
<image class="yuyinimg" v-show="!audioList[v.audioIndex].playFlag" src="../../static/images/sound3.png"></image>
<image class="yuyinimg" v-show="audioList[v.audioIndex].playFlag" src="../../static/images/sound3.gif"></image>
<label> {{v.msgTimeLength}}s</label>
</view>
</view>
<view class="contentleft" v-if="v.msgType==4">
<image :src="v.content" mode="aspectFit" @click="showBigImg(v.content)"></image>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
chatRecordList:[],//所有消息列表
audioIndex:0,//语音消息index
audioLength:0,//语音消息数量
audioList:[],//语音消息列表
audio:{},//语音播放对象
}
},
onLoad() {
//初始化语音播放对象----可以优化到判断语音数量不为0的情况下初始化audio对象
this.audio = uni.createInnerAudioContext();
this.audio.autoplay = true;
//所有消息
this.chatRecordList = [{"id":985361,"orderId":"1293461523256213000","orderNo":"202105268946468190","createTime":"2021-05-27 16:05:16","fromUserId":4092,"toUserId":397025,"msgType":2,"content":"https://xxxxx/webstatic/group1/M00/0A/95/wKgBUWCvUVOAL2oyAAHRLFiy1y8022.mp3","msgStatus":1,"updateTime":null,"userType":1,"msgTimeLength":3},{"id":985360,"orderId":"1293461523256213000","orderNo":"202105268946468190","createTime":"2021-05-27 16:05:09","fromUserId":4092,"toUserId":397025,"msgType":2,"content":"https://xxxxxx/webstatic/group1/M00/0A/95/wKgBUWCvUUuAKCKkAAIrLNJ05Qw622.mp3","msgStatus":1,"updateTime":null,"userType":1,"msgTimeLength":4},{"id":985359,"orderId":"202105268946468190","orderNo":"202105268946468190","createTime":"2021-05-27 16:04:12","fromUserId":677201,"toUserId":4092,"msgType":4,"content":"https://xxxx/dfs/group1/M00/0A/BA/wKgKHGCvUnyAHrMTAADu8lnDb88757.png","msgStatus":1,"updateTime":null,"userType":0,"msgTimeLength":null},{"id":985358,"orderId":"202105268946468190","orderNo":"202105268946468190","createTime":"2021-05-27 16:04:04","fromUserId":677201,"toUserId":4092,"msgType":1,"content":"11111","msgStatus":1,"updateTime":null,"userType":0,"msgTimeLength":null}]
let _this = this;
_this.audioIndex = 0;
//过滤出语音播放列表,并且添加关联的index
this.audioList =this.chatRecordList.filter(function(item,i){
console.log("data.data.list",data.data.list[i]);
if(item.msgType==2){
_this.chatRecordList[i].audioIndex = _this.audioIndex;
_this.audioIndex++;
_this.$set(item,"playFlag",false)//需要加入observe,切换效果,使用$set
return item;
}
})
this.audioLength = this.audioList.length;
},
methods: {
playAudio(i){
let Audio = this.audio;
let curAudioInfo = this.audioList[i];
let _this = this;
if(curAudioInfo.playFlag){//当前正在播放,切换效果,暂停播放
curAudioInfo.playFlag=false;
Audio.pause();
console.log("点击正在播放的语音,暂停播放");
return;
}
//样式切换
_this.audioList.forEach(function(item,index){
_this.audioList[index].playFlag=false;
});
curAudioInfo.playFlag = true;
Audio.src = curAudioInfo.content; //音频地址
Audio.play();//执行播放
Audio.onPlay(function(){
console.log("开始播放");
});
Audio.onError((res) => {
curAudioInfo.playFlag = false;
uni.showToast({
title:res.errCode+","+res.errMsg,
icon:"none"
})
});
Audio.onPause(function() {
console.log('pause');
curAudioInfo.playFlag = false;
});
Audio.onEnded(function(){
console.log('end');
curAudioInfo.playFlag = false;
});
}
}
}
</script>
动态播放&静态展示效果图