template 代码
<view class="player">
<view class="progress">
<view class="current-time">{{ slider_time }}</view>
<view class="slider"><slider :value="slider_index" :max="song_time" activeColor="#0190ff" backgroundColor="#dddddd" block-color="#0190ff" block-size="12" /></view>
<view class="max-time">{{ slider_maxTime }}</view>
</view>
<view class="control">
<view class="col">
<view class="previous-btn" @click="changePrevious()"><view class="icon-previous"></view></view>
</view>
<view class="col">
<view class="outer" v-if="song_loading"></view>
<view class="inner" v-if="song_loading"></view>
<view class="play-btn" v-else @click="changePlayState()"><view :class="[song_playState ? 'icon-pause' : 'icon-play']"></view></view>
</view>
<view class="col">
<view class="next-btn" @click="changeNext()"><view class="icon-next"></view></view>
</view>
</view>
</view>
script 代码
var innerAudioContext;
export default {
data() {
return {
musicList: [
{ song: '扬州三月', url: 'https://static.cdn.ejcms.com/1.mp3' },
{ song: 'The Right Path', url: 'https://static.cdn.ejcms.com/2.mp3' },
{ song: '故乡的原风景', url: 'https://static.cdn.ejcms.com/3.mp3' },
{ song: '夏夜', url: 'https://static.cdn.ejcms.com/4.mp3' },
{ song: 'Going Home', url: 'https://static.cdn.ejcms.com/5.mp3' }
],
song_index: 0,
song_url: '',
song_loading: false,
song_playState: false,
song_time: 0,
slider_index: 0,
slider_time: '',
slider_maxTime: ''
};
},
onLoad() {
this.playAudio(this.musicList[0]);
},
methods: {
initPlay() {
let _this = this;
// 销毁当前实例
if (innerAudioContext) {
innerAudioContext.destroy();
}
// 创建音频
innerAudioContext = uni.createInnerAudioContext();
// 音频的数据链接,用于直接播放。
innerAudioContext.src = _this.song_url;
// 开始播放的位置(单位:s),默认 0
innerAudioContext.startTime = 0;
// 是否自动开始播放,默认 false
innerAudioContext.autoplay = true;
// 音频进入可以播放状态,但不保证后面可以流畅播放
innerAudioContext.onCanplay(res => {
_this.song_loading = false;
});
// 音频播放事件
innerAudioContext.onPlay(() => {
_this.song_playState = true;
});
// 音频暂停事件
innerAudioContext.onPause(() => {
_this.song_playState = false;
});
// 音频停止事件
innerAudioContext.onStop(res => {
innerAudioContext.destroy();
// console.log(res);
});
// 音频自然播放结束事件
innerAudioContext.onEnded(res => {
innerAudioContext.destroy();
_this.song_playState = false;
_this.changeNext();
});
// 音频播放进度更新事件
innerAudioContext.onTimeUpdate(() => {
let { currentTime, duration } = innerAudioContext;
_this.slider_index = currentTime;
_this.song_time = duration;
_this.slider_time = _this.formatTime(currentTime);
_this.slider_maxTime = _this.formatTime(duration);
});
// 音频播放错误事件
innerAudioContext.onError(res => {
_this.song_playState = false;
console.log('onError', res);
});
// 音频加载中事件,当音频因为数据不足,需要停下来加载时会触发
innerAudioContext.onWaiting(res => {
_this.song_loading = true;
});
},
// 上一曲
changePrevious() {
if (this.song_index > 0) {
this.song_index--;
} else {
this.song_index = 0;
}
this.playAudio(this.musicList[this.song_index]);
},
// 播放状态
changePlayState() {
if (this.song_playState) {
innerAudioContext.pause();
} else {
innerAudioContext.play();
}
},
// 下一曲
changeNext() {
if (this.musicList.length > this.song_index + 1) {
this.song_index++;
} else {
this.song_index = 0;
}
this.playAudio(this.musicList[this.song_index]);
},
playAudio(data) {
this.slider_index = 0;
this.song_url = data.url;
this.initPlay();
},
formatTime(num) {
num = num.toFixed(0);
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;
}
}
};
style 代码
uni-app,
page {
background-image: linear-gradient(35deg, #b6e8fc, #ecccfb, #b6e8fc);
}
.player {
margin-top: calc(100vh - 150px);
width: 100%;
height: 150px;
background-image: linear-gradient(150deg, #e7f5ff, #ffffff, #f1eeff);
border-top-right-radius: 30px;
border-top-left-radius: 30px;
position: relative;
.progress {
height: 50px;
display: flex;
justify-content: space-between;
align-items: center;
.current-time {
width: 60px;
text-align: right;
color: #898989;
}
.slider {
width: calc(100% - 120px);
}
.max-time {
width: 60px;
text-align: left;
color: #898989;
}
}
.control {
margin: 0 auto;
width: 80%;
height: 80px;
.col {
float: left;
position: relative;
display: block;
box-sizing: border-box;
width: 33.3333336%;
height: 100px;
line-height: 100px;
display: flex;
justify-content: center;
.outer {
border: 5px solid rgba(0, 148, 255, 0.9);
opacity: 0.9;
width: 68px;
height: 68px;
border-top-color: transparent;
border-bottom-color: transparent;
border-radius: 50%;
animation: spinRight 0.5s linear infinite normal;
animation-delay: 0;
margin: 0 auto;
}
.inner {
border: 5px solid rgba(0, 148, 255, 0.9);
opacity: 0.9;
width: 38px;
height: 38px;
border-left-color: transparent;
border-bottom-color: transparent;
border-radius: 50%;
animation: spinLeft 0.5s linear infinite normal;
animation-delay: 0;
margin: 0 auto;
top: -63px;
display: block;
position: relative;
}
.play-btn,
.previous-btn,
.next-btn {
width: 68px;
height: 68px;
line-height: 68px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.play-btn {
background-color: #0190ff;
}
}
}
}
.icon-play {
width: 26px;
height: 26px;
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNjY5ODE5MzUxMDA4IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjIzNDciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjYiIGhlaWdodD0iMjYiPjxwYXRoIGQ9Ik01NS4zNjk1MjMxNCA2OC4wNTM3MDM0NWMwLTU2LjE2NTU0ODY3IDM5LjYyNTM3ODQ2LTc5LjI3NjEyNDg1IDg4LjIwNTc4NzEyLTUxLjgwMjE5MTE4bDc4OC41NzU0NjU1NSA0NDUuODc0MjkyN2M0OC43MDcyNTA4NyAyNy41NTAwMzg3NiA0OC41ODA0MDg2NiA3Mi4yOTk4MjU1MiAwIDk5Ljc0ODM5MDA2TDE0My41NzUzMTAyNiAxMDA3Ljc0ODQ4NzczQzk0Ljg2ODA1OTM5IDEwMzUuMjk4NTI2NDcgNTUuMzY5NTIzMTQgMTAxMi4xMTE4NDUxOSA1NS4zNjk1MjMxNCA5NTUuOTQ2Mjk2NTV2LTg4Ny44OTI1OTMxeiIgZmlsbD0iI0ZGRkZGRiIgcC1pZD0iMjM0OCI+PC9wYXRoPjwvc3ZnPg==');
}
.icon-pause {
width: 26px;
height: 26px;
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNjY5ODE5Mzk3NDY2IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjI4MDkiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjYiIGhlaWdodD0iMjYiPjxwYXRoIGQ9Ik0zOTUuNTM5MjA1OCA5NzUuODI0ODIyMjljMCAyMy4yODIyOTM4OC0xOS4wNDg3NDIzOCA0Mi4zMzEwMzYyNi00Mi4zMzEwMzYzIDQyLjMzMTAzNjI1TDE4Ni45NjYyMzA3IDEwMTguMTU1ODU4NTRjLTIzLjI4MjI5Mzg4IDAtNDIuMzMxMDM2MjYtMTkuMDQ4NzQyMzgtNDIuMzMxMDM2MjctNDIuMzMxMDM2MjVsMC05MzMuMTEzNTk3MDhjMC0yMy4yODIyOTM4OCAxOS4wNDg3NDIzOC00Mi4zMzEwMzYyNiA0Mi4zMzEwMzYyNy00Mi4zMzEwMzYyMmwxNjYuMjQxOTM4OCAwYzIzLjI4MjI5Mzg4IDAgNDIuMzMxMDM2MjYgMTkuMDQ4NzQyMzggNDIuMzMxMDM2MyA0Mi4zMzEwMzYyMkwzOTUuNTM5MjA1OCA5NzUuODI0ODIyMjl6IiBmaWxsPSIjRkZGRkZGIiBwLWlkPSIyODEwIj48L3BhdGg+PHBhdGggZD0iTTg3OS40MjI5NTIzOSA5NzUuODI0ODIyMjljMCAyMy4yODIyOTM4OC0xOS4wNDg3NDIzOCA0Mi4zMzEwMzYyNi00Mi4zMzEwMzYyNiA0Mi4zMzEwMzYyNWwtMTY2LjI0MTkzODgzIDBjLTIzLjI4MjI5Mzg4IDAtNDIuMzMxMDM2MjYtMTkuMDQ4NzQyMzgtNDIuMzMxMDM2MjUtNDIuMzMxMDM2MjVsMC05MzMuMTEzNTk3MDhjMC0yMy4yODIyOTM4OCAxOS4wNDg3NDIzOC00Mi4zMzEwMzYyNiA0Mi4zMzEwMzYyNS00Mi4zMzEwMzYyMmwxNjYuMjQxOTM4ODMgMGMyMy4yODIyOTM4OCAwIDQyLjMzMTAzNjI2IDE5LjA0ODc0MjM4IDQyLjMzMTAzNjI2IDQyLjMzMTAzNjIyTDg3OS40MjI5NTIzOSA5NzUuODI0ODIyMjl6IiBmaWxsPSIjRkZGRkZGIiBwLWlkPSIyODExIj48L3BhdGg+PC9zdmc+');
}
.icon-previous {
width: 22px;
height: 22px;
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNjY5ODE5Mzg5NjI4IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjI1MDEiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjIiIGhlaWdodD0iMjIiPjxwYXRoIGQ9Ik0yODYuNTUxNzY1NzYgNTEybDY3MC4xNzAxMDE3Ni01MDAuNDQzODc1OTV2MTAwMC43MzcxNTE5MUwyODYuNTUxNzY1NzYgNTEyek02Ny4yNzgxMzI0OCAxMS41NTYxMjQwNWgxMjAuNDgwMDE4MzF2MTAwMC43MzcxNTE5MWgtMTIwLjQ4MDAxODMxVjExLjU1NjEyNDA1eiIgZmlsbD0iIiBwLWlkPSIyNTAyIj48L3BhdGg+PC9zdmc+');
}
.icon-next {
width: 22px;
height: 22px;
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNjY5ODE5MzkzNjAzIiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjI2NTUiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjIiIGhlaWdodD0iMjIiPjxwYXRoIGQ9Ik02Ny4yNzgxMzI0OCAxMDEyLjQ0Mzg3NTk1VjExLjU1NjEyNDA1bDY3MC4xNzAxMDE3NiA1MDAuNDQzODc1OTUtNjcwLjE3MDEwMTc2IDUwMC40NDM4NzU5NXogbTg4OS40NDM3MzUwNCAwaC0xMjAuNDgwMDE4MzFWMTEuNTU2MTI0MDVoMTIwLjQ4MDAxODMxdjEwMDAuODg3NzUxOXoiIGZpbGw9IiIgcC1pZD0iMjY1NiI+PC9wYXRoPjwvc3ZnPg==');
}
Tenglin (作者)
没有,最后放弃了
2024-12-02 10:03