2121 >
2222 <Transition name="fade" mode="out-in">
2323 <div
24- :key =" musicStore.songLyric.lrcData?.[0]?.content "
24+ :key =" musicStore.songLyric.lrcData?.[0]?.words?.[0]?.word "
2525 class =" lyric-content"
2626 @after-enter =" lyricsScroll(statusStore.lyricIndex)"
2727 @after-leave =" lyricsScroll(statusStore.lyricIndex)"
3434 <!-- 倒计时 -->
3535 <CountDown
3636 :start =" 0 "
37- :duration =" musicStore .songLyric .yrcData [0 ].time || 0 "
37+ :duration =" ( musicStore .songLyric .yrcData [0 ].startTime || 0 ) / 1000 "
3838 :seek =" playSeek "
3939 :playing =" statusStore .playStatus "
4040 />
5050 // on: statusStore.lyricIndex === index,
5151 // 当播放时间大于等于当前歌词的开始时间
5252 on:
53- (playSeek >= item.time && playSeek < item.endTime) ||
53+ (playSeek >= item.startTime / 1000 && playSeek < item.endTime / 1000 ) ||
5454 statusStore.lyricIndex === index,
5555 'is-bg': item.isBG,
5656 'is-duet': item.isDuet,
5757 },
5858 ]"
5959 :style =" {
6060 filter: settingStore.lyricsBlur
61- ? (playSeek >= item.time && playSeek < item.endTime) ||
61+ ? (playSeek >= item.startTime / 1000 && playSeek < item.endTime / 1000 ) ||
6262 statusStore.lyricIndex === index
6363 ? 'blur(0)'
6464 : `blur(${Math.min(Math.abs(statusStore.lyricIndex - index) * 1.8, 10)}px)`
6565 : 'blur(0)',
6666 }"
67- @click =" jumpSeek(item.time )"
67+ @click =" jumpSeek(item.startTime )"
6868 >
6969 <!-- 歌词 -->
7070 <div class =" content" >
7171 <div
72- v-for =" (text, textIndex) in item.contents "
72+ v-for =" (text, textIndex) in item.words "
7373 :key =" textIndex"
7474 :class =" {
7575 'content-text': true,
7676 'content-long':
7777 settingStore.showYrcLongEffect &&
78- text.duration >= 1.5 &&
79- playSeek <= text.endTime,
80- 'end-with-space': text.endsWithSpace ,
78+ ( text.endTime - item.startTime) / 1000 >= 1.5 &&
79+ playSeek <= text.endTime / 1000 ,
80+ 'end-with-space': text.word.endsWith(' ') || text.startTime === 0 ,
8181 }"
8282 >
83- <span class =" word" :lang =" getLyricLanguage(text.content )" >
84- {{ text.content }}
83+ <span class =" word" :lang =" getLyricLanguage(text.word )" >
84+ {{ text.word }}
8585 </span >
8686 <span
8787 class =" filler"
8888 :style =" getYrcStyle(text, index)"
89- :lang =" getLyricLanguage(text.content )"
89+ :lang =" getLyricLanguage(text.word )"
9090 >
91- {{ text.content }}
91+ {{ text.word }}
9292 </span >
9393 </div >
9494 </div >
9595 <!-- 翻译 -->
96- <span v-if =" item.tran && settingStore.showTran" class =" tran" lang =" en" >
97- {{ item.tran }}
96+ <span v-if =" item.translatedLyric && settingStore.showTran" class =" tran" lang =" en" >
97+ {{ item.translatedLyric }}
9898 </span >
9999 <!-- 音译 -->
100- <span v-if =" item.roma && settingStore.showRoma" class =" roma" lang =" en" >
101- {{ item.roma }}
100+ <span v-if =" item.romanLyric && settingStore.showRoma" class =" roma" lang =" en" >
101+ {{ item.romanLyric }}
102102 </span >
103103 <!-- 间奏倒计时 -->
104104 <div
105105 v-if ="
106106 settingStore.countDownShow &&
107- item.time > 0 &&
108- musicStore.songLyric.yrcData[index + 1]?.time - item.endTime >= 10
107+ item.startTime > 0 &&
108+ ((musicStore.songLyric.yrcData[index + 1]?.startTime || 0) - item.endTime) /
109+ 1000 >=
110+ 10
109111 "
110112 class =" count-down-content"
111113 >
112114 <CountDown
113- :start =" item .endTime "
114- :duration =" musicStore .songLyric .yrcData [index + 1 ]?.time - item .endTime || 0 "
115+ :start =" item .endTime / 1000 "
116+ :duration ="
117+ ((musicStore .songLyric .yrcData [index + 1 ]?.startTime || 0 ) - item .endTime ) /
118+ 1000
119+ "
115120 :seek =" playSeek "
116121 :playing =" statusStore .playStatus "
117122 />
125130 <!-- 倒计时 -->
126131 <CountDown
127132 :start =" 0 "
128- :duration =" musicStore .songLyric .lrcData [0 ].time || 0 "
133+ :duration =" ( musicStore .songLyric .lrcData [0 ].startTime || 0 ) / 1000 "
129134 :seek =" playSeek "
130135 :playing =" statusStore .playStatus "
131136 />
140145 ? `blur(${Math.min(Math.abs(statusStore.lyricIndex - index) * 1.8, 10)}px)`
141146 : 'blur(0)',
142147 }"
143- @click =" jumpSeek(item.time )"
148+ @click =" jumpSeek(item.startTime )"
144149 >
145150 <!-- 歌词 -->
146- <span class =" content" :lang =" getLyricLanguage(item.content)" >{{ item.content }}</span >
151+ <span class =" content" :lang =" getLyricLanguage(item.words?.[0]?.word)" >
152+ {{ item.words?.[0]?.word }}
153+ </span >
147154 <!-- 翻译 -->
148- <span v-if =" item.tran && settingStore.showTran" class =" tran" lang =" en" >
149- {{ item.tran }}
155+ <span v-if =" item.translatedLyric && settingStore.showTran" class =" tran" lang =" en" >
156+ {{ item.translatedLyric }}
150157 </span >
151158 <!-- 音译 -->
152- <span v-if =" item.roma && settingStore.showRoma" class =" roma" lang =" en" >
153- {{ item.roma }}
159+ <span v-if =" item.romanLyric && settingStore.showRoma" class =" roma" lang =" en" >
160+ {{ item.romanLyric }}
154161 </span >
155162 </div >
156163 <div class =" placeholder" />
164171</template >
165172
166173<script setup lang="ts">
167- import type { LyricContentType } from " @/types/main" ;
174+ // import type { LyricContentType } from "@/types/main";
175+ import { LyricWord } from " @applemusic-like-lyrics/lyric" ;
168176import { NScrollbar } from " naive-ui" ;
169177import { useMusicStore , useSettingStore , useStatusStore } from " @/stores" ;
170178import player from " @/utils/player" ;
@@ -222,22 +230,22 @@ const INACTIVE_NO_ANIMATION_STYLE = { opacity: 0 } as const;
222230 * @param lyricIndex 歌词索引
223231 * @returns 逐字歌词动画样式
224232 */
225- const getYrcStyle = (wordData : LyricContentType , lyricIndex : number ) => {
233+ const getYrcStyle = (wordData : LyricWord , lyricIndex : number ) => {
226234 // 获取当前歌词行数据
227235 const currentLine = musicStore .songLyric .yrcData [lyricIndex ];
228236 // 缓存 playSeek 值,避免多次访问响应式变量
229237 const currentSeek = playSeek .value ;
230238
231239 // 判断当前行是否处于激活状态
232240 const isLineActive =
233- (currentSeek >= currentLine .time && currentSeek < currentLine .endTime ) ||
241+ (currentSeek >= currentLine .startTime / 1000 && currentSeek < currentLine .endTime / 1000 ) ||
234242 statusStore .lyricIndex === lyricIndex ;
235243
236244 // 如果当前歌词行不是激活状态,返回固定样式,避免不必要的计算
237245 if (! isLineActive ) {
238246 if (settingStore .showYrcAnimation ) {
239247 // 判断单词是否已经唱过:已唱过保持填充状态(0%),未唱到保持未填充状态(100%)
240- const hasPlayed = currentSeek >= wordData .time + wordData . duration ;
248+ const hasPlayed = currentSeek >= wordData .endTime / 1000 ;
241249 return {
242250 WebkitMaskPositionX: hasPlayed ? " 0%" : " 100%" ,
243251 };
@@ -249,24 +257,30 @@ const getYrcStyle = (wordData: LyricContentType, lyricIndex: number) => {
249257 // 激活状态的样式计算
250258 if (settingStore .showYrcAnimation ) {
251259 // 如果播放状态不是加载中,且当前单词的时间加上持续时间减去播放进度大于 0
252- if (statusStore .playLoading === false && wordData .time + wordData . duration - currentSeek > 0 ) {
260+ if (statusStore .playLoading === false && wordData .endTime / 1000 - currentSeek > 0 ) {
253261 return {
254262 transitionDuration: ` 0s, 0s, 0.35s ` ,
255263 transitionDelay: ` 0ms ` ,
256264 WebkitMaskPositionX: ` ${
257- 100 - Math .max (((currentSeek - wordData .time ) / wordData .duration ) * 100 , 0 )
265+ 100 -
266+ Math .max (
267+ ((currentSeek - wordData .startTime / 1000 ) /
268+ ((wordData .endTime - wordData .startTime ) / 1000 )) *
269+ 100 ,
270+ 0 ,
271+ )
258272 }% ` ,
259273 };
260274 }
261275 // 预计算时间差,避免重复计算
262- const timeDiff = wordData .time - currentSeek ;
276+ const timeDiff = wordData .startTime - currentSeek * 1000 ;
263277 return {
264- transitionDuration: ` ${wordData .duration }ms, ${wordData .duration * 0.8 }ms, 0.35s ` ,
265- transitionDelay: ` ${timeDiff }ms, ${timeDiff + wordData .duration * 0.5 }ms, 0ms ` ,
278+ transitionDuration: ` ${wordData .endTime - wordData . startTime }ms, ${( wordData .endTime - wordData . startTime ) * 0.8 }ms, 0.35s ` ,
279+ transitionDelay: ` ${timeDiff }ms, ${timeDiff + ( wordData .endTime - wordData . startTime ) * 0.5 }ms, 0ms ` ,
266280 };
267281 } else {
268282 // 无动画模式:根据单词时间判断透明度
269- return statusStore .playLoading === false && wordData .time >= currentSeek
283+ return statusStore .playLoading === false && wordData .startTime / 1000 >= currentSeek
270284 ? { opacity: 0 }
271285 : { opacity: 1 };
272286 }
@@ -277,7 +291,7 @@ const jumpSeek = (time: number) => {
277291 if (! time ) return ;
278292 lrcMouseStatus .value = false ;
279293 const offsetSeconds = statusStore .getSongOffset (musicStore .playSong ?.id );
280- player .setSeek (time - offsetSeconds );
294+ player .setSeek (time / 1000 - offsetSeconds );
281295 player .play ();
282296};
283297
@@ -411,7 +425,7 @@ onBeforeUnmount(() => {
411425 opacity 0.3s ,
412426 filter 0.3s ,
413427 margin 0.3s ,
414- padding 0.3s !important ;
428+ padding 0.3s ;
415429 }
416430 & .end-with-space {
417431 margin-right : 12px ;
0 commit comments