lyrics improvement
This commit is contained in:
parent
74d9bceb90
commit
5d8a22eacd
5 changed files with 261 additions and 152 deletions
|
@ -7,11 +7,6 @@ Vue.component('sidebar-library-item', {
|
||||||
methods: {}
|
methods: {}
|
||||||
});
|
});
|
||||||
|
|
||||||
Vue.component('lyrics-view', {
|
|
||||||
template: '#lyrics-view',
|
|
||||||
props: ["time", "lyrics", "translation"],
|
|
||||||
methods: {}
|
|
||||||
});
|
|
||||||
|
|
||||||
// This is going to suck to code
|
// This is going to suck to code
|
||||||
var CiderContextMenu = {
|
var CiderContextMenu = {
|
||||||
|
@ -194,12 +189,14 @@ const app = new Vue({
|
||||||
details: {}
|
details: {}
|
||||||
},
|
},
|
||||||
mxmtoken: "",
|
mxmtoken: "",
|
||||||
|
playerReady: false,
|
||||||
lyricon: false,
|
lyricon: false,
|
||||||
currentTrackID: '',
|
currentTrackID: '',
|
||||||
currentTrackIDBG: '',
|
currentTrackIDBG: '',
|
||||||
lyrics: [],
|
lyrics: [],
|
||||||
currentLyricsLine: 0,
|
currentLyricsLine: 0,
|
||||||
lyriccurrenttime: 0,
|
lyriccurrenttime: 0,
|
||||||
|
richlyrics: [],
|
||||||
lyricsMediaItem: {},
|
lyricsMediaItem: {},
|
||||||
lyricsDebug: {
|
lyricsDebug: {
|
||||||
current: 0,
|
current: 0,
|
||||||
|
@ -292,71 +289,20 @@ const app = new Vue({
|
||||||
|
|
||||||
MusicKit.getInstance().videoContainerElement = document.getElementById("apple-music-video-player")
|
MusicKit.getInstance().videoContainerElement = document.getElementById("apple-music-video-player")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
this.mk.addEventListener(MusicKit.Events.playbackTimeDidChange, (a) => {
|
this.mk.addEventListener(MusicKit.Events.playbackTimeDidChange, (a) => {
|
||||||
this.currentSongInfo = a
|
this.currentSongInfo = a
|
||||||
self.playerLCD.playbackDuration = (self.mk.currentPlaybackTime)
|
self.playerLCD.playbackDuration = (self.mk.currentPlaybackTime)
|
||||||
self.lyriccurrenttime = app.mk.currentPlaybackTime;
|
if (!self.playerReady){
|
||||||
|
self.playerReady = true
|
||||||
if (self.lyricon) app.getActiveLyric();
|
document.getElementById("apple-music-player").addEventListener('timeupdate', function () {
|
||||||
|
self.lyriccurrenttime = this.currentTime;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
// animated dot like AM - bad perf
|
// animated dot like AM - bad perf
|
||||||
if (self.lyricon && self.drawertest) {
|
|
||||||
let currentLine = document.querySelector(`.lyric-line.active`)
|
|
||||||
if (currentLine && currentLine.getElementsByClassName('lyricWaiting').length > 0) {
|
|
||||||
let duration = currentLine.getAttribute("end") - currentLine.getAttribute("start");
|
|
||||||
let u = (self.lyriccurrenttime - currentLine.getAttribute("start")) / duration;
|
|
||||||
if (u < 0.25 && !currentLine.classList.contains('mode1')) {
|
|
||||||
try {
|
|
||||||
currentLine.classList.add('mode1');
|
|
||||||
currentLine.classList.remove('mode3');
|
|
||||||
currentLine.classList.remove('mode2');
|
|
||||||
} catch (e) {
|
|
||||||
}
|
|
||||||
currentLine.getElementsByClassName('WaitingDot1')[0].style.animation = `dotOpacity ${0.25 * duration}s cubic-bezier(0.42, 0, 0.58, 1) forwards`;
|
|
||||||
currentLine.getElementsByClassName('WaitingDot2')[0].style.animation = ``;
|
|
||||||
currentLine.getElementsByClassName('WaitingDot3')[0].style.animation = ``;
|
|
||||||
currentLine.getElementsByClassName('WaitingDot2')[0].style.opacity = 0.25;
|
|
||||||
currentLine.getElementsByClassName('WaitingDot3')[0].style.opacity = 0.25;
|
|
||||||
|
|
||||||
} else if (u >= 0.25 && u < 0.5 && !currentLine.classList.contains('mode2')) {
|
|
||||||
try {
|
|
||||||
currentLine.classList.add('mode2');
|
|
||||||
currentLine.classList.remove('mode1');
|
|
||||||
currentLine.classList.remove('mode3');
|
|
||||||
} catch (e) {
|
|
||||||
}
|
|
||||||
currentLine.getElementsByClassName('WaitingDot2')[0].style.animation = `dotOpacity ${0.25 * duration}s cubic-bezier(0.42, 0, 0.58, 1) forwards`;
|
|
||||||
currentLine.getElementsByClassName('WaitingDot1')[0].style.animation = ``;
|
|
||||||
currentLine.getElementsByClassName('WaitingDot3')[0].style.animation = ``;
|
|
||||||
currentLine.getElementsByClassName('WaitingDot1')[0].style.opacity = 1;
|
|
||||||
currentLine.getElementsByClassName('WaitingDot3')[0].style.opacity = 0.25;
|
|
||||||
} else if (u >= 0.5 && u < 0.75 && !currentLine.classList.contains('mode3')) {
|
|
||||||
try {
|
|
||||||
currentLine.classList.add('mode3');
|
|
||||||
currentLine.classList.remove('mode1');
|
|
||||||
currentLine.classList.remove('mode2');
|
|
||||||
} catch (e) {
|
|
||||||
}
|
|
||||||
currentLine.getElementsByClassName('WaitingDot3')[0].style.animation = `dotOpacity ${0.25 * duration}s cubic-bezier(0.42, 0, 0.58, 1) forwards`;
|
|
||||||
currentLine.getElementsByClassName('WaitingDot1')[0].style.animation = ``;
|
|
||||||
currentLine.getElementsByClassName('WaitingDot2')[0].style.animation = ``;
|
|
||||||
currentLine.getElementsByClassName('WaitingDot1')[0].style.opacity = 1;
|
|
||||||
currentLine.getElementsByClassName('WaitingDot2')[0].style.opacity = 1;
|
|
||||||
} else if (u >= 0.75 && currentLine.classList.contains('mode3')) {
|
|
||||||
try {
|
|
||||||
currentLine.classList.remove('mode1');
|
|
||||||
currentLine.classList.remove('mode2');
|
|
||||||
currentLine.classList.remove('mode3');
|
|
||||||
} catch (e) {
|
|
||||||
}
|
|
||||||
currentLine.getElementsByClassName('WaitingDot1')[0].style.animation = ``;
|
|
||||||
currentLine.getElementsByClassName('WaitingDot2')[0].style.animation = ``;
|
|
||||||
currentLine.getElementsByClassName('WaitingDot1')[0].style.opacity = 1;
|
|
||||||
currentLine.getElementsByClassName('WaitingDot2')[0].style.opacity = 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
this.mk.addEventListener(MusicKit.Events.nowPlayingItemDidChange, (a) => {
|
this.mk.addEventListener(MusicKit.Events.nowPlayingItemDidChange, (a) => {
|
||||||
|
@ -380,6 +326,7 @@ const app = new Vue({
|
||||||
}
|
}
|
||||||
self.chrome.artworkReady = false
|
self.chrome.artworkReady = false
|
||||||
self.lyrics = []
|
self.lyrics = []
|
||||||
|
self.richlyrics = []
|
||||||
app.getNowPlayingArtwork(42);
|
app.getNowPlayingArtwork(42);
|
||||||
app.getNowPlayingArtworkBG(32);
|
app.getNowPlayingArtworkBG(32);
|
||||||
app.loadLyrics()
|
app.loadLyrics()
|
||||||
|
@ -1263,6 +1210,7 @@ const app = new Vue({
|
||||||
const artist = encodeURIComponent((this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem.artistName ?? '' : '');
|
const artist = encodeURIComponent((this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem.artistName ?? '' : '');
|
||||||
const time = encodeURIComponent((this.mk.nowPlayingItem != null) ? (Math.round((this.mk.nowPlayingItem.attributes["durationInMillis"] ?? -1000) / 1000) ?? -1) : -1);
|
const time = encodeURIComponent((this.mk.nowPlayingItem != null) ? (Math.round((this.mk.nowPlayingItem.attributes["durationInMillis"] ?? -1000) / 1000) ?? -1) : -1);
|
||||||
var lrcfile = "";
|
var lrcfile = "";
|
||||||
|
var richsync = [];
|
||||||
const lang = "en" // translation language
|
const lang = "en" // translation language
|
||||||
function revisedRandId() {
|
function revisedRandId() {
|
||||||
return Math.random().toString(36).replace(/[^a-z]+/g, '').substr(2, 10);
|
return Math.random().toString(36).replace(/[^a-z]+/g, '').substr(2, 10);
|
||||||
|
@ -1315,7 +1263,7 @@ const app = new Vue({
|
||||||
function getMXMSubs(track, artist, token, lang, time) {
|
function getMXMSubs(track, artist, token, lang, time) {
|
||||||
var usertoken = encodeURIComponent(token);
|
var usertoken = encodeURIComponent(token);
|
||||||
var timecustom = (!time || (time && time < 0)) ? '' : `&f_subtitle_length=${time}&q_duration=${time}&f_subtitle_length_max_deviation=40`;
|
var timecustom = (!time || (time && time < 0)) ? '' : `&f_subtitle_length=${time}&q_duration=${time}&f_subtitle_length_max_deviation=40`;
|
||||||
var url = "https://apic-desktop.musixmatch.com/ws/1.1/macro.subtitles.get?format=json&namespace=lyrics_richsynched&subtitle_format=lrc&q_artist=" + artist + "&q_track=" + track + "&usertoken=" + usertoken + timecustom + "&app_id=web-desktop-app-v1.0&t=" + revisedRandId();
|
var url = "https://apic-desktop.musixmatch.com/ws/1.1/macro.subtitles.get?format=json&namespace=lyrics_richsynched&optional_calls=track.richsync&subtitle_format=lrc&q_artist=" + artist + "&q_track=" + track + "&usertoken=" + usertoken + timecustom + "&app_id=web-desktop-app-v1.0&t=" + revisedRandId();
|
||||||
var req = new XMLHttpRequest();
|
var req = new XMLHttpRequest();
|
||||||
req.overrideMimeType("application/json");
|
req.overrideMimeType("application/json");
|
||||||
req.open('GET', url, true);
|
req.open('GET', url, true);
|
||||||
|
@ -1331,11 +1279,19 @@ const app = new Vue({
|
||||||
if (jsonResponse["message"]["body"]["macro_calls"]["matcher.track.get"]["message"]["header"]["status_code"] == 200 && jsonResponse["message"]["body"]["macro_calls"]["track.subtitles.get"]["message"]["header"]["status_code"] == 200) {
|
if (jsonResponse["message"]["body"]["macro_calls"]["matcher.track.get"]["message"]["header"]["status_code"] == 200 && jsonResponse["message"]["body"]["macro_calls"]["track.subtitles.get"]["message"]["header"]["status_code"] == 200) {
|
||||||
id = jsonResponse["message"]["body"]["macro_calls"]["matcher.track.get"]["message"]["body"]["track"]["track_id"] ?? '';
|
id = jsonResponse["message"]["body"]["macro_calls"]["matcher.track.get"]["message"]["body"]["track"]["track_id"] ?? '';
|
||||||
lrcfile = jsonResponse["message"]["body"]["macro_calls"]["track.subtitles.get"]["message"]["body"]["subtitle_list"][0]["subtitle"]["subtitle_body"];
|
lrcfile = jsonResponse["message"]["body"]["macro_calls"]["track.subtitles.get"]["message"]["body"]["subtitle_list"][0]["subtitle"]["subtitle_body"];
|
||||||
|
|
||||||
|
try{
|
||||||
|
lrcrich = jsonResponse["message"]["body"]["macro_calls"]["track.richsync.get"]["message"]["body"]["richsync"]["richsync_body"];
|
||||||
|
richsync = JSON.parse(lrcrich);
|
||||||
|
app.richlyrics = richsync;
|
||||||
|
} catch(_){}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lrcfile == "") {
|
if (lrcfile == "") {
|
||||||
app.loadAMLyrics()
|
app.loadAMLyrics()
|
||||||
} else {
|
} else {
|
||||||
|
if (richsync == [] || richsync.length == 0 ){
|
||||||
|
console.log("ok");
|
||||||
// process lrcfile to json here
|
// process lrcfile to json here
|
||||||
app.lyricsMediaItem = lrcfile
|
app.lyricsMediaItem = lrcfile
|
||||||
let u = app.lyricsMediaItem.split(/[\r\n]/);
|
let u = app.lyricsMediaItem.split(/[\r\n]/);
|
||||||
|
@ -1358,6 +1314,20 @@ const app = new Vue({
|
||||||
translation: ''
|
translation: ''
|
||||||
});
|
});
|
||||||
app.lyrics = preLrc.reverse();
|
app.lyrics = preLrc.reverse();
|
||||||
|
} else {
|
||||||
|
preLrc = richsync.map(function (item){ return { startTime: item.ts,
|
||||||
|
endTime: item.te,
|
||||||
|
line: item.x,
|
||||||
|
translation: ''}})
|
||||||
|
if (preLrc.length > 0)
|
||||||
|
preLrc.unshift({
|
||||||
|
startTime: 0,
|
||||||
|
endTime: preLrc[0].startTime,
|
||||||
|
line: "lrcInstrumental",
|
||||||
|
translation: ''
|
||||||
|
});
|
||||||
|
app.lyrics = preLrc;
|
||||||
|
}
|
||||||
if (lrcfile != null && lrcfile != '') {
|
if (lrcfile != null && lrcfile != '') {
|
||||||
// load translation
|
// load translation
|
||||||
getMXMTrans(id, lang, token);
|
getMXMTrans(id, lang, token);
|
||||||
|
@ -1397,7 +1367,7 @@ const app = new Vue({
|
||||||
for (var i = 0; i < u.length - 1; i++) {
|
for (var i = 0; i < u.length - 1; i++) {
|
||||||
preTrans[i] = ""
|
preTrans[i] = ""
|
||||||
for (var trans_line of translation_list) {
|
for (var trans_line of translation_list) {
|
||||||
if (u[i].line == " " + trans_line["translation"]["matched_line"]) {
|
if (u[i].line == " " + trans_line["translation"]["matched_line"] || u[i].line == trans_line["translation"]["matched_line"]) {
|
||||||
u[i].translation = trans_line["translation"]["description"];
|
u[i].translation = trans_line["translation"]["description"];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1483,31 +1453,6 @@ const app = new Vue({
|
||||||
getCurrentTime() {
|
getCurrentTime() {
|
||||||
return parseFloat(this.hmsToSecondsOnly(this.parseTime(this.mk.nowPlayingItem.attributes.durationInMillis - app.mk.currentPlaybackTimeRemaining * 1000)));
|
return parseFloat(this.hmsToSecondsOnly(this.parseTime(this.mk.nowPlayingItem.attributes.durationInMillis - app.mk.currentPlaybackTimeRemaining * 1000)));
|
||||||
},
|
},
|
||||||
getActiveLyric() {
|
|
||||||
const delayfix = 0.5
|
|
||||||
const prevLine = app.currentLyricsLine;
|
|
||||||
for (var i = 0; i < app.lyrics.length; i++) {
|
|
||||||
if (this.lyriccurrenttime + delayfix >= app.lyrics[i].startTime && this.lyriccurrenttime + delayfix <= app.lyrics[i].endTime) {
|
|
||||||
if (app.currentLyricsLine != i) {
|
|
||||||
app.currentLyricsLine = i;
|
|
||||||
if (app.lyricon && document.querySelector(`.lyric-line[line-index="${i}"]`)) {
|
|
||||||
document.querySelector(`.lyric-line[line-index="${prevLine}"]`).classList.remove("active");
|
|
||||||
document.querySelector(`.lyric-line[line-index="${i}"]`).classList.add("active");
|
|
||||||
if (checkIfScrollIsStatic) {
|
|
||||||
document.querySelector(`.lyric-line[line-index="${i}"]`).scrollIntoView({
|
|
||||||
behavior: "smooth",
|
|
||||||
block: "center"
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (app.currentLyricsLine == 0) {
|
|
||||||
if (document.querySelector(`.lyric-line[line-index="0"]`) && !document.querySelector(`.lyric-line[line-index="0"]`).classList.contains("active"))
|
|
||||||
document.querySelector(`.lyric-line[line-index="0"]`).classList.add("active");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
seekTo(time) {
|
seekTo(time) {
|
||||||
this.mk.seekToTime(time);
|
this.mk.seekToTime(time);
|
||||||
},
|
},
|
||||||
|
@ -1717,7 +1662,7 @@ const app = new Vue({
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (this.mk.nowPlayingItem && this.mk.nowPlayingItem.id != this.currentTrackID && document.querySelector('.bg-artwork')) {
|
if (this.mk.nowPlayingItem && this.mk.nowPlayingItem.id && this.mk.nowPlayingItem.id != this.currentTrackID && document.querySelector('.bg-artwork')) {
|
||||||
if (document.querySelector('.bg-artwork')) {
|
if (document.querySelector('.bg-artwork')) {
|
||||||
clearInterval(bginterval);
|
clearInterval(bginterval);
|
||||||
}
|
}
|
||||||
|
@ -1733,7 +1678,8 @@ const app = new Vue({
|
||||||
try { clearInterval(bginterval); } catch (err) { console.log(err) }
|
try { clearInterval(bginterval); } catch (err) { console.log(err) }
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.setLibraryArtBG()
|
if (this.mk.nowPlayingItem && this.mk.nowPlayingItem.id && document.querySelector('.bg-artwork')){
|
||||||
|
this.setLibraryArtBG()}
|
||||||
}
|
}
|
||||||
}, 200)
|
}, 200)
|
||||||
},
|
},
|
||||||
|
@ -1741,7 +1687,7 @@ const app = new Vue({
|
||||||
let interval = setInterval(() => {
|
let interval = setInterval(() => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (this.mk.nowPlayingItem && this.mk.nowPlayingItem.id != this.currentTrackIDBG && document.querySelector('.app-playback-controls .artwork')) {
|
if (this.mk.nowPlayingItem && this.mk.nowPlayingItem.id && this.mk.nowPlayingItem.id != this.currentTrackIDBG && document.querySelector('.app-playback-controls .artwork')) {
|
||||||
this.currentTrackIDBG = this.mk.nowPlayingItem.id;
|
this.currentTrackIDBG = this.mk.nowPlayingItem.id;
|
||||||
if (document.querySelector('.app-playback-controls .artwork') != null) {
|
if (document.querySelector('.app-playback-controls .artwork') != null) {
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
|
@ -1757,30 +1703,30 @@ const app = new Vue({
|
||||||
try { clearInterval(interval); } catch (err) { console.log(err) }
|
try { clearInterval(interval); } catch (err) { console.log(err) }
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
if (this.mk.nowPlayingItem && this.mk.nowPlayingItem.id && document.querySelector('.app-playback-controls .artwork')){
|
||||||
this.setLibraryArt()
|
this.setLibraryArt()}
|
||||||
|
|
||||||
}
|
}
|
||||||
}, 200)
|
}, 200)
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async setLibraryArt() {
|
async setLibraryArt() {
|
||||||
const data = await this.mk.api.library.song(this.mk.nowPlayingItem.id)
|
|
||||||
try {
|
try {
|
||||||
|
const data = await this.mk.api.library.song(this.mk.nowPlayingItem.id)
|
||||||
|
|
||||||
if (data != null && data !== "") {
|
if (data != null && data !== "") {
|
||||||
document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', 'url("' + (data["attributes"]["artwork"]["url"]).toString() + '")');
|
document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', 'url("' + (data["attributes"]["artwork"]["url"]).toString() + '")');
|
||||||
} else {
|
} else {
|
||||||
document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("https://beta.music.apple.com/assets/product/MissingArtworkMusic.svg")`);
|
document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("")`);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("https://beta.music.apple.com/assets/product/MissingArtworkMusic.svg")`);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async setLibraryArtBG() {
|
async setLibraryArtBG() {
|
||||||
const data = await this.mk.api.library.song(this.mk.nowPlayingItem.id)
|
|
||||||
try {
|
try {
|
||||||
|
const data = await this.mk.api.library.song(this.mk.nowPlayingItem.id)
|
||||||
|
|
||||||
if (data != null && data !== "") {
|
if (data != null && data !== "") {
|
||||||
document.querySelector('.bg-artwork').src = (data["attributes"]["artwork"]["url"]).toString();
|
document.querySelector('.bg-artwork').src = (data["attributes"]["artwork"]["url"]).toString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1366,6 +1366,14 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
||||||
margin-right: 0px;
|
margin-right: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.lyric-line.active .verse{
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lyric-line.active .verse.verse-active{
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.lyric-line:hover {
|
.lyric-line:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
20
resources/cider-ui/views/components/karaoke-in.ejs
Normal file
20
resources/cider-ui/views/components/karaoke-in.ejs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<script type="text/x-template" id="karaoke-in">
|
||||||
|
<div class="karaoke-viewer">
|
||||||
|
<div class="lyric">
|
||||||
|
<template v-for="segment in lyrics" v-if="segmentInRange(segment.ts, segment.te, segment.x)">
|
||||||
|
<div class="verse-group active">
|
||||||
|
<template v-for="(verse, verseIndex) in segment.l"
|
||||||
|
v-if="verseInRange(segment.ts, segment.te, verse.o)">
|
||||||
|
<span class="verse verse-active">{{ verse.c }}</span>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<span class="verse">{{ verse.c }}</span>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<div class="verse-group">{{ segment.x }}</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</script>
|
164
resources/cider-ui/views/components/lyrics-view.ejs
Normal file
164
resources/cider-ui/views/components/lyrics-view.ejs
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
<script type="text/x-template" id="lyrics-view">
|
||||||
|
<div ref="lyricsview" class="md-body lyric-body">
|
||||||
|
<template v-if="lyrics && lyrics != []">
|
||||||
|
<template v-for="(lyric, index) in lyrics" v-if="lyric.line != 'lrcInstrumental'">
|
||||||
|
<h3 class="lyric-line" @click="if(lyric.startTime != 9999999) app.seekTo(lyric.startTime, false)"
|
||||||
|
v-bind:line-index="index.toString()">
|
||||||
|
<template v-if="richlyrics && richlyrics != [] && richlyrics.length > 0">
|
||||||
|
<div class="richl" >
|
||||||
|
<template v-for="verse in getVerseLine(index-1)" >
|
||||||
|
<span class="verse" :llinestart="lyric.startTime" :versestart="verse.o" >{{ verse.c }}</span>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<div class="norm" >
|
||||||
|
{{ lyric.line }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div class="lyrics-translation" v-if="lyric.translation && lyric.translation != ''">
|
||||||
|
{{ lyric.translation }}
|
||||||
|
</div>
|
||||||
|
</h3>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<h3 class="lyric-line" @click="if(lyric.startTime != 9999999) app.seekTo(lyric.startTime, false)"
|
||||||
|
:start="lyric.startTime"
|
||||||
|
:end="lyric.endTime" v-bind:line-index="index.toString()">
|
||||||
|
<div class="lyricWaiting">
|
||||||
|
<div class='WaitingDot1'></div>
|
||||||
|
<div class='WaitingDot2'></div>
|
||||||
|
<div class='WaitingDot3'></div>
|
||||||
|
</div>
|
||||||
|
</h3>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
No Lyrics Available
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
Vue.component('lyrics-view', {
|
||||||
|
template: '#lyrics-view',
|
||||||
|
props: ["time", "lyrics", "richlyrics", "translation", "onindex"],
|
||||||
|
watch: {
|
||||||
|
time: function () {
|
||||||
|
if (app.lyricon && app.drawer.open) {
|
||||||
|
let currentLine = this.$refs.lyricsview.querySelector(`.lyric-line.active`)
|
||||||
|
if (currentLine && currentLine.getElementsByClassName('lyricWaiting').length > 0) {
|
||||||
|
let duration = currentLine.getAttribute("end") - currentLine.getAttribute("start");
|
||||||
|
let u = (this.time - currentLine.getAttribute("start")) / duration;
|
||||||
|
if (u < 0.25 && !currentLine.classList.contains('mode1')) {
|
||||||
|
try {
|
||||||
|
currentLine.classList.add('mode1');
|
||||||
|
currentLine.classList.remove('mode3');
|
||||||
|
currentLine.classList.remove('mode2');
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
currentLine.getElementsByClassName('WaitingDot1')[0].style.animation = `dotOpacity ${0.25 * duration}s cubic-bezier(0.42, 0, 0.58, 1) forwards`;
|
||||||
|
currentLine.getElementsByClassName('WaitingDot2')[0].style.animation = ``;
|
||||||
|
currentLine.getElementsByClassName('WaitingDot3')[0].style.animation = ``;
|
||||||
|
currentLine.getElementsByClassName('WaitingDot2')[0].style.opacity = 0.25;
|
||||||
|
currentLine.getElementsByClassName('WaitingDot3')[0].style.opacity = 0.25;
|
||||||
|
|
||||||
|
} else if (u >= 0.25 && u < 0.5 && !currentLine.classList.contains('mode2')) {
|
||||||
|
try {
|
||||||
|
currentLine.classList.add('mode2');
|
||||||
|
currentLine.classList.remove('mode1');
|
||||||
|
currentLine.classList.remove('mode3');
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
currentLine.getElementsByClassName('WaitingDot2')[0].style.animation = `dotOpacity ${0.25 * duration}s cubic-bezier(0.42, 0, 0.58, 1) forwards`;
|
||||||
|
currentLine.getElementsByClassName('WaitingDot1')[0].style.animation = ``;
|
||||||
|
currentLine.getElementsByClassName('WaitingDot3')[0].style.animation = ``;
|
||||||
|
currentLine.getElementsByClassName('WaitingDot1')[0].style.opacity = 1;
|
||||||
|
currentLine.getElementsByClassName('WaitingDot3')[0].style.opacity = 0.25;
|
||||||
|
} else if (u >= 0.5 && u < 0.75 && !currentLine.classList.contains('mode3')) {
|
||||||
|
try {
|
||||||
|
currentLine.classList.add('mode3');
|
||||||
|
currentLine.classList.remove('mode1');
|
||||||
|
currentLine.classList.remove('mode2');
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
currentLine.getElementsByClassName('WaitingDot3')[0].style.animation = `dotOpacity ${0.25 * duration}s cubic-bezier(0.42, 0, 0.58, 1) forwards`;
|
||||||
|
currentLine.getElementsByClassName('WaitingDot1')[0].style.animation = ``;
|
||||||
|
currentLine.getElementsByClassName('WaitingDot2')[0].style.animation = ``;
|
||||||
|
currentLine.getElementsByClassName('WaitingDot1')[0].style.opacity = 1;
|
||||||
|
currentLine.getElementsByClassName('WaitingDot2')[0].style.opacity = 1;
|
||||||
|
} else if (u >= 0.75 && currentLine.classList.contains('mode3')) {
|
||||||
|
try {
|
||||||
|
currentLine.classList.remove('mode1');
|
||||||
|
currentLine.classList.remove('mode2');
|
||||||
|
currentLine.classList.remove('mode3');
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
currentLine.getElementsByClassName('WaitingDot1')[0].style.animation = ``;
|
||||||
|
currentLine.getElementsByClassName('WaitingDot2')[0].style.animation = ``;
|
||||||
|
currentLine.getElementsByClassName('WaitingDot1')[0].style.opacity = 1;
|
||||||
|
currentLine.getElementsByClassName('WaitingDot2')[0].style.opacity = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
this.getActiveLyric();
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getActiveLyric() {
|
||||||
|
// console.log(this.time);
|
||||||
|
const delayfix = 0.35
|
||||||
|
const prevLine = app.currentLyricsLine;
|
||||||
|
for (var i = 0; i < this.lyrics.length; i++) {
|
||||||
|
if (this.time + delayfix >= this.lyrics[i].startTime && this.time + delayfix <= app.lyrics[i].endTime) {
|
||||||
|
if (app.currentLyricsLine != i) {
|
||||||
|
app.currentLyricsLine = i;
|
||||||
|
if (app.lyricon && this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${i}"]`)) {
|
||||||
|
this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${prevLine}"]`).classList.remove("active");
|
||||||
|
this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${i}"]`).classList.add("active")
|
||||||
|
if (checkIfScrollIsStatic) {
|
||||||
|
this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${i}"]`).scrollIntoView({
|
||||||
|
behavior: "smooth",
|
||||||
|
block: "center"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (app.currentLyricsLine == 0) {
|
||||||
|
if (this.$refs.lyricsview.querySelector(`.lyric-line[line-index="0"]`) && !this.$refs.lyricsview.querySelector(`.lyric-line[line-index="0"]`).classList.contains("active"))
|
||||||
|
this.$refs.lyricsview.querySelector(`.lyric-line[line-index="0"]`).classList.add("active");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try{
|
||||||
|
try{this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${prevLine}"]`).childNodes.classList.remove("verse-active");} catch(e){
|
||||||
|
|
||||||
|
}
|
||||||
|
// console.log(this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${prevLine}"]`).childNodes);
|
||||||
|
for (child of this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${app.currentLyricsLine}"]`).querySelectorAll(".verse")){
|
||||||
|
// console.log(this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${app.currentLyricsLine}"]`).querySelectorAll(".verse"))
|
||||||
|
if (this.time + delayfix >= child.getAttribute("llinestart") * 1 + child.getAttribute("versestart") * 1){
|
||||||
|
child.classList.add("verse-active");
|
||||||
|
} else {child.classList.remove("verse-active");}
|
||||||
|
}
|
||||||
|
} catch(e){}
|
||||||
|
|
||||||
|
},
|
||||||
|
getActiveVerse(timeStart, timeEnd, verseTime) {
|
||||||
|
let relativeTime = this.time - timeStart
|
||||||
|
console.log(this.time,timeEnd,timeStart,relativeTime >= verseTime && relativeTime <= timeEnd - timeStart)
|
||||||
|
return relativeTime >= verseTime && relativeTime <= timeEnd - timeStart
|
||||||
|
},
|
||||||
|
getVerseLine(index) {
|
||||||
|
|
||||||
|
if (this.richlyrics[index] != null && this.richlyrics[index].l != null) {
|
||||||
|
return this.richlyrics[index].l
|
||||||
|
}
|
||||||
|
else return []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -374,8 +374,7 @@
|
||||||
</div>
|
</div>
|
||||||
<transition name="drawertransition">
|
<transition name="drawertransition">
|
||||||
<div class="app-drawer" v-if="drawer.open">
|
<div class="app-drawer" v-if="drawer.open">
|
||||||
<lyrics-view v-if="drawer.panel == 'lyrics'" :time="lyriccurrenttime" :lyrics="lyrics">
|
<lyrics-view v-if="drawer.panel == 'lyrics'" :time="lyriccurrenttime" :lyrics="lyrics" :richlyrics="richlyrics"></lyrics-view>
|
||||||
</lyrics-view>
|
|
||||||
<cider-queue ref="queue" v-if="drawer.panel == 'queue'"></cider-queue>
|
<cider-queue ref="queue" v-if="drawer.panel == 'queue'"></cider-queue>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
|
@ -490,37 +489,9 @@
|
||||||
<%- include('components/mediaitem-mvview-sp') %>
|
<%- include('components/mediaitem-mvview-sp') %>
|
||||||
<!-- Animated Artwork View -->
|
<!-- Animated Artwork View -->
|
||||||
<%- include('components/animatedartwork-view') %>
|
<%- include('components/animatedartwork-view') %>
|
||||||
|
|
||||||
<!-- Lyrics View -->
|
<!-- Lyrics View -->
|
||||||
<script type="text/x-template" id="lyrics-view">
|
<%- include('components/lyrics-view') %>
|
||||||
<div class="md-body lyric-body">
|
|
||||||
<template v-if="lyrics && lyrics != []">
|
|
||||||
<template v-for="(lyric, index) in lyrics" v-if="lyric.line != 'lrcInstrumental'">
|
|
||||||
<h3 class="lyric-line" @click="if(lyric.startTime != 9999999) app.seekTo(lyric.startTime, false)"
|
|
||||||
v-bind:line-index="index.toString()">
|
|
||||||
{{ lyric.line }}
|
|
||||||
<div class="lyrics-translation" v-if="lyric.translation && lyric.translation != ''">
|
|
||||||
{{ lyric.translation }}
|
|
||||||
<div>
|
|
||||||
</h3>
|
|
||||||
</template>
|
|
||||||
<template v-else>
|
|
||||||
<h3 class="lyric-line" @click="if(lyric.startTime != 9999999) app.seekTo(lyric.startTime, false)"
|
|
||||||
:start="lyric.startTime"
|
|
||||||
:end="lyric.endTime" v-bind:line-index="index.toString()">
|
|
||||||
<div class="lyricWaiting">
|
|
||||||
<div class='WaitingDot1'></div>
|
|
||||||
<div class='WaitingDot2'></div>
|
|
||||||
<div class='WaitingDot3'></div>
|
|
||||||
</div>
|
|
||||||
</h3>
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
<template v-else>
|
|
||||||
No Lyrics Available
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</script>
|
|
||||||
<script src="musickit.js?v=1"></script>
|
<script src="musickit.js?v=1"></script>
|
||||||
<script>
|
<script>
|
||||||
if (typeof MusicKit == 'undefined') {
|
if (typeof MusicKit == 'undefined') {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue