<!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;
background: rgba(0, 0, 0, 0.000);
}
div {
display: block;
padding: 9px;
border-radius: 6px;
background: rgba(128, 128, 128, 0.800);
}
< / style >
< title > OSD Lyrics< / title >
< script >
const electron = (typeof navigator === 'object' & & typeof navigator.userAgent === 'string' & & navigator.userAgent.indexOf('Electron') >= 0) ? 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 >