feat(lyrics): Add pronunciation lyric mode (#2091)

* feat: Add pronunciation lyric mode

* fix(lyrics): Fixed issue where lyric-mode-switch displays when the translation setting is off
This commit is contained in:
拆家大主教 2023-08-07 23:32:28 +08:00 committed by GitHub
parent f4d3d67132
commit f2efc4e682
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 93 additions and 2 deletions

View File

@ -113,6 +113,8 @@ export default {
pause: 'Pause',
mute: 'Mute',
nextUp: 'Next Up',
translationLyric: 'lyric (trans)',
PronunciationLyric: 'lyric (pronounce)',
},
modal: {
close: 'Close',

View File

@ -108,6 +108,8 @@ export default {
pause: 'Durdur',
mute: 'Sesi kapat',
nextUp: 'Sıradaki',
translationLyric: 'şarkı sözleri (çeviri)',
PronunciationLyric: 'şarkı sözleri (çeviri)',
},
modal: {
close: 'Kapat',

View File

@ -114,6 +114,8 @@ export default {
pause: '暂停',
mute: '静音',
nextUp: '播放列表',
translationLyric: '歌词(译)',
PronunciationLyric: '歌词(音)',
},
modal: {
close: '关闭',

View File

@ -110,6 +110,8 @@ export default {
pause: '暫停',
mute: '靜音',
nextUp: '播放清單',
translationLyric: '歌詞(譯)',
PronunciationLyric: '歌詞(音)',
},
modal: {
close: '關閉',

View File

@ -2,6 +2,7 @@ export function lyricParser(lrc) {
return {
lyric: parseLyric(lrc?.lrc?.lyric || ''),
tlyric: parseLyric(lrc?.tlyric?.lyric || ''),
romalyric: parseLyric(lrc?.romalrc?.lyric || ''),
lyricuser: lrc.lyricUser,
transuser: lrc.transUser,
};

View File

@ -201,6 +201,28 @@
>
<svg-icon icon-class="shuffle" />
</button-icon>
<button-icon
v-show="
isShowLyricTypeSwitch &&
$store.state.settings.showLyricsTranslation &&
lyricType === 'translation'
"
:title="$t('player.translationLyric')"
@click.native="switchLyricType"
>
<span class="lyric-switch-icon"></span>
</button-icon>
<button-icon
v-show="
isShowLyricTypeSwitch &&
$store.state.settings.showLyricsTranslation &&
lyricType === 'romaPronunciation'
"
:title="$t('player.PronunciationLyric')"
@click.native="switchLyricType"
>
<span class="lyric-switch-icon"></span>
</button-icon>
</div>
</div>
</div>
@ -215,7 +237,7 @@
>
<div id="line-1" class="line"></div>
<div
v-for="(line, index) in lyricWithTranslation"
v-for="(line, index) in lyricToShow"
:id="`line${index}`"
:key="index"
class="line"
@ -277,6 +299,8 @@ export default {
lyricsInterval: null,
lyric: [],
tlyric: [],
romalyric: [],
lyricType: 'translation', // or 'romaPronunciation'
highlightLyricIndex: -1,
minimize: true,
background: '',
@ -302,6 +326,14 @@ export default {
bgImageUrl() {
return this.player.currentTrack?.al?.picUrl + '?param=512y512';
},
isShowLyricTypeSwitch() {
return this.romalyric.length > 0 && this.tlyric.length > 0;
},
lyricToShow() {
return this.lyricType === 'translation'
? this.lyricWithTranslation
: this.lyricWithRomaPronunciation;
},
lyricWithTranslation() {
let ret = [];
//
@ -333,6 +365,37 @@ export default {
}
return ret;
},
lyricWithRomaPronunciation() {
let ret = [];
//
const lyricFiltered = this.lyric.filter(({ content }) =>
Boolean(content)
);
// content
if (lyricFiltered.length) {
lyricFiltered.forEach(l => {
const { rawTime, time, content } = l;
const lyricItem = { time, content, contents: [content] };
const sameTimeRomaLyric = this.romalyric.find(
({ rawTime: tLyricRawTime }) => tLyricRawTime === rawTime
);
if (sameTimeRomaLyric) {
const { content: romaLyricContent } = sameTimeRomaLyric;
if (content) {
lyricItem.contents.push(romaLyricContent);
}
}
ret.push(lyricItem);
});
} else {
ret = lyricFiltered.map(({ time, content }) => ({
time,
content,
contents: [content],
}));
}
return ret;
},
lyricFontSize() {
return {
fontSize: `${this.$store.state.settings.lyricFontSize || 28}px`,
@ -439,9 +502,10 @@ export default {
if (!data?.lrc?.lyric) {
this.lyric = [];
this.tlyric = [];
this.romalyric = [];
return false;
} else {
let { lyric, tlyric } = lyricParser(data);
let { lyric, tlyric, romalyric } = lyricParser(data);
lyric = lyric.filter(
l => !/^作(词|曲)\s*(:|)\s*无$/.exec(l.content)
);
@ -461,15 +525,27 @@ export default {
if (lyric.length === 1 && includeAM) {
this.lyric = [];
this.tlyric = [];
this.romalyric = [];
return false;
} else {
this.lyric = lyric;
this.tlyric = tlyric;
this.romalyric = romalyric;
if (tlyric.length * romalyric.length > 0) {
this.lyricType = 'translation';
} else {
this.lyricType =
lyric.length > 0 ? 'translation' : 'romaPronunciation';
}
return true;
}
}
});
},
switchLyricType() {
this.lyricType =
this.lyricType === 'translation' ? 'romaPronunciation' : 'translation';
},
formatTrackTime(value) {
return formatTrackTime(value);
},
@ -758,6 +834,12 @@ export default {
width: 22px;
}
}
.lyric-switch-icon {
color: var(--color-text);
font-size: 14px;
line-height: 14px;
opacity: 0.88;
}
}
}
}