vue仿網(wǎng)易云音樂播放器界面的簡單實現(xiàn)過程
由于工作項目的需要,需要使用到歌曲播放,參考多方資料,寫了一個仿網(wǎng)易云音樂播放界面,能完整的實現(xiàn)音樂播放功能。


前端簡單的使用vue組件和audio標簽實現(xiàn)了播放器界面,后端則是調(diào)用網(wǎng)易云的API獲取對應的歌曲信息。

?廢話不多說上代碼
歌曲播放界面(musicPlay.vue)
<template>
<div class="main-page">
<audio :src="songInfo.url" id="music" autoplay="autoplay"></audio>
<div
class="background-flitter"
:style="`background-image: url(${songInfo.cover})`"
></div>
<div class="play-mini">
<div class="progress-bar" @click="handleProgressClick" ref="track">
<div
class="progress-box"
:style="{ width: audioProgressPercent }"
></div>
</div>
<div class="songInfo">
<img class="poster" :src="songInfo.cover" alt="" />
<!-- 歌名、歌手名 -->
<div class="info">
<p style="font-weight: 600; color: #fff;">{{ songInfo.name }}</p>
<p style="font-size: 14px; color: #fff">{{ songInfo.artistsName }}</p>
</div>
</div>
<div class="controls">
<!-- 上一首提示 -->
<Tooltip content="上一首" theme="light" :delay="1500">
<a href="javascript:;">
<Icon
type="md-skip-backward"
@click="skipBack"
size="26"
color="white"
/>
</a>
</Tooltip>
<!-- 播放暫停 -->
<Tooltip content="播放暫停" theme="light" :delay="1500">
<img
@click="playMusic"
class="status"
v-show="!playing"
src="@/assets/play_icon.png"
alt=""
/>
<img
class="status"
@click="playMusic"
v-show="playing"
src="@/assets/play-02.png"
alt=""
/>
</Tooltip>
<!-- 下一首提示 -->
<Tooltip content="下一首" theme="light" :delay="1500">
<a href="javascript:;">
<Icon
type="md-skip-forward"
@click="skipForward"
size="26"
color="white"
/>
</a>
</Tooltip>
</div>
<div class="right-botton">
<div class="text-div"></div>
<!-- 音量 -->
<a href="javascript:;">
<Icon
:type="volumeType"
size="26"
color="white"
@click="volumeChange"
/>
</a>
<div class="text-div"></div>
<Slider
style="width: 80px; z-index: 99999"
@on-input="changeVolum"
v-model="volume"
></Slider>
<div class="text-div"></div>
<div class="text-div"></div>
<div class="text-div"></div>
<!-- 歌曲播放類型 -->
<Tooltip :content="showPlayType" theme="light" :delay="1500">
<a href="javascript:;">
<Icon
:custom="playStatus"
@click="playTypeChange"
size="26"
color="white"
/>
</a>
</Tooltip>
<div class="text-div"></div>
<div class="text-div"></div>
<div class="playlist">
<!-- 播放列表 -->
<Tooltip content="列表" theme="light" :delay="1500">
<a href="javascript:;">
<Icon
custom="iconfont icon-bofangqi-xuanji"
@click="drawer = true"
size="36"
color="white"
/>
</a>
</Tooltip>
</div>
</div>
</div>
<div class="song-cover-lyric">
<div class="disc-continer">
<div class="poster" ref="rotate">
<img :src="songInfo.cover" alt="" />
</div>
<div class="song-name">{{ songInfo.name }}</div>
<div class="song-artistsName">{{ songInfo.artistsName }}</div>
</div>
<div class="lyric">
<mscroll
ref="lyric"
:color="color"
:colorLight="colorLight"
:lineHeight="lineHeight"
:paddingTop="paddingTop"
:fontSize="fontSize"
:lyricIndex="lyricIndex"
:lyricsList="lyricInfo"
></mscroll>
</div>
</div>
<Drawer
title="播放列表"
placement="left"
width="320"
:closable="false"
v-model="drawer"
>
<div class="list-container">
<div
class="songInfo"
v-for="(item, index) in songList"
:key="index"
@click="PlayListMusic(index)"
>
<img :src="item.cover" alt="" />
<div class="info">
<div class="name">{{ item.name }}</div>
<div class="singer">{{ item.artistsName }}</div>
</div>
</div>
</div>
</Drawer>
</div>
</template>
<script>
import { showMessage } from "../../publicMethod/publicMethods";
import Mscroll from "./lyricScroll.vue";
import commonJs from "../../utils/timeConversion";
import axios from "axios";
export default {
data() {
return {
volumeNum: 80, //暫存的音量
volumeStatus: true, //音量圖標的變化
volumeType: "md-volume-up", //音量圖標
playStatus: "iconfont icon-xunhuanbofang", //播放類型圖標
playing: false,
drawer: false,
playIndex: 0,
songInfo: {},
songList: [],
volume: 80, // 音量
lyricInfo: [],
playType: 1, // 播放類型:1-列表循環(huán),2-隨機播放,3-單曲循環(huán)
showPlayType: "列表循環(huán)",
audioProgress: 0,
thumbTranslateX: 0,
lyricIndex: 0,
color: "#fff", //歌詞默認顏色
colorLight: "#40ce8f", //歌詞高亮色
fontSize: "16px", //歌詞字體大小
lineHeight: "42", //每段行高
paddingTop: "300px", //高亮歌詞部分居中
};
},
created() {},
components: {
Mscroll,
},
computed: {
audioProgressPercent() {
return `${this.audioProgress * 100}%`;
},
},
mounted() {
const music = document.getElementById("music");
if (this.$route.query.play) {
this.ClickPlay();
} else {
this.GetSongList();
}
if (this.playing) {
// 播放中,點擊則為暫停
this.playing = false;
this.$refs.rotate.style.animationPlayState = "paused";
music.pause();
} else {
// 暫停中,點擊則為播放
this.playing = true;
this.$refs.rotate.style.animationPlayState = "running";
music.play();
}
},
methods: {
//音量變化
volumeChange() {
if (this.volumeStatus) {
this.volumeStatus = false;
this.volumeNum = this.volume;
this.volume = 0;
this.volumeType = "md-volume-off";
} else {
this.volumeStatus = true;
this.volume = this.volumeNum;
this.volumeType = "md-volume-up";
}
},
//歌曲播放類型變化
playTypeChange() {
if (this.playType == 1) {
this.playType = 2;
this.showPlayType = "隨機播放";
this.playStatus = "iconfont icon-suijibofang";
return;
}
if (this.playType == 2) {
this.playType = 3;
this.showPlayType = "單曲循環(huán)";
this.playStatus = "iconfont icon-danquxunhuan";
return;
}
if (this.playType == 3) {
this.playType = 1;
this.showPlayType = "列表循環(huán)";
this.playStatus = "iconfont icon-xunhuanbofang";
return;
}
},
ClickPlay() {
this.audioInit();
this.getMusicList(this.songInfo.id);
this.$refs.rotate.style.animationPlayState = "running";
this.playing = true;
setTimeout(() => {
music.play();
}, 100);
},
GetSongList() {
axios.get("/musicController/getMusicList").then(this.GetSongListInfo);
},
GetSongListInfo(res) {
let myList;
if (res.code == "0000") {
myList = res.data;
} else {
console.log("沒查到數(shù)據(jù)");
myList = [
{
artistsName: "房東的貓",
cover:
"https://p3.music.126.net/KkrcSwKbRsd8GuaOHILlxA==/109951166077317301.jpg",
id: 1857630559,
name: "New Boy",
url: "https://music.163.com/song/media/outer/url?id=1857630559.mp3",
lyric:
"\n[00:25.075]\n[00:25.189]是的我看見到處是陽光\n[00:29.156]快樂在城市上空飄揚\n[00:32.773]新世界來得像夢一樣\n[00:36.689]讓我暖洋洋\n[00:40.122]你的老懷表還在轉(zhuǎn)嗎\n[00:43.822]你的舊皮鞋還能穿嗎\n[00:47.506]這兒有一支未來牌香煙\n[00:51.479]你不想嘗嘗嗎\n[00:54.512]明天一早 我猜陽光會好\n[01:02.679]我要把自己打掃\n[01:05.896]把破舊的全部賣掉\n[01:09.212]哦這樣多好 快來吧奔騰電腦\n[01:17.329]就讓它們代替我來思考\n[01:27.229]穿新衣吧 剪新發(fā)型呀\n[01:31.347]輕松一下Windows98\n[01:35.048]打扮漂亮 18歲是天堂\n[01:39.064]我們的生活甜得像糖\n[01:42.431]穿新衣吧 剪新發(fā)型呀\n[01:46.098]輕松一下Windows98\n[01:49.914]以后的路不再會有痛苦\n[01:53.948]我們的未來該有多酷\n[02:12.481]是的我看見到處是陽光\n[02:16.164]快樂在城市上空飄揚\n[02:19.847]新世界來的像夢一樣\n[02:23.748]讓我暖洋洋\n[02:27.164]你的老懷表還在轉(zhuǎn)嗎\n[02:30.815]你的舊皮鞋還能穿嗎\n[02:34.614]這兒有一支未來牌香煙\n[02:38.448]你不想嘗嘗嗎\n[02:41.548]明天一早我猜陽光會好\n[02:49.898]我要把自己打掃\n[02:53.564]把破舊的全部賣掉\n[02:56.198]哦這樣多好 快來吧奔騰電腦\n[03:04.598]就讓它們代替我來思考\n[03:11.081]\n[03:11.414]穿新衣吧剪新發(fā)型呀\n[03:14.698]輕松一下Windows98\n[03:18.264]打扮漂亮18歲是天堂\n[03:22.481]我們的生活甜得像糖\n[03:25.964]穿新衣吧剪新發(fā)型呀\n[03:29.515]輕松一下Windows98\n[03:33.264]以后的路不再會有痛苦\n[03:37.681]我們的未來該有多酷",
},
];
}
this.songList = myList;
this.songInfo = this.songList[0];
this.getMusicList(this.songInfo.id); //通過正在播放的歌曲id獲取歌曲播放的URL歌詞信息
this.audioInit();
},
audioInit() {
let that = this;
let progressL = this.$refs.track.offsetWidth; // 進度條總長
music.addEventListener("timeupdate", () => {
// 當前播放時間
let compareTime = music.currentTime;
for (let i = 0; i < that.lyricInfo.length; i++) {
if (compareTime > parseInt(that.lyricInfo[i].time)) {
const index = that.lyricInfo[i].index;
if (i === parseInt(index)) {
that.lyricIndex = i;
}
}
}
that.currentTime = commonJs.TimeToString(music.currentTime);
that.audioProgress = music.currentTime / music.duration;
that.thumbTranslateX = (that.audioProgress * progressL).toFixed(3);
});
music.addEventListener("ended", () => {
switch (parseInt(that.playType)) {
case 1: // 列表循環(huán)
that.playIndex =
that.playIndex + 1 >= that.songList.length
? 0
: that.playIndex + 1;
break;
case 2: // 隨機播放
that.playIndex = Math.floor(Math.random() * that.songList.length);
break;
case 3: // 單曲循環(huán)
break;
}
that.songInfo = that.songList[that.playIndex];
this.getMusicList(that.songInfo.id);
setTimeout(() => {
this.$refs.rotate.style.animationPlayState = "running";
music.play();
}, 200);
});
},
//播放與暫停
playMusic() {
if (this.playing) {
// 播放中,點擊則為暫停
this.playing = false;
this.$refs.rotate.style.animationPlayState = "paused";
music.pause();
} else {
// 暫停中,點擊則為播放
this.playing = true;
this.$refs.rotate.style.animationPlayState = "running";
music.play();
}
},
PlayListMusic(index) {
this.playIndex = index;
this.songInfo = this.songList[this.playIndex];
this.getMusicList(this.songInfo.id);
this.playing = true;
this.drawer = false;
setTimeout(() => {
this.$refs.rotate.style.animationPlayState = "running";
music.play();
}, 200);
},
//點擊進度條
handleProgressClick(event) {
let progressL = this.$refs.track.offsetWidth; // 進度條總長
let clickX = event.offsetX;
let time = (clickX / progressL).toFixed(2);
this.setProgress(time);
},
setProgress(x) {
music.currentTime = music.duration * x;
},
// 上一首
skipBack() {
this.skipFn("skipBack");
},
// 下一首
skipForward() {
this.skipFn("skipForward");
},
//上下首封裝
skipFn(type) {
switch (parseInt(this.playType)) {
case 2: // 隨機播放
this.playIndex = Math.floor(Math.random() * this.songList.length);
break;
default:
if (type == "skipBack") {
this.playIndex - 1 >= 0 ? this.playIndex-- : 0;
} else {
this.playIndex =
this.playIndex + 1 >= this.songList.length
? this.songList.length - 1
: this.playIndex + 1;
}
break;
}
this.songInfo = this.songList[this.playIndex];
this.getMusicList(this.songInfo.id);
this.playing = true;
setTimeout(() => {
this.$refs.rotate.style.animationPlayState = "running";
music.play();
}, 200);
},
//調(diào)節(jié)音量
changeVolum(c) {
music.volume = c / 100;
if (music.volume == 0) {
this.volumeType = "md-volume-off";
} else {
this.volumeType = "md-volume-up";
}
},
//獲取歌曲播放的URL信息
getMusicList(id) {
let that = this;
axios.get("/musicController/getMusicURLInfo/" + id).then(function (res) {
switch (res.code) {
case "0000":
that.songInfo.url = res.data.url;
that.GetLyricList(res.data.lyric);
break;
case "1111":
showMessage("warning", res.message);
break;
}
});
},
GetLyricList(lrc) {
let lyricsObjArr = [];
const regNewLine = /\n/;
const lineArr = lrc.split(regNewLine); // 每行歌詞的數(shù)組
const regTime = /\[\d{2}:\d{2}.\d{2,3}\]/;
lineArr.forEach((item) => {
if (item === "") return;
const obj = {};
const time = item.match(regTime);
obj.lyric =
item.split("]")[1].trim() === "" ? "" : item.split("]")[1].trim();
obj.time = time
? commonJs.TimeToSeconds(time[0].slice(1, time[0].length - 1))
: 0;
obj.uid = Math.random().toString().slice(-6);
if (obj.lyric === "") {
console.log("這一行沒有歌詞");
} else {
lyricsObjArr.push(obj);
}
});
this.lyricInfo = lyricsObjArr.map((item, index) => {
item.index = index;
return {
...item,
};
});
},
},
};
</script>
<style lang="less" scoped>
.main-page {
width: 100%;
height: 100%;
position: absolute;
background: rgba(15, 15, 15, 0.4);
overflow: hidden;
.background-flitter {
position: absolute;
z-index: 0;
background-repeat: no-repeat;
width: 100%;
height: 100%;
top: 0;
left: 0;
background-size: cover;
background-position: 50%;
filter: blur(8px);
// margin: -20px;
opacity: 0.7;
overflow: hidden;
box-sizing: border-box;
}
.play-mini {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 72px;
// background: #fff;
display: flex;
align-items: center;
padding: 6px 0;
box-sizing: border-box;
z-index: 10;
.songInfo {
min-width: 360px;
max-width: 480px;
position: relative;
padding: 0 18px;
box-sizing: border-box;
display: flex;
.poster {
width: 52px;
height: 52px;
border-radius: 5px;
margin-top: 4px;
margin-right: 20px;
}
.info {
min-width: 280px;
height: 100%;
line-height: 30px;
font-size: 16px;
}
}
.controls {
width: 280px;
height: 100%;
display: flex;
align-items: center;
img {
width: 40px;
height: 40px;
cursor: pointer;
}
.status {
width: 40px;
height: 40px;
margin-left: 36px;
margin-right: 36px;
cursor: pointer;
}
}
.progress-bar {
position: absolute;
z-index: 10;
top: -5px;
width: 100%;
height: 5px;
background: rgba(255, 255, 255, 0.5);
cursor: pointer;
.progress-box {
height: 100%;
background: #40ce8f;
position: relative;
}
}
.right-botton {
position: relative;
width: 420px;
height: 100%;
display: flex;
align-items: center;
.text-div {
color: #fff;
height: 100%;
line-height: 60px;
margin-left: 5px;
margin-right: 5px;
}
.playlist {
position: absolute;
right: 0px;
}
a {
color: #333;
}
}
}
.song-cover-lyric {
position: relative;
width: 100%;
height: 100%;
padding-bottom: 72px;
box-sizing: border-box;
display: flex;
overflow: hidden;
.disc-continer {
width: 50%;
height: 100%;
position: relative;
.poster {
position: relative;
width: 280px;
height: 280px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.3);
left: 50%;
top: 100px;
margin-left: -140px;
box-shadow: 0 0 0 12px rgba(255, 255, 255, 0.4);
animation: animations1 12s linear infinite forwards;
animation-play-state: paused;
overflow: hidden;
margin-bottom: 160px;
img {
width: 100%;
height: 100%;
}
}
.song-name {
width: 100%;
height: 40px;
text-align: center;
font-size: 32px;
font-weight: 600;
color: #fff;
line-height: 40px;
}
.song-artistsName {
width: 100%;
height: 40px;
text-align: center;
font-size: 28px;
font-weight: 600;
color: #fff;
line-height: 40px;
margin-top: 24px;
}
@keyframes animations1 {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
}
.lyric {
width: 50%;
height: 600px;
position: relative;
overflow: hidden;
}
}
}
</style>
<style lang="less">
.ivu-drawer-body {
.list-container {
width: 100%;
height: 100%;
overflow: auto;
position: relative;
.songInfo {
width: 100%;
height: 42px;
display: flex;
align-items: center;
margin-bottom: 12px;
cursor: pointer;
img {
width: 36px;
height: 36px;
border-radius: 5px;
margin-right: 12px;
}
.info {
position: relative;
width: 240px;
height: 36px;
line-height: 18px;
.name {
width: 100%;
height: 18px;
font-size: 14px;
font-weight: 600;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
line-height: 18px;
}
.singer {
width: 100%;
height: 18px;
font-size: 12px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
line-height: 18px;
}
}
}
}
}
</style>
歌詞部分(lyricScroll.vue)
<template>
<!--歌詞-->
<div
ref="musicLyric"
class="music-lyric"
:style="{ 'padding-top': paddingTop }"
>
<div class="music-lyric-items" :style="lyricTop">
<template v-if="lyricsList.length > 0">
<p
v-for="(item, index) in lyricsList"
:key="index"
:data-index="index"
ref="lyric"
:style="{
color: lyricIndex === index ? colorLight : color,
'font-size': fontSize,
}"
>
{{ item.lyric }}
</p>
</template>
<p style="color: #fff" v-else>歌詞拼命加載中。。。。。</p>
</div>
</div>
</template>
<script>
const COMPONENT_NAME = "scroll";
export default {
name: COMPONENT_NAME,
props: {
// 歌詞列表
lyricsList: {
type: Array,
default: () => [],
},
// 當前歌詞下標索引
lyricIndex: {
type: Number,
default: 0,
},
// 歌詞默認色
color: {
type: String,
default: "#fff",
},
// 歌詞高亮色
colorLight: {
type: String,
default: "#40ce8f",
},
fontSize: {
type: String,
default: "16px",
},
lineHeight: {
type: String,
default: "42",
},
paddingTop: {
type: String,
default: "300px",
},
},
data() {
return {
top: 0, // 歌詞居中
//歌詞list示例
lyricListDemo: [
{
index: 0,
lyric: "作曲 : CMJ",
time: 0,
},
{
index: 1,
lyric: "作詞 : 桃玖",
time: 0.29,
},
{
index: 2,
lyric: "你聽啊秋末的落葉",
time: 0.89,
},
{
index: 3,
lyric: "你聽它嘆息著離別",
time: 5.14,
},
{
index: 4,
lyric: "只剩我獨自領略",
time: 9.39,
},
{
index: 5,
lyric: "海與山 風和月",
time: 13.14,
},
],
};
},
mounted() {},
watch: {
lyricIndex(newVal, oldVal) {},
},
computed: {
lyricTop() {
return `transform :translate3d(0, ${(0 - this.lineHeight) *
(this.lyricIndex - this.top)}px, 0);color: ${this.color};line-height: ${
this.lineHeight
}px`;
},
},
methods: {},
};
</script>
<style lang="less" scoped>
/*歌詞部分*/
.music-lyric {
padding-top: 300px;
box-sizing: border-box;
overflow: hidden;
text-align: center;
mask-image: linear-gradient(
to bottom,
rgba(255, 255, 255, 0) 0,
rgba(255, 255, 255, 0.6) 5%,
rgba(255, 255, 255, 1) 15%,
rgba(255, 255, 255, 1) 85%,
rgba(255, 255, 255, 0.6) 95%,
rgba(255, 255, 255, 0) 100%
);
.music-lyric-items {
text-align: center;
font-size: 16px;
color: #fff;
transform: translate3d(0, 0, 0);
transition: transform 0.6s ease-out;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
.on {
color: #40ce8f;
}
}
}
</style>
時間轉(zhuǎn)換的JS(timeConversion.js)
/**
* @author lyq
* @time 2021年11月21日21:08:48
*
* 秒值轉(zhuǎn)時分秒
* @name TimeToString
* @example 秒值轉(zhuǎn)時分秒
* @param {String} seconds 秒
*/
const TimeToString = (seconds) => {
let param = parseInt(seconds);
let hh = "",
mm = "",
ss = "";
if (param >= 0 && param < 60) {
param < 10 ? (ss = "0" + param) : (ss = param);
return "00:" + ss;
} else if (param >= 60 && param < 3600) {
mm = parseInt(param / 60);
mm < 10 ? (mm = "0" + mm) : mm;
param - parseInt(mm * 60) < 10 ?
(ss = "0" + String(param - parseInt(mm * 60))) :
(ss = param - parseInt(mm * 60));
return mm + ":" + ss;
}
}
基本前端代碼都在這兒了,下面為后端的接口邏輯層代碼
/**
* @author : [LiuYanQiang]
* @version : [v1.0]
* @className : MusicServiceImpl
* @description : [描述說明該類的功能]
* @createTime : [2021/11/16 14:28]
* @updateUser : [LiuYanQiang]
* @updateTime : [2021/11/16 14:28]
* @updateRemark : [描述說明本次修改內(nèi)容]
*/
@Service
@Slf4j
public class MusicServiceImpl implements MusicService {
@Autowired
private Environment environment;
/*
* @version V1.0
* Title: getMusicList
* @author LiuYanQiang
* @description 獲取熱歌榜隨機二十首音樂信息
* @createTime 2021/11/16 14:32
* @param []
* @return java.util.Map*/
@Override
public List<Map<String, Object>> getMusicList() {
JSONArray resultObject = null;
//拼接URL發(fā)送對應的請求
StringBuffer url = new StringBuffer();
url.append("https://api.vvhan.com/api/rand.music?type=all&sort=熱歌榜");
//獲取接口的返回值
String body = HttpUtils.sendGet(url.toString());
resultObject = JSONObject.parseArray(body);
List<Map<String, Object>> list = new ArrayList<>();
for (int i = 0; i < resultObject.size(); i++) {
HashMap<String, Object> map = new HashMap<String, Object>();
JSONObject jsonObject = resultObject.getJSONObject(i);
map.put("cover", JSONObject.parseObject(jsonObject.get("album").toString()).getString("picUrl"));
map.put("artistsName", JSONObject.parseArray(jsonObject.get("artists").toString()).getJSONObject(0).getString("name"));
map.put("name", jsonObject.getString("name"));
map.put("id", jsonObject.getString("id"));
list.add(map);
}
Random random = new Random();
int num = random.nextInt(179) % (179 - 0 + 1) + 0;
list = list.subList(num, num + 20);
return list;
}
/*
* @version V1.0
* Title: getMusicURLInfo
* @author LiuYanQiang
* @description 獲取音樂播放的URL信息
* @createTime 2021/11/19 9:22
* @param [Id——音樂Id]
* @return java.util.List<java.util.Map<java.lang.String,java.lang.Object>>*/
@Override
public Map<String, Object> getMusicURLInfo(String Id) {
JSONObject resultObject = null;
//拼接URL發(fā)送對應的請求
StringBuffer url = new StringBuffer();
url.append("https://api.vvhan.com/api/music?id=" + Id + "&type=song&media=netease");
//獲取接口的返回值
String body = HttpUtils.sendGet(url.toString());
resultObject = JSONObject.parseObject(body);
HashMap<String, Object> map = new HashMap<String, Object>();
//判斷第三方給的音樂URL是否有效,無效則替換官方的URL
if(this.isValid(resultObject.get("mp3url").toString())){
map.put("id", resultObject.get("song_id").toString());
map.put("name", resultObject.get("name"));
map.put("artistsName", resultObject.get("author"));
map.put("cover", resultObject.get("cover"));
map.put("url", resultObject.get("mp3url"));
map.put("lyric", this.getMusicLyricById(Id) != null ? this.getMusicLyricById(Id) : null);
}
else{
map.put("id", Id);
map.put("url", "https://music.163.com/song/media/outer/url?id="+Id+".mp3");
map.put("lyric", this.getMusicLyricById(Id) != null ? this.getMusicLyricById(Id) : null);
}
return map;
}
/*
* @version V1.0
* Title: isValid
* @author LiuYanQiang
* @description 判斷鏈接是否有效
* @createTime 2021/11/20 10:23
* @param [strLink——輸入鏈接]
* @return boolean
* */
public boolean isValid(String strLink) {
URL url;
try {
url = new URL(strLink);
HttpURLConnection connt = (HttpURLConnection) url.openConnection();
connt.setRequestMethod("HEAD");
String strMessage = connt.getResponseMessage();
if (strMessage.compareTo("Not Found") == 0) {
return false;
}
connt.disconnect();
} catch (Exception e) {
return false;
}
return true;
}
/*
* @version V1.0
* Title: getRandomFiveMusic
* @author LiuYanQiang
* @description 隨機5首音樂,不能頻繁調(diào)用,不然網(wǎng)易云接口回調(diào)異常
* @createTime 2021/11/19 9:08
* @param []
* @return java.util.List<java.util.Map<java.lang.String,java.lang.Object>>*/
@Override
public List<Map<String, Object>> getRandomFiveMusic() {
List<Map<String, Object>> list = new ArrayList<>();
for (int i = 0; i < 5; i++) {
JSONObject resultObject = null;
//拼接URL發(fā)送對應的請求
StringBuffer url = new StringBuffer();
url.append("https://api.vvhan.com/api/rand.music?type=json&sort=熱歌榜");
//獲取接口的返回值
String body = HttpUtils.sendGet(url.toString());
resultObject = JSONObject.parseObject(body);
JSONObject info = JSONObject.parseObject(resultObject.get("info").toString());
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("id", info.get("id").toString());
map.put("name", info.get("name"));
map.put("artistsName", info.get("auther"));
map.put("cover", info.get("picUrl"));
map.put("url", info.get("mp3url"));
map.put("lyric", this.getMusicLyricById(info.get("id").toString()) != null ? this.getMusicLyricById(info.get("id").toString()) : null);
list.add(map);
log.info("調(diào)用成功" + i + "次");
}
return list;
}
/*
* @version V1.0
* Title: getMusicLyricById
* @author LiuYanQiang
* @description 獲取歌詞信息
* @createTime 2021/11/16 19:23
* @param [Id——音樂Id]
* @return java.lang.String*/
@Override
public String getMusicLyricById(String Id) {
try {
JSONObject resultObject = null;
//拼接URL發(fā)送對應的請求
StringBuffer url = new StringBuffer();
url.append("https://music.163.com/api/song/media?id=" + Id);
//獲取接口的返回值
String body = HttpUtils.sendGet(url.toString());
resultObject = JSONObject.parseObject(body);
if (resultObject.get("lyric").toString() != null) {
return resultObject.get("lyric").toString();
} else {
return null;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
總結
到此這篇關于vue仿網(wǎng)易云音樂播放器界面簡單實現(xiàn)的文章就介紹到這了,更多相關vue網(wǎng)易云音樂播放器界面內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
通過實例解析chrome如何在mac環(huán)境中安裝vue-devtools插件
這篇文章主要介紹了通過實例解析chrome如何在mac環(huán)境中安裝vue-devtools插件,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-07-07
Vue3+ts+setup?getCurrentInstance使用時遇到的問題以及解決辦法
getCurrentInstance方法用于獲取當前組件實例,僅在setup和生命周期中起作用,下面這篇文章主要給大家介紹了關于Vue3+ts+setup?getCurrentInstance使用時遇到的問題以及解決辦法,需要的朋友可以參考下2022-08-08

