Files
learning-system-mobile/components/audio-player/audio-player.vue
2023-11-21 17:11:05 +08:00

275 lines
6.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view>
<view class="xaudio">
<view class="xaudio-image">
<image :src="require('./images/music.png')" mode="widthFix"></image>
</view>
<view class="xaudio-title">{{name}}</view>
<view class="xaudio-process">
<view class="xaudio-process-left">{{currentTime}}</view>
<view class="xaudio-process-slider">
<slider
class="audio-slider"
block-size="16"
:value="playDuration"
:max="duration"
@change="sliderChange"
:disabled="allowDrag">
</slider>
</view>
<view class="xaudio-process-right">{{allTime}}</view>
</view>
<view class="xaudio-control">
<!-- 块退15s -->
<image :src="require('./images/prev.png')" class="prevbtn" @click="stepPlay(-15)" mode="widthFix"></image>
<!--播放或暂停-->
<image class="btn-size" v-if="playing" @click="onPlayerPause()" src="../audio-player/images/pausebtn2.png"></image>
<image class="btn-size" v-else @click="onPlayerPlay()" src="../audio-player/images/playbtn2.png"></image>
<!-- 快进15s -->
<image :src="require('./images/next.png')" class="nextbtn" @click="stepPlay(15)" mode="widthFix"></image>
</view>
</view>
</view>
</template>
<script>
export default{
props: {
src: {
type: String,
default:''
},
name:{
type:String,
default:''
},
author:{
type:String,
default:''
},
drag:{ //是否允许拖拽
type: Boolean,
default: true,
},
initialTime: {
//默认播放的位置,第几秒
type: Number,
default: 0,
},
autoplay: {
// 是否自动播放
type: Boolean,
default: false,
},
timeInterval: {
//快进快退间隔
type: Number,
default: 15,
}
},
data(){
return {
audioContext:null,
playing:false,
allowDrag:false,
percentage: 0, // 音频进度百分比
currentTime: '00:00', // 音频当前播放时间
allTime: '00:00', // 音频总播放时间
playDuration:0,// 音频总播放秒数
duration:100,//总的播放时间
audioInterval: null, // 定时器
speed: 1,
muted: false, // 是否默认静音
currVolume: 50, // 当前音量
allowUpdate:true,
checkSecond:-1 //用于检查的秒数
}
},
created() {
},
mounted() {
this.audioContext = uni.createInnerAudioContext();
this.resetPlay();
},
beforeDestroy(){
this.audioContext.destroy();
},
watch:{
src(newVal,oldVal){
if(newVal!=oldVal){
if(newVal!=''){
this.resetPlay();
}
}
}
},
methods:{
resetPlay(){
//console.log('重新执行');
let $this=this;
this.allowDrag=!this.drag;
this.audioContext.autoplay = this.autoplay;
this.audioContext.src = this.src;
this.audioContext.onTimeUpdate(()=>{
$this.onPlayerPlaying();
});
this.audioContext.onCanplay(()=>{
//console.log('可以播放了');
$this.duration=$this.audioContext.duration;
//$this.currentTime=$this.formatSeconds(0);
$this.allTime=$this.formatSeconds($this.duration);
});
this.audioContext.onError((res) => {
console.log(res.errMsg);
console.log(res.errCode);
});
this.playing=false;
this.audioContext.seek(0);
//this.onPlayerPlay();
},
stepPlay(t){
this.allowUpdate=false;
let current=this.audioContext.currentTime;
let newTime=current+t;
this.audioContext.seek(newTime);
this.allowUpdate=true;
},
sliderChanging(e) {
//拖拽过程中,不允许更新进度条
//this.updateState= false;
this.allowUpdate=false;
this.audioContext.pause();
this.playing=false;
},
// 拖动slider完成后触发
sliderChange(e) {
//console.log(e,'e');
let second=e.detail.value;
this.audioContext.seek(second);
this.allowUpdate=true;
this.audioContext.play();
this.playing=true;
this.currentTime=this.formatSeconds(second);
// 重新计时
this.$emit("onPlay",this.audioContext);
},
onPlayerPlay(){
//console.log('开始播放');
this.allowUpdate=true;
//console.log(this.audioContext.duration,'this.audioContext.duration');
this.audioContext.play();
this.checkSecond=-1;//重置检查的秒数
this.playing=true;
this.$emit("onPlay",this.audioContext);
},
onPlayerPause(){
//console.log('暂停播放');
this.audioContext.pause();
this.playing=false;
this.$emit("onPause",this.audioContext);
},
onPlayerPlaying(){
//let total=this.audioContext.duration;
if(this.allowUpdate){
let current=this.audioContext.currentTime;
//this.playDuration=current*100/total;
this.playDuration=current;
//console.log(this.playDuration,'this.playDuration');
this.currentTime=this.formatSeconds(current);
//以下修改为1秒调用一次减少调用次数
let intTime=parseInt(current);
if(intTime>this.checkSecond){
this.checkSecond=intTime;
this.$emit("onPlaying",this.audioContext,intTime);
}
// 相等的时候,关闭计时
if(this.currentTime == this.allTime){
//图标变换
this.onPlayerEnded()
}
}
},
onPlayerEnded(){
//console.log('结束播放');
this.audioContext.stop();
this.playing=false;
//let intTime=parseInt(e.detail.currentTime);
this.$emit("onEnded",this.audioContext);
},
formatSeconds(a) {
var hh = parseInt(a/3600);
var mm = parseInt((a-hh*3600)/60);
if(mm<10) mm = "0" + mm;
var ss = parseInt((a-hh*3600)%60);
if(ss<10) ss = "0" + ss;
if(hh<10) hh = hh == 0?'':`0${hh}:`;
var length = hh + mm + ":" + ss;
if(a>=0){
return length;
}else{
return "00:00";
}
},
}
}
</script>
<style lang="scss" scoped>
.prevbtn,
.nextbtn {
width: 50rpx;
height: 50rpx;
}
.xaudio{
.xaudio-image{
text-align: center;
image{
width: 260rpx;
height: 260rpx;
}
}
.xaudio-title{
padding: 0 40upx;
font-weight: bold;
font-size: 34rpx;
margin-top: 50rpx;
text-align: center;
word-break:break-all;
}
.btn-size{
width: 100rpx;
height: 100rpx;
}
.xaudio-process{
display: flex;
align-items: center;
width: 90%;
margin: 0 auto;
.xaudio-process-left{
font-size: 24upx;
line-height: 1;
}
.xaudio-process-slider{
flex: 1;
}
.xaudio-process-right{
font-size: 24upx;
line-height: 1;
color: #333;
}
}
.xaudio-control{
display: flex;
align-items: center;
margin: 40rpx auto 0;
justify-content: space-around;
height: 100rpx
}
}
</style>