feat. OSD Lyrics | 增加桌面歌词功能 (#685)
* Add OSD Lyrics * tidy files * fix OSDLyrics: last line of lyrics not showing, performance * tidy files * make user can resize the lyrics window * Fix bug of initial window size * Fix: 1. auto resize osdlyrics window after packaging; 2. lyric parser problem with %; * tidy filesmaster
parent
d464e30d83
commit
85592142af
@ -0,0 +1,239 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Barlow, -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, WenQuanYi Micro Hei, sans-serif;
|
||||||
|
font-weight: 600;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 28px;
|
||||||
|
user-select: none;
|
||||||
|
margin: 2px;
|
||||||
|
padding: 0px;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-webkit-app-region: drag;
|
||||||
|
}
|
||||||
|
|
||||||
|
div {
|
||||||
|
display: block;
|
||||||
|
padding: 9px;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: rgba(128, 128, 128, 0.800);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<title>OSD Lyrics</title>
|
||||||
|
<script>
|
||||||
|
const electron = process && process.versions && process.versions.hasOwnProperty('electron') ? window.require('electron') : null;
|
||||||
|
const ipcRenderer = electron ? electron.ipcRenderer : null;
|
||||||
|
const player_api = window.location.origin + "/player";
|
||||||
|
const lyrics_api = window.location.origin + "/api/lyric?id=";
|
||||||
|
const min_update_interval = 50;
|
||||||
|
const max_update_interval = 500;
|
||||||
|
song_id = null;
|
||||||
|
lyrics = null;
|
||||||
|
current_line = null;
|
||||||
|
current_index = 0;
|
||||||
|
next_time = 0;
|
||||||
|
function lyric_parser(lrc) {
|
||||||
|
if (!lrc) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
lines = lrc
|
||||||
|
.split('\n')
|
||||||
|
.map(nx => {
|
||||||
|
//nx = decodeURIComponent(x);
|
||||||
|
text = nx.split(']');
|
||||||
|
lrc = text[1];
|
||||||
|
if (!lrc) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
_time = text[0].split('[')[1];
|
||||||
|
if (!_time) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
time = _time.split(':')
|
||||||
|
min = Number(time[0]);
|
||||||
|
sec = Number(time[1]);
|
||||||
|
if (lrc.length < 1) {
|
||||||
|
return [min * 60 + sec, " "]
|
||||||
|
} else {
|
||||||
|
return [min * 60 + sec, lrc];
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter(x => Boolean(x));
|
||||||
|
if (lines.length > 0) {
|
||||||
|
return lines;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function update_window_size() {
|
||||||
|
if (!ipcRenderer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
offsetHeight = document.getElementById('line1').offsetHeight + 4;
|
||||||
|
if (offsetHeight == window.innerHeight) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ipcRenderer.send('resizeOSDLyrics', offsetHeight);
|
||||||
|
}
|
||||||
|
function search_line(progress) {
|
||||||
|
for (i = 1; i < lyrics.length; i++) {
|
||||||
|
if (progress < lyrics[i][0]) {
|
||||||
|
current_index = i - 1;
|
||||||
|
next_time = lyrics[i][0];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
current_index = lyrics.length - 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
function translation_combine(lrc, tr) {
|
||||||
|
if (!lrc) {
|
||||||
|
lyrics = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!tr) {
|
||||||
|
lyrics = lrc.map(x => [x[0], x[1], null]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lyrics = new Array(lrc.length);
|
||||||
|
lrc_length = lrc.length;
|
||||||
|
t_length = tr.length;
|
||||||
|
for (i = 0, j = 0; i < lrc_length;) {
|
||||||
|
if (j >= t_length) {
|
||||||
|
lyrics[i] = [lrc[i][0], lrc[i][1], null];
|
||||||
|
i++;
|
||||||
|
} else {
|
||||||
|
lrc_time = lrc[i][0];
|
||||||
|
tr_time = tr[j][0];
|
||||||
|
if (lrc_time == tr_time) {
|
||||||
|
lyrics[i] = [lrc_time, lrc[i][1], tr[j][1]];
|
||||||
|
i++; j++;
|
||||||
|
} else if (lrc_time < tr_time) {
|
||||||
|
lyrics[i] = [lrc_time, lrc[i][1], null];
|
||||||
|
i++;
|
||||||
|
} else if (lrc_time > tr_time) {
|
||||||
|
while (lrc_time > tr[j][0] && j < t_length) {
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function update_display() {
|
||||||
|
document.getElementById("line1").innerHTML = current_line;
|
||||||
|
update_window_size();
|
||||||
|
}
|
||||||
|
function update_line(progress) {
|
||||||
|
next_update = max_update_interval;
|
||||||
|
if (!lyrics) {
|
||||||
|
current_line = "纯音乐,请欣赏";
|
||||||
|
} else {
|
||||||
|
lyrics_length = lyrics.length;
|
||||||
|
if (progress > lyrics[current_index][0]) {
|
||||||
|
next_index = current_index + 1;
|
||||||
|
if (next_index < lyrics_length) {
|
||||||
|
if (progress < lyrics[next_index][0]) {
|
||||||
|
next_update = (next_time - progress) * 1000;
|
||||||
|
} else {
|
||||||
|
next_next_index = next_index + 1;
|
||||||
|
if (next_next_index < lyrics_length) {
|
||||||
|
if (progress < lyrics[next_next_index][0]) {
|
||||||
|
current_index = next_index;
|
||||||
|
current = lyrics[next_index];
|
||||||
|
current_line = current[2] ? (current[1] + "<br>" + current[2]) : current[1];
|
||||||
|
next_time = lyrics[next_next_index][0];
|
||||||
|
next_update = (next_time - progress) * 1000;
|
||||||
|
} else {
|
||||||
|
search_line(progress);
|
||||||
|
current = lyrics[current_index];
|
||||||
|
current_line = current[2] ? (current[1] + "<br>" + current[2]) : current[1];
|
||||||
|
next_update = (next_time - progress) * 1000;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// next line is last line
|
||||||
|
current_index = next_index;
|
||||||
|
current = lyrics[next_index];
|
||||||
|
current_line = current[2] ? (current[1] + "<br>" + current[2]) : current[1];
|
||||||
|
next_update = max_update_interval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// last line
|
||||||
|
next_update = max_update_interval;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
search_line(progress);
|
||||||
|
current = lyrics[current_index];
|
||||||
|
current_line = current[2] ? (current[1] + "<br>" + current[2]) : current[1];
|
||||||
|
next_update = (next_time - progress) * 1000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (next_update > max_update_interval) {
|
||||||
|
interval = parseInt(next_update / max_update_interval);
|
||||||
|
next_update = next_update / interval;
|
||||||
|
} else if (next_update < min_update_interval) {
|
||||||
|
next_update = min_update_interval;
|
||||||
|
}
|
||||||
|
setTimeout(update_lyrics, next_update);
|
||||||
|
update_display();
|
||||||
|
}
|
||||||
|
function get_lyrics(_song_id) {
|
||||||
|
var url = lyrics_api + _song_id;
|
||||||
|
fetch(url)
|
||||||
|
.then(
|
||||||
|
(_lyric) => {
|
||||||
|
_lyric
|
||||||
|
.text()
|
||||||
|
.then(
|
||||||
|
(text) => {
|
||||||
|
result = JSON.parse(text);
|
||||||
|
if (!result.lrc) {
|
||||||
|
lyrics = null;
|
||||||
|
update_line(_progress);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_lyrics = lyric_parser(result.lrc.lyric);
|
||||||
|
_translation = lyric_parser(result.tlyric.lyric);
|
||||||
|
translation_combine(_lyrics, _translation);
|
||||||
|
current_index = 0;
|
||||||
|
update_line(_progress);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
function update_lyrics() {
|
||||||
|
fetch(player_api)
|
||||||
|
.then(
|
||||||
|
(player) => {
|
||||||
|
player
|
||||||
|
.text()
|
||||||
|
.then((text) => {
|
||||||
|
_status = JSON.parse(text);
|
||||||
|
_song_id = _status.currentTrack.id;
|
||||||
|
_progress = _status.progress;
|
||||||
|
if (_song_id !== song_id) {
|
||||||
|
song_id = _song_id;
|
||||||
|
get_lyrics(_song_id);
|
||||||
|
} else {
|
||||||
|
update_line(_progress);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function init_lyrics() {
|
||||||
|
update_window_size();
|
||||||
|
update_lyrics();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body onload="init_lyrics()">
|
||||||
|
<div id="line1">YesPlayMusic</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
After Width: | Height: | Size: 2.4 KiB |
Loading…
Reference in new issue