parent
6e5b22162b
commit
cc5ec68490
|
|
@ -1,17 +1,3 @@
|
||||||
@charset "UTF-8";
|
|
||||||
|
|
||||||
/* ----
|
|
||||||
|
|
||||||
# Kico Player 0.9
|
|
||||||
# By: Dreamer-Paul
|
|
||||||
# Last Update: 2021.8.30
|
|
||||||
|
|
||||||
一个简洁强大的网页音乐播放器。
|
|
||||||
|
|
||||||
本代码为奇趣保罗原创,并遵守 MIT 开源协议。欢迎访问我的博客:https://paugram.com
|
|
||||||
|
|
||||||
---- */
|
|
||||||
|
|
||||||
kplayer{
|
kplayer{
|
||||||
--kp-primary: #3498db;
|
--kp-primary: #3498db;
|
||||||
--kp-secondly: #ffc670;
|
--kp-secondly: #ffc670;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
# KPlayer 0.9
|
# KPlayer 0.9
|
||||||
# By: Dreamer-Paul
|
# By: Dreamer-Paul
|
||||||
# Last Update: 2021.9.7
|
# Last Update: 2022.5.12
|
||||||
|
|
||||||
一个简洁强大的网页音乐播放器。
|
一个简洁强大的网页音乐播放器。
|
||||||
|
|
||||||
|
|
@ -99,6 +99,49 @@ var KPlayer = function KPlayer (settings) {
|
||||||
list_items: []
|
list_items: []
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 事件
|
||||||
|
var events = {
|
||||||
|
onPlay: () => {
|
||||||
|
if (!interval) interval = setInterval(interval_fc, 500);
|
||||||
|
|
||||||
|
elements.buttons.toggle.innerHTML = icons.pause;
|
||||||
|
actions.title_change(true);
|
||||||
|
},
|
||||||
|
onPause: () => {
|
||||||
|
interval = clearInterval(interval);
|
||||||
|
elements.buttons.toggle.innerHTML = icons.play;
|
||||||
|
actions.title_change(false);
|
||||||
|
},
|
||||||
|
onProgress: () => {
|
||||||
|
const player = elements.player;
|
||||||
|
const percentage = player.buffered.length ? (
|
||||||
|
player.buffered.end(player.buffered.length - 1) / player.duration
|
||||||
|
) : 0;
|
||||||
|
|
||||||
|
elements.bar.loaded.style.width = percentage * 100 + "%";
|
||||||
|
},
|
||||||
|
onError: () => {
|
||||||
|
interval = clearInterval(interval);
|
||||||
|
elements.buttons.toggle.innerHTML = icons.play;
|
||||||
|
actions.title_change(false);
|
||||||
|
|
||||||
|
elements.details.title.innerText = ":(";
|
||||||
|
elements.details.artist.innerText = "发生了错误";
|
||||||
|
},
|
||||||
|
onEnd: () => {
|
||||||
|
// 列表和随机列表循环
|
||||||
|
if(current.play_mode === 0 || current.play_mode === 2){
|
||||||
|
this.next();
|
||||||
|
}
|
||||||
|
// 单曲循环
|
||||||
|
else if(current.play_mode === 1){
|
||||||
|
current.lyric_index = 0;
|
||||||
|
this.play();
|
||||||
|
elements.lyric.innerText = current.playlist[current.id].title + " (" + current.playlist[current.id].artist + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var wrapper = {
|
var wrapper = {
|
||||||
wrap: tools.create("div", { class: "kp-header" }),
|
wrap: tools.create("div", { class: "kp-header" }),
|
||||||
info: tools.create("div", { class: "kp-info" }),
|
info: tools.create("div", { class: "kp-info" }),
|
||||||
|
|
@ -110,21 +153,9 @@ var KPlayer = function KPlayer (settings) {
|
||||||
|
|
||||||
var interval;
|
var interval;
|
||||||
var interval_fc = function () {
|
var interval_fc = function () {
|
||||||
elements.details.time.innerText = calc.sec_time(elements.player.currentTime);
|
actions.update_time();
|
||||||
elements.bar.played.style.width = (elements.player.currentTime / elements.player.duration) * 100 + "%";
|
actions.update_bar();
|
||||||
|
actions.update_lyric_playing();
|
||||||
if(current.playlist[current.id].lyric){
|
|
||||||
if(current.lyric[current.lyric_index] && elements.player.currentTime > current.lyric[current.lyric_index].time){
|
|
||||||
elements.lyric.innerText = current.lyric[current.lyric_index].text;
|
|
||||||
if(current.lyric[current.lyric_index].sub_text){
|
|
||||||
elements.lyric.innerHTML = current.lyric[current.lyric_index].text + "<br><br>" + current.lyric[current.lyric_index].sub_text;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
elements.lyric.innerText = current.lyric[current.lyric_index].text;
|
|
||||||
}
|
|
||||||
current.lyric_index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 构造模块
|
// 构造模块
|
||||||
|
|
@ -148,23 +179,23 @@ var KPlayer = function KPlayer (settings) {
|
||||||
settings.container.appendChild(elements.container); // 总添加
|
settings.container.appendChild(elements.container); // 总添加
|
||||||
|
|
||||||
// 拖动播放
|
// 拖动播放
|
||||||
elements.container.addEventListener("dragenter", function (e) {
|
elements.container.ondragenter = function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
wrapper.drop.classList.add("active");
|
wrapper.drop.classList.add("active");
|
||||||
});
|
};
|
||||||
elements.container.addEventListener("dragover", function (e) {
|
elements.container.ondragover = function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
wrapper.drop.classList.add("active");
|
wrapper.drop.classList.add("active");
|
||||||
});
|
};
|
||||||
elements.container.addEventListener("drag", function (e) {
|
elements.container.ondrag = function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
wrapper.drop.classList.add("active");
|
wrapper.drop.classList.add("active");
|
||||||
});
|
};
|
||||||
elements.container.addEventListener("dragleave", function (e) {
|
elements.container.ondragleave = function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
wrapper.drop.classList.remove("active");
|
wrapper.drop.classList.remove("active");
|
||||||
});
|
};
|
||||||
elements.container.addEventListener("drop", function (e) {
|
elements.container.ondrop = function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
wrapper.drop.classList.remove("active");
|
wrapper.drop.classList.remove("active");
|
||||||
var arr = [];
|
var arr = [];
|
||||||
|
|
@ -187,75 +218,45 @@ var KPlayer = function KPlayer (settings) {
|
||||||
|
|
||||||
var n = tools.name(s.name);
|
var n = tools.name(s.name);
|
||||||
|
|
||||||
var single = {
|
arr.push({
|
||||||
title: n.title,
|
title: n.title,
|
||||||
artist: n.artist,
|
artist: n.artist,
|
||||||
link: url
|
link: url
|
||||||
};
|
});
|
||||||
|
|
||||||
arr.push(single);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
that.add(arr);
|
that.add(arr);
|
||||||
that.jump(current.playlist.length - 1);
|
that.jump(current.playlist.length - 1);
|
||||||
});
|
};
|
||||||
|
|
||||||
// 播放器
|
// 播放器
|
||||||
elements.player.volume = 1;
|
elements.player.volume = 1;
|
||||||
|
|
||||||
elements.player.addEventListener("play", function () {
|
elements.player.addEventListener("play", events.onPlay);
|
||||||
if(!interval) interval = setInterval(interval_fc, 500);
|
elements.player.addEventListener("pause", events.onPause);
|
||||||
elements.buttons.toggle.innerHTML = icons.pause;
|
elements.player.addEventListener("progress", events.onProgress);
|
||||||
actions.title_change(true);
|
elements.player.addEventListener("error", events.onError);
|
||||||
});
|
elements.player.addEventListener("ended", events.onEnd);
|
||||||
elements.player.addEventListener("pause", function () {
|
|
||||||
interval = clearInterval(interval);
|
|
||||||
elements.buttons.toggle.innerHTML = icons.play;
|
|
||||||
actions.title_change(false);
|
|
||||||
});
|
|
||||||
elements.player.addEventListener("progress", function () {
|
|
||||||
var percentage = elements.player.buffered.length ? elements.player.buffered.end(elements.player.buffered.length - 1) / elements.player.duration : 0;
|
|
||||||
elements.bar.loaded.style.width = percentage * 100 + "%";
|
|
||||||
});
|
|
||||||
elements.player.addEventListener("error", function () {
|
|
||||||
interval = clearInterval(interval);
|
|
||||||
elements.buttons.toggle.innerHTML = icons.play;
|
|
||||||
actions.title_change(false);
|
|
||||||
|
|
||||||
elements.details.title.innerText = ":(";
|
|
||||||
elements.details.artist.innerText = "发生了错误";
|
|
||||||
});
|
|
||||||
elements.player.addEventListener("ended", function () {
|
|
||||||
// 列表和随机列表循环
|
|
||||||
if(current.play_mode === 0 || current.play_mode === 2){
|
|
||||||
that.next();
|
|
||||||
}
|
|
||||||
// 单曲循环
|
|
||||||
else if(current.play_mode === 1){
|
|
||||||
current.lyric_index = 0;
|
|
||||||
that.play();
|
|
||||||
elements.lyric.innerText = current.playlist[current.id].title + " (" + current.playlist[current.id].artist + ")";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 按钮们
|
// 按钮们
|
||||||
elements.buttons.toggle.addEventListener("click", that.toggle);
|
elements.buttons.toggle.addEventListener("click", that.toggle);
|
||||||
elements.buttons.prev.addEventListener("click", that.prev);
|
elements.buttons.prev.addEventListener("click", that.prev);
|
||||||
elements.buttons.next.addEventListener("click", that.next);
|
elements.buttons.next.addEventListener("click", that.next);
|
||||||
elements.buttons.mode.addEventListener("click", that.mode);
|
elements.buttons.mode.addEventListener("click", that.mode);
|
||||||
elements.buttons.list.addEventListener("click", that.list_toggle);
|
elements.buttons.list.addEventListener("click", that.toggle_list);
|
||||||
elements.buttons.volume.addEventListener("click", actions.volume);
|
elements.buttons.volume.addEventListener("click", that.toggle_volume);
|
||||||
|
|
||||||
// 进度条
|
// 进度条
|
||||||
elements.bar.wrap.appendChild(elements.bar.loaded);
|
elements.bar.wrap.appendChild(elements.bar.loaded);
|
||||||
elements.bar.wrap.appendChild(elements.bar.played);
|
elements.bar.wrap.appendChild(elements.bar.played);
|
||||||
elements.bar.wrap.addEventListener("click", function (t) {
|
elements.bar.wrap.addEventListener("click", function (t) {
|
||||||
if(elements.player.currentTime){
|
if (!elements.player.currentTime) return;
|
||||||
elements.player.currentTime = (t.offsetX / elements.bar.wrap.clientWidth) * elements.player.duration;
|
|
||||||
}
|
elements.player.currentTime = (t.offsetX / elements.bar.wrap.clientWidth) * elements.player.duration;
|
||||||
if(current.playlist[current.id].lyric){
|
actions.update_bar();
|
||||||
calc.lyric();
|
actions.update_time();
|
||||||
}
|
|
||||||
|
current.lyric.length && actions.update_lyric();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
playlist: function (item) {
|
playlist: function (item) {
|
||||||
|
|
@ -289,14 +290,10 @@ var KPlayer = function KPlayer (settings) {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
randlist: function () {
|
randlist: function () {
|
||||||
function rand_gen(min, max) {
|
|
||||||
return Math.floor(Math.random() * (max - min) + min);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(var i = 0; i < current.randlist.length - 1; i++){
|
for(var i = 0; i < current.randlist.length - 1; i++){
|
||||||
i++;
|
i++;
|
||||||
var a = rand_gen(0, current.randlist.length - 1);
|
var a = calc.random(0, current.randlist.length - 1);
|
||||||
var b = rand_gen(0, current.randlist.length - 1);
|
var b = calc.random(0, current.randlist.length - 1);
|
||||||
var cache = current.randlist[a];
|
var cache = current.randlist[a];
|
||||||
|
|
||||||
current.randlist[a] = current.randlist[b];
|
current.randlist[a] = current.randlist[b];
|
||||||
|
|
@ -304,7 +301,7 @@ var KPlayer = function KPlayer (settings) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
lyric: function (lyric, sub_lyric) {
|
lyric: function (lyric, sub_lyric) {
|
||||||
var time, text, sub_text, single;
|
var time, text, sub_text;
|
||||||
|
|
||||||
// var text = lyric.match(/\[[0-9]{2,}:[0-9]{2}\.[0-9]{2,}\](\S| )+/g).replace(/\[[0-9]{2,}:[0-9]{2}\.[0-9]{2,}\]/g);
|
// var text = lyric.match(/\[[0-9]{2,}:[0-9]{2}\.[0-9]{2,}\](\S| )+/g).replace(/\[[0-9]{2,}:[0-9]{2}\.[0-9]{2,}\]/g);
|
||||||
|
|
||||||
|
|
@ -348,14 +345,10 @@ var KPlayer = function KPlayer (settings) {
|
||||||
|
|
||||||
// 播放与暂停切换
|
// 播放与暂停切换
|
||||||
this.play = function () {
|
this.play = function () {
|
||||||
if(elements.player.src){
|
elements.player.src && elements.player.play();
|
||||||
elements.player.play();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
this.pause = function () {
|
this.pause = function () {
|
||||||
if(elements.player.src){
|
elements.player.src && elements.player.pause();
|
||||||
elements.player.pause();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
this.toggle = function () {
|
this.toggle = function () {
|
||||||
if(elements.player.src){
|
if(elements.player.src){
|
||||||
|
|
@ -389,10 +382,10 @@ var KPlayer = function KPlayer (settings) {
|
||||||
if(current.playlist[current.id].cover) _meta.artwork = [{ src: current.playlist[current.id].cover }]
|
if(current.playlist[current.id].cover) _meta.artwork = [{ src: current.playlist[current.id].cover }]
|
||||||
|
|
||||||
navigator.mediaSession.metadata = new MediaMetadata(_meta);
|
navigator.mediaSession.metadata = new MediaMetadata(_meta);
|
||||||
navigator.mediaSession.setActionHandler('play', that.play);
|
navigator.mediaSession.setActionHandler("play", that.play);
|
||||||
navigator.mediaSession.setActionHandler('pause', that.pause);
|
navigator.mediaSession.setActionHandler("pause", that.pause);
|
||||||
navigator.mediaSession.setActionHandler('previoustrack', that.prev);
|
navigator.mediaSession.setActionHandler("previoustrack", that.prev);
|
||||||
navigator.mediaSession.setActionHandler('nexttrack', that.next);
|
navigator.mediaSession.setActionHandler("nexttrack", that.next);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 上次播放记录
|
// 上次播放记录
|
||||||
|
|
@ -476,29 +469,51 @@ var KPlayer = function KPlayer (settings) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// 播放列表切换显示
|
// 播放列表切换显示
|
||||||
this.list_toggle = function () {
|
this.toggle_list = function () {
|
||||||
elements.playlist.classList.toggle("show");
|
elements.playlist.classList.toggle("show");
|
||||||
};
|
};
|
||||||
|
|
||||||
// 事件模块
|
// 切换音量
|
||||||
var actions = {
|
this.toggle_volume = function () {
|
||||||
volume: function () {
|
var btn = elements.buttons.volume;
|
||||||
var btn = elements.buttons.volume;
|
var player = elements.player;
|
||||||
|
|
||||||
switch (elements.player.volume){
|
switch (player.volume){
|
||||||
case 1: elements.player.volume = 0.75; btn.innerHTML = icons.mid; break;
|
case 1: player.volume = 0.75; btn.innerHTML = icons.mid; break;
|
||||||
case 0.75: elements.player.volume = 0.50; btn.innerHTML = icons.low; break;
|
case 0.75: player.volume = 0.50; btn.innerHTML = icons.low; break;
|
||||||
case 0.50: elements.player.volume = 0.25; btn.innerHTML = icons.none; break;
|
case 0.50: player.volume = 0.25; btn.innerHTML = icons.none; break;
|
||||||
case 0.25: elements.player.volume = 1; btn.innerHTML = icons.max; break;
|
case 0.25: player.volume = 1; btn.innerHTML = icons.max; break;
|
||||||
}
|
|
||||||
},
|
|
||||||
title_change: function (stat) {
|
|
||||||
settings.title_change && current.playlist[current.id] && stat === true ? document.title = "▶ " + current.playlist[current.id].title + " - " + current.page_title : document.title = current.page_title;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var calc = {
|
// 卸载播放器
|
||||||
lyric: function () {
|
this.destroy = function () {
|
||||||
|
events.onPause();
|
||||||
|
elements.player.pause();
|
||||||
|
|
||||||
|
elements.player.removeEventListener("play", events.onPlay);
|
||||||
|
elements.player.removeEventListener("pause", events.onPause);
|
||||||
|
elements.player.removeEventListener("progress", events.onProgress);
|
||||||
|
elements.player.removeEventListener("error", events.onError);
|
||||||
|
elements.player.removeEventListener("ended", events.onEnd);
|
||||||
|
|
||||||
|
elements.buttons.toggle.removeEventListener("click", that.toggle);
|
||||||
|
elements.buttons.prev.removeEventListener("click", that.prev);
|
||||||
|
elements.buttons.next.removeEventListener("click", that.next);
|
||||||
|
elements.buttons.mode.removeEventListener("click", that.mode);
|
||||||
|
elements.buttons.list.removeEventListener("click", that.toggle_list);
|
||||||
|
elements.buttons.volume.removeEventListener("click", that.toggle_volume);
|
||||||
|
|
||||||
|
elements.player = undefined;
|
||||||
|
elements.buttons = undefined;
|
||||||
|
|
||||||
|
elements.container.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 事件模块
|
||||||
|
var actions = {
|
||||||
|
// 拖拽进度条更新歌词
|
||||||
|
update_lyric: function () {
|
||||||
var num = 0;
|
var num = 0;
|
||||||
|
|
||||||
current.lyric.forEach(function (t, index) {
|
current.lyric.forEach(function (t, index) {
|
||||||
|
|
@ -517,24 +532,52 @@ var KPlayer = function KPlayer (settings) {
|
||||||
elements.lyric.innerText = current.lyric[num].text.toString();
|
elements.lyric.innerText = current.lyric[num].text.toString();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// 播放过程中更新歌词
|
||||||
|
update_lyric_playing: function () {
|
||||||
|
if(!current.lyric.length) return;
|
||||||
|
|
||||||
|
if(current.lyric[current.lyric_index] && elements.player.currentTime > current.lyric[current.lyric_index].time){
|
||||||
|
elements.lyric.innerText = current.lyric[current.lyric_index].text;
|
||||||
|
if(current.lyric[current.lyric_index].sub_text){
|
||||||
|
elements.lyric.innerHTML = current.lyric[current.lyric_index].text + "<br><br>" + current.lyric[current.lyric_index].sub_text;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
elements.lyric.innerText = current.lyric[current.lyric_index].text;
|
||||||
|
}
|
||||||
|
current.lyric_index++;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
update_time: function () {
|
||||||
|
elements.details.time.innerText = calc.sec_time(elements.player.currentTime);
|
||||||
|
},
|
||||||
|
update_bar: function () {
|
||||||
|
elements.bar.played.style.width = (elements.player.currentTime / elements.player.duration) * 100 + "%";
|
||||||
|
},
|
||||||
|
title_change: function (stat) {
|
||||||
|
settings.title_change && current.playlist[current.id] && stat === true ? document.title = "▶ " + current.playlist[current.id].title + " - " + current.page_title : document.title = current.page_title;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 计算函数
|
||||||
|
var calc = {
|
||||||
|
add_zero: function (num) {
|
||||||
|
return num < 10 ? "0" + num : num;
|
||||||
|
},
|
||||||
sec_time: function (second) {
|
sec_time: function (second) {
|
||||||
if(isNaN(second)){
|
if(isNaN(second)){
|
||||||
return '00:00';
|
return "00:00";
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
var add0 = function add0(num) {
|
|
||||||
return num < 10 ? '0' + num : num;
|
|
||||||
};
|
|
||||||
var min = parseInt(second / 60);
|
var min = parseInt(second / 60);
|
||||||
var sec = parseInt(second - min * 60);
|
var sec = parseInt(second - min * 60);
|
||||||
var hours = parseInt(min / 60);
|
var hours = parseInt(min / 60);
|
||||||
var minAdjust = parseInt(second / 60 - 60 * parseInt(second / 60 / 60));
|
var minAdjust = parseInt(second / 60 - 60 * parseInt(second / 60 / 60));
|
||||||
|
|
||||||
return second >= 3600 ? add0(hours) + ':' + add0(minAdjust) + ':' + add0(sec) : add0(min) + ':' + add0(sec);
|
return second >= 3600 ? `${calc.add_zero(hours)}:${calc.add_zero(minAdjust)}:${calc.add_zero(sec)}` : `${calc.add_zero(min)}:${calc.add_zero(sec)}`;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
random: function (min, max) {
|
random: function (min, max) {
|
||||||
return Math.floor(min + Math.random() * (max - min));
|
return Math.floor(Math.random() * (max - min) + min);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -544,7 +587,7 @@ var KPlayer = function KPlayer (settings) {
|
||||||
build.playlist(settings.playlist);
|
build.playlist(settings.playlist);
|
||||||
|
|
||||||
if(settings.show_list === true){
|
if(settings.show_list === true){
|
||||||
that.list_toggle();
|
that.toggle_list();
|
||||||
}
|
}
|
||||||
if(settings.debug){
|
if(settings.debug){
|
||||||
console.log("MP3 兼容情况:" + elements.player.canPlayType("audio/mp3"));
|
console.log("MP3 兼容情况:" + elements.player.canPlayType("audio/mp3"));
|
||||||
|
|
|
||||||
|
|
@ -58,8 +58,7 @@ function KPlayer(props: KPlayerProps, ref: Ref<KPlayerRef>) {
|
||||||
});
|
});
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
// Todo
|
playerRef.current.destroy();
|
||||||
// kp.destroy();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue