<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">
<meta content="yes" name="apple-mobile-web-app-capable">
<meta content="black" name="apple-mobile-web-app-status-bar-style">
<meta content="telephone=no" name="format-detection">
<title>小刘的播放器</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.8"></script>
<style>
* {
padding: 0;
margin: 0;
}
ul, li {
list-style: none;
}
.bg_player {
width: 100vw;
height: 100vh;
background-image: url(https://y.qq.com/music/photo_new/T002R300x300M000003xRf4B1fqaZX.jpg?max_age=2592000);
background-color: rgb(255, 255, 255);
background-repeat: no-repeat;
background-size: cover;
background-position: 50%;
filter: blur(65px);
opacity: .6;
transform: translateZ(0);
}
#audio {
width: 70%;
height: 50px;
text-align: center;
}
#audio-list {
font-size: 15px;
position: absolute;
top: 20px;
left: 16px;
}
#audio-list li {
color: hsl(0deg 3% 40% / 80%);
height: 50px;
line-height: 50px;
}
#audio-list li:hover {
color: #fff;
}
input[type="checkbox"] {
width: 20px;
height: 20px;
}
.list_menu__icon {
display: inline-block;
width: 36px;
height: 36px;
margin-right: 8px;
vertical-align: middle;
background-image: url(https://y.qq.com/ryqq/static/media/icon_list_menu.08951c0e.png?max_age=2592000);
background-repeat: no-repeat;
}
.list_menu__icon_play {
background-position: -120px 0;
}
.list_menu__icon_pause {
background-position: -120px -200px;
}
.bottom-area {
display: flex;
align-items: center;
justify-content: space-evenly;
position: absolute;
bottom: 20px;
width: 100%;
}
button {
width: 55px;
height: 35px;
}
.musidLyric{
position: absolute;
bottom: 75px;
left: 16px;
}
.musidLyric.all{
background:rgba(255,255,255,0.5);
width:100%;
position: absolute;
top: 0;
left: 0;
bottom: 0;
padding-left: 32px;
padding-top: 32px;
}
.now-audio {
position: absolute;
bottom:95px;
left: 16px;
color: hsl(0deg 3% 40% / 80%);
width: 100%;
}
.musidLyric p.active{
color:#fff;
font-size:16px;
}
.look-more{
position: absolute;
bottom:0px;
right: 32px;
}
</style>
</head>
<body>
<div id="root">
<div class="bg_player"></div>
<ul id="audio-list">
<li v-for="(item,index) in audiolist" :key="index">
<i class="list_menu__icon list_menu__icon_pause" @click="pause(item)"
v-if="checkKey==item.index&&type=='play'"></i>
<i class="list_menu__icon list_menu__icon_play" @click="play(item)" v-else></i>
<span>{{item.title}}</span>
</li>
</ul>
<div class="Lyric-area">
<div class="musidLyric" ref="musidLyric" :class="{'all':islookMore}">
<template v-for="item in lyric" :key="item">
<p :class="{ active: currenTime >= item.time && currenTime < item.pre }" v-if="!islookMore?(currenTime >= item.time && currenTime < item.pre):true">
<!-- //只显示当前唱的这句话-->
{{ item.lrc }}
</p>
</template>
</div>
<div v-if="checkKey>-1" class="now-audio">
当前播放:{{audiolist[checkKey].title}}
<span v-if="lyric.length>0" class="look-more" @click="lookMore()">
<template v-if="!islookMore">全部歌词 ?</template>
<template v-else>收起 ? </template>
</span>
</div>
</div>
<div class="bottom-area">
<button type="button" @click="pre()">上一首</button>
<audio id="audio"
ref="audio"
controls="true"
preload='metadata'
:src="aduioSrc"
@timeupdate="updateTime"
controls="controls">
Your browser does not support the audio tag.
</audio>
<button type="button" @click="next()">下一首</button>
</div>
</div>
<script type="text/javascript">
// 创建一个Vue对象
const app = new Vue({
el: "#root",
// 定义vue中的数据
data() {
return {
audio: '',
checkKey: -1,//播放的音乐的下标
type: 'play',//当前是播放还是暂停
lyric:[],//歌词
currenTime:0,
islookMore:false,
aduioSrc: "http://dl.stream.qqmusic.qq.com/RS02060mot3x2EQDlw.mp3?guid=8778707332&vkey=72DA3FAD7C00A9A2B298A69264AF69C2E3D233CE75195A10C308D67AF20C024A309F1C4A87C851036E45768484D1173AF85AE46115AD7AA5&uin=&fromtag=120052",
audiolist: [{
index: 0,
title: '海绵宝宝',
src: 'http://dl.stream.qqmusic.qq.com/RS02060mot3x2EQDlw.mp3?guid=8778707332&vkey=72DA3FAD7C00A9A2B298A69264AF69C2E3D233CE75195A10C308D67AF20C024A309F1C4A87C851036E45768484D1173AF85AE46115AD7AA5&uin=&fromtag=120052',
lyric: '[00:00.00]海绵宝宝\n' +
'[00:02.00]\n' +
'[00:03.00]词曲:小小苏\n' +
'[00:05.00]编曲:上官芳\n' +
'[00:07.00]演唱:回音哥\n' +
'[00:09.00]\n' +
'[00:10.00]歌词制作:咱会宠你\n' +
'[00:12.00]QQ:1505339352\n' +
'[00:14.00]\n' +
'[00:14.64]我喜欢你冷冷态度\n' +
'[00:16.92]面对我的小招数\n' +
'[00:19.05]喜欢你说话语速\n' +
'[00:20.99]陪你逛街买衣服\n' +
'[00:23.03]我喜欢你的小糊涂\n' +
'[00:25.29]想要牵你过马路\n' +
'[00:27.32]不用走太多地图\n' +
'[00:29.36]下一站就叫幸福\n' +
'[00:32.19]眼睛瞪大在装无辜\n' +
'[00:34.50]原来最后于事无补\n' +
'[00:36.61]不知你卖什么葫芦心里没数\n' +
'[00:40.68]追你的竞争太残酷\n' +
'[00:42.90]都猜你心里的温度\n' +
'[00:44.97]你收的礼物都装满了一仓库\n' +
'[00:48.76]妈妈说有机会要紧握\n' +
'[00:52.60]我不会让你轻易挣脱\n' +
'[00:56.68]平时太沉默 这次要突破\n' +
'[01:00.54]快使出海绵宝宝的幽默\n' +
'[01:04.15]'
}, {
index: 1,
title: '奔向你',
src: 'http://dl.stream.qqmusic.qq.com/C4000011hoaf4Hxccg.m4a?guid=1497395988&vkey=EB2E4C818A4EAE364B5D337D042E841259DAB2F5F13FAAC5105B5C3F6BB4D0166E5ACD5E0E251AE80163D7070ED70F66F4CF0D05B8B6077C&uin=&fromtag=120032',
lyric: ''
}]
}
},
mounted() {
},
methods: {
updateTime(e){
this.currenTime=parseInt(e.timeStamp);
console.log(this.currenTime)
},
// 播放
play(item) {
if (this.$refs.audio.src != item.src) {//如果不加这个判断会导致src重置。播放的时间也从头开始而不是上次暂停的地方开始
this.$refs.audio.src = item.src;
}
this.checkKey = item.index;
this.type = 'play';
this.lyric=this.parseLyric(item.lyric);
this.$refs.audio.play();
},
// 暂停
pause() {
this.type = 'pause';
this.$refs.audio.pause();
},
// 上一首
pre() {
if (this.checkKey <= 0) {
this.checkKey = this.audiolist.length - 1
} else {
this.checkKey = this.checkKey - 1;
}
this.$refs.audio.src = this.audiolist[this.checkKey].src;
this.lyric=this.parseLyric(this.audiolist[this.checkKey].lyric);
this.type = 'play';
this.$refs.audio.play();
},
// 下一首
next() {
if (this.checkKey == this.audiolist.length - 1) {
this.checkKey = 0
} else {
this.checkKey = this.checkKey + 1;
}
this.$refs.audio.src = this.audiolist[this.checkKey].src;
this.lyric=this.parseLyric(this.audiolist[this.checkKey].lyric);
this.type = 'play';
this.$refs.audio.play();
},
//获取歌词
parseLyric(text) {
if (text) { //判断有没有歌词,因为有些音乐没有歌词
arr = text.split(/[(\f\n)\r\t\v]/).map((item, i) => { //用正则的换行符分割
let min = item.slice(1, 3);
let sec = item.slice(4, 6);
let mill = item.slice(7, 10);
let lrc = item.slice(11, item.length)
let time = parseInt(min) * 60 * 1000 + parseInt(sec) * 1000 + parseInt(mill) //把分钟变成秒,秒变成毫秒
if (isNaN(Number(mill))) { //判断是不是数字 不是的话进行二次分割 有些还是这种格式的 53]
mill = item.slice(7, 9);
lrc = item.slice(10, item.length)
time = parseInt(min) * 60 * 1000 + parseInt(sec) * 1000 + parseInt(mill) //把分钟变成秒,秒变成毫秒
}
return { min, sec, mill, lrc, time }
})
arr.forEach((item, i) => { //歌词到了最后一句的处理
if (i === arr.length - 1 || isNaN(arr[i + 1].time)) {
item.pre = 100000
} else { //没到最后一句 那么久等于下一句歌词的时间
item.pre = arr[i + 1].time
}
});
console.log(arr);
return arr
}
},
//查看所有的歌词
lookMore(){
this.islookMore=!this.islookMore;
},
}
})
</script>
</body>
</html>