興趣乃學習的動力冈在,想自己動手寫個音樂播放器瓷产,查了網(wǎng)上一些博客站玄,最終東拼西湊寫了一個。網(wǎng)上有網(wǎng)易云的接口濒旦,這里不多贅述了株旷。
整體項目代碼挺多的,在這里就只挑選音樂播放和切換音樂來記錄了。
https://github.com/gloryin2016/manageplatform
把搜索后獲取的音樂列表晾剖,將其存入store锉矢;通過index來切換不同的歌曲。
HTML的audio屬性參考http://www.reibang.com/p/1fe701c9179f
//進度條直接用的element的slider齿尽,修改樣式顏色即可
<div class="ap-play-track" ref="track">
<el-slider
class="ap-play-track"
@change="SetCurrentTime"
v-model="processWidth"
></el-slider>
<div>
<audio :src="songInfo.url" id="audio"></audio>
data
data() {
return {
playing: false,
index: 0, // 當前播放歌曲在列表中的下標
currentTime: "00:00", // 當前播放時間
totalTime: "00:00", // 總播放時間
bufferedScaleX: 0, // 緩存進度
processWidth: 0, //播放百分比
progressScaleX: 0, // 播放進度
thumbTranslateX: 0, // 進度條滑塊位置
silderBoxX: 0, //進度條滑塊位置-->采用element后的
volume: 50, // 音量
error: "", // 報錯內(nèi)容
playType: '1', // 播放類型:1-列表循環(huán)沽损,2-隨機播放,3-單曲循環(huán)
//播放列表
songList: [
{
albumId: 75612550,
albumTitle: "辭.九門回憶",
artistsName: "解憂草",
cover: "",
finalTime: "04:00",
id: 1347524822,
index: 6,
mvId: 0,
name: "辭.九門回憶",
sort: "07",
url: "https://music.163.com/song/media/outer/url?id=1347524822.mp3",
},
{
albumId: 85511857,
albumTitle: "謫仙",
artistsName: "伊格賽聽",
cover: "",
finalTime: "02:0",
id: 1421256202,
index: 0,
mvId: 0,
name: "謫仙",
sort: "01",
url: "https://music.163.com/song/media/outer/url?id=1421256202.mp3",
},
{
albumId: 35172219,
albumTitle: "君の名は - 黃昏之時",
artistsName: "Frank_Jiang",
cover:
"https://p1.music.126.net/YppJiMHyrLc7tDkj6jUttg==/109951162858188597.jpg",
finalTime: "03:00",
id: 459116892,
index: 5,
mvId: 0,
name: "黃昏之時(FRANKOWO Bootleg)",
sort: "06",
url: "https://music.163.com/song/media/outer/url?id=459116892.mp3",
},
],
//當前播放歌曲
songInfo: {
albumId: 75612550,
albumTitle: "辭.九門回憶",
artistsName: "解憂草/冰幽",
cover: "",
finalTime: "04:00",
id: 1347524822,
index: 6,
mvId: 0,
name: "辭.九門回憶",
sort: "07",
url: "https://music.163.com/song/media/outer/url?id=1347524822.mp3",
},
lyricsObjArr: [],//歌詞
lyricIndex: 0,歌詞索引
};
},
JS
mounted() {
audio = document.getElementById("audio");
this.Init();
},
method: {
Init(){
this.songInfo = this.songList[0];
this.audioInit();
}
//播放與暫停
play() {
if (this.playing) {
// 播放中,點擊則為暫停
this.playing = false;
audio.pause();
} else {
// 暫停中,點擊則為播放
this.playing = true;
audio.play();
}
},
audioInit() {
let _this = this;
let progressL = this.$refs.track.offsetWidth; // 進度條總長
// 播放位置改變時觸發(fā)[注意:播放和調(diào)整指示定位時都會觸發(fā)](主要事件)
audio.addEventListener("timeupdate", () => {
// 當前播放時間
_this.currentTime = _this.timeToString(audio.currentTime);
let compareTime = audio.currentTime;
for (let i = 0; i < _this.lyricsObjArr.length; i++) {
if (compareTime > parseInt(_this.lyricsObjArr[i].time)) {
const index = _this.$refs.lyric[i].dataset.index;
if (i === parseInt(index)) {
_this.lyricIndex = i;
}
}
}
// 總播放時間
_this.totalTime = _this.timeToString(audio.duration);
// 當前播放進度百分比
let precent = audio.currentTime / audio.duration || 0;
// 當前播放進度
_this.progressScaleX = precent.toFixed(3);
_this.processWidth = precent.toFixed(2) * 100;
// 當前緩存進度
// 已緩存時間
let buffered = audio.buffered.length
? audio.buffered.end(audio.buffered.length - 1)
: 0;
_this.bufferedScaleX = (buffered / audio.duration).toFixed(3);
// 當前進度按鈕位置
_this.thumbTranslateX = (precent * progressL).toFixed(3);
});
// 音頻或視頻能夠不停頓地一直播放
audio.addEventListener("canplaythrough", () => {
console.log("canplaythrough");
});
// 音頻或視頻的時長已改變
audio.addEventListener("durationchange", () => {
console.log("durationchange");
_this.totalTime = _this.timeToString(audio.duration);
});
// 在音頻或視頻終止加載時觸發(fā)循头,包括終止當前播放(未加載完)進行下一首播放時也會觸發(fā)
audio.addEventListener("abort", () => {
console.log("abort");
});
// 在音頻或視頻加載發(fā)生錯誤時觸發(fā)
audio.addEventListener("error", () => {
console.log("error");
console.log("-----networkState---------", audio.networkState);
console.log("-----readyState---------", audio.readyState);
switch (audio.networkState) {
case "0":
_this.error = "尚未初始化";
break;
case "1":
_this.error = "正在下載數(shù)據(jù)";
break;
case "3":
_this.error = "未找到資源";
break;
}
audio.readyState == "0" && (_this.error = "音頻地址錯誤");
setTimeout(() => {
_this.error = "";
}, 3000);
});
// 播放結(jié)束
audio.addEventListener(
"ended",
() => {
console.log("ended");
switch (parseInt(_this.playType)) {
case 1: // 列表循環(huán)
_this.index =
_this.index + 1 >= _this.songList.length ? 0 : _this.index + 1;
break;
case 2: // 隨機播放
_this.index = Math.floor(Math.random() * _this.songList.length);
break;
case 3: // 單曲循環(huán)
break;
}
_this.songInfo = _this.songList[_this.index];
this.$store.dispatch("setSongIndex", _this.index); //在vuex存入當前播放歌曲的index
this.GetLyric(_this.songInfo.id);//獲取歌詞的接口
_this.thumbSlide = true;
setTimeout(() => {
audio.play();
}, 100);
// 解決因為transition的回彈bug
setTimeout(() => {
_this.thumbSlide = false;
}, 1000);
},
true
);
},
},
// 秒值轉(zhuǎn)字符串
timeToString(param) {
param = parseInt(param);
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;
}
},
//上下首封裝
skipFn(type) {
switch (parseInt(this.playType)) {
case 2: // 隨機播放
this.index = Math.floor(Math.random() * this.songList.length);
break;
default:
if (type == "skipBack") {
this.index - 1 >= 0 ? this.index-- : 0;
} else {
this.index =
this.index + 1 >= this.songList.length
? this.songList.length - 1
: this.index + 1;
}
break;
}
this.songInfo = this.songList[this.index];
this.$store.dispatch("setSongIndex", this.index);
this.playing = true;
setTimeout(() => {
this.totalTime = "00:00";
audio.play();
}, 100);
},