要实现的是这种的一个样子!本地调试或真机调试不是很流畅,可以发到小程序体验版上去试试效果
<template>
<view class="audio-component">
<view class="audio-slider">
<view class="img-box" @click="playAudio">
<image v-show="state" src="./_play.png" class="laba"></image>
<image v-show="!state" src="./_Suspend.png" class="laba"></image>
</view>
<slider block-size='14' :value="sliderProgressValue" @change="sliderChange" min="0" :max="sliderMax" activeColor='#12C489' block-color="#12C489" step="1"/>
<view class="close-box" @click="close">
<image src="./_close.png" ></image>
</view>
</view>
<view class="text-content">
<text>录音</text>
<view class="time-Show">{{currentTimeStr}}/{{sliderValue}}</view>
</view>
</view>
</template>
<script>
export default {
props:{
presentData:{
type:Object,
default:()=>{},
}
},
data(){
return{
sliderMax:'', // 例如30 音频总时长
sliderProgressValue:0, // 例如11 实时进度
sliderValue:'00:00', // 例如00:30 最大值
currentTimeStr:'00:00', // 例如00:11 音频实时播放进度
innerAudioContext:null, // 实例
state:false // 播放状态 false暂停 true播放
}
},
watch:{//监听用户点击播放的数据变动
presentData: {
handler:function (item) {
// console.log('监听',item)
this.sliderProgressValue=0
this.currentTimeStr='00:00'
// 重置 销毁1
if(this.innerAudioContext){
this.innerAudioContext.destroy()
}
if(item){
this.innerAudioContext= uni.createInnerAudioContext()
this.state=true
this.innerAudioContext.autoplay = true;//设置是否自动播放
this.innerAudioContext.sessionCategory = 'soloAmbient';//在后台时不播放,如有其他播放,会暂停其他播放(但在移动端h5中 后台不播放失效)
this.innerAudioContext.src = item.src//'http://*******/files/download/sound1/206/1638.mp3';//音频的url
this.creatAudio()
}
},
deep:true,//深度监听
}
},
methods:{
// 点击播放事件
playAudio(){
this.state=!this.state
// false暂停 true播放
if(this.state){
this.innerAudioContext.play() //播放
this.creatAudio() //获取播放时长进度
}else{
this.innerAudioContext.pause()//暂停
}
},
//实时播放时长
creatAudio(){
// 播放中的实时监听 播放位置 以及时长
this.innerAudioContext.onTimeUpdate(() => {
const { currentTime,duration} = this.innerAudioContext;//这俩参数是这个api自带的参数, 解构
let currTimeStr = this.formatTime(currentTime);
// 未转化 时间格式的实时时长
this.sliderProgressValue = Math.floor(currentTime);
this.sliderMax = Math.floor(duration);
// 实时变动的时间
this.currentTimeStr = currTimeStr;
//音频总时长
this.sliderValue = this.formatSecond(duration);
// console.log('时长',this.sliderProgressValue,this.currentTimeStr,currentTime,duration)
});
// 监听播放结束 的处理
this.innerAudioContext.onEnded(()=>{
console.log('播放结束')
setTimeout(()=>{
this.currentTimeStr = this.sliderValue;
this.sliderProgressValue=this.sliderMax
this.state=false
},300)
})
},
//格式化时间格式
formatTime(num) {
num = Math.floor(num)
let second = num % 60;
if (second < 10) second = '0' + second;
let min = Math.floor(num / 60);
if (min < 10) min = '0' + min;
return min + ":" + second;
},
// 拖拽音频播放位置
sliderChange(e) {
// console.log('value 发生变化:' + e.detail.value,this.state,this.innerAudioContext)
const currTimeStr = this.formatTime(e.detail.value)
this.currentTimeStr = currTimeStr
// 播放进度条位置
this.sliderProgressValue=e.detail.value
//设置要播放的位置
this.innerAudioContext.seek(e.detail.value);
// this.innerAudioContext.pause()//暂停
// // 因为拖拽后自动播放 导致实时获取播放时间的方法没有执行【坑点】
// setTimeout(()=>{
// //模拟点击播放
// this.state=false
// this.playAudio()
// },1000)
},
formatSecond(seconds) {
var h = Math.floor(seconds / 3600) < 10 ? '0'+Math.floor(seconds / 3600) : Math.floor(seconds / 3600);
var m = Math.floor((seconds / 60 % 60)) < 10 ? '0' + Math.floor((seconds / 60 % 60)) : Math.floor((seconds / 60 % 60));
var s = Math.floor((seconds % 60)) < 10 ? '0' + Math.floor((seconds % 60)) : Math.floor((seconds % 60));
// return h + ":" + m + ":" + s;
return m + ":" + s;
},
// 关闭
close(){
if(this.innerAudioContext){
this.innerAudioContext.destroy()
}
this.sliderMax='' // 例如30 音频总时长
this.sliderProgressValue=0 // 例如11 实时进度
this.sliderValue='00:00' // 例如00:30 最大值
this.currentTimeStr='00:00' // 例如00:11 音频实时播放进度
this.innerAudioContext=null // 实例
this.state=false
this.$emit('AudioDestroy','关闭')
}
},
// 组件销毁 同时销毁音频
destroyed(){
if(this.innerAudioContext){
this.innerAudioContext.destroy()
}
}
}
</script>
<style lang="scss" scoped>
.audio-component{
background-color: #313131 ;
padding: 30rpx 0rpx 0rpx 0rpx;
border-radius: 4px;
// position: fixed;
// width: calc(100% - 60rpx);
// left: 0;
// bottom: 120rpx;
// margin: 0 30rpx;
}
.audio-slider{
display: flex;
align-items: center;
slider{
flex: 1;
margin:6rpx 40rpx 6rpx 20rpx ;
}
.img-box{
width: 80rpx;
// background-color: red;
display: flex;
align-items: center;
justify-content: center;
.laba{
width: 60rpx;
height: 60rpx;
}
}
}
.time-Show{
color: #9A9B9D;
}
.close-box{
width: 35rpx;
height: 35rpx;
margin-right: 25rpx;
image{
width: 35rpx;
height: 35rpx;
}
}
.text-content{
display: flex;
color:#9A9B9D;
justify-content: space-between;
padding: 0 90rpx 0 90rpx;
}
</style>
```·