Skip to content

Commit e0380ad

Browse files
authored
Merge pull request #773 from imsyy/dev-fixerr
🐞 fix: 修复 ttml 歌词解析问题
2 parents 2f382c6 + d1628de commit e0380ad

7 files changed

Lines changed: 49 additions & 20 deletions

File tree

.github/workflows/issue-helper.yml

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636
token: ${{ secrets.GITHUB_TOKEN }}
3737
body: |
3838
抱歉,由于被标记为 **${{ github.event.label.name }}**,该 Issue 将自动关闭
39-
如果您认为该 Issue 仍然有效,请重新开启或者创建新的 Issue,我们会尽快确认并修复
39+
如果您认为该 Issue 仍然有效,请创建新的 Issue,我们会尽快确认并修复
4040
# 有问题回复
4141
- name: Auto Reply
4242
if: github.event.action == 'labeled' && github.event.label.name == '有问题'
@@ -58,6 +58,17 @@ jobs:
5858
labels: "有问题, 过期"
5959
body: |
6060
🤝 您好 @${{ github.event.issue.user.login }},感谢您的反馈!我们已经确认该问题,并将在下一个版本中修复
61+
# 无法复现
62+
- name: Auto Unreproducible
63+
if: github.event.action == 'labeled' && github.event.label.name == '无法复现'
64+
uses: actions-cool/issues-helper@v3
65+
with:
66+
actions: "create-comment"
67+
token: ${{ secrets.GITHUB_TOKEN }}
68+
body: |
69+
🤝 您好 @${{ github.event.issue.user.login }},感谢您的反馈!
70+
由于无法复现问题,我们无法修复
71+
请确保您已经详细描述了问题的复现步骤,维护团队会尽快查看
6172
# 已修复
6273
- name: Auto Fixed
6374
if: github.event.action == 'labeled' && github.event.label.name == '已修复'
@@ -68,6 +79,6 @@ jobs:
6879
labels: "BUG"
6980
close-reason: "completed"
7081
body: |
71-
🎉 您好 @${{ github.event.issue.user.login }},该问题已修复,感谢您的反馈!
72-
73-
若您觉得仍存在问题,请重新开启或者创建新的 Issue,我们会尽快确认并修复
82+
🎉 您好 @${{ github.event.issue.user.login }},感谢您的反馈!
83+
该问题已在当前开发版或下一个正式版中修复完成。
84+
若您觉得仍存在问题,请创建新的 Issue,我们会尽快确认并修复

components.d.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ declare module 'vue' {
8888
NH1: typeof import('naive-ui')['NH1']
8989
NH2: typeof import('naive-ui')['NH2']
9090
NH3: typeof import('naive-ui')['NH3']
91-
NHelpTip: typeof import('naive-ui')['NHelpTip']
9291
NIcon: typeof import('naive-ui')['NIcon']
9392
NImage: typeof import('naive-ui')['NImage']
9493
NInput: typeof import('naive-ui')['NInput']
@@ -121,7 +120,6 @@ declare module 'vue' {
121120
NSelect: typeof import('naive-ui')['NSelect']
122121
NSkeleton: typeof import('naive-ui')['NSkeleton']
123122
NSlider: typeof import('naive-ui')['NSlider']
124-
NSpace: typeof import('naive-ui')['NSpace']
125123
NSpin: typeof import('naive-ui')['NSpin']
126124
NSwitch: typeof import('naive-ui')['NSwitch']
127125
NTab: typeof import('naive-ui')['NTab']

src/components/Player/PlayerMeta/PlayerData.vue

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,7 @@
5656
<span class="meta-item">{{ lyricMode }}</span>
5757
<!-- 是否在线 -->
5858
<span class="meta-item">
59-
{{
60-
musicStore.playSong.path
61-
? "LOCAL"
62-
: musicStore.playSong.type === "streaming"
63-
? "STREAMING"
64-
: "ONLINE"
65-
}}
59+
{{ audioSourceText }}
6660
</span>
6761
</n-flex>
6862
<!-- 歌手 -->
@@ -120,6 +114,7 @@ import type { RouteLocationRaw } from "vue-router";
120114
import { useMusicStore, useStatusStore, useSettingStore } from "@/stores";
121115
import { debounce, isObject } from "lodash-es";
122116
import { removeBrackets } from "@/utils/format";
117+
import { SongUnlockServer } from "@/core/player/SongManager";
123118
124119
defineProps<{
125120
center?: boolean;
@@ -144,6 +139,23 @@ const lyricMode = computed(() => {
144139
return musicStore.isHasLrc ? "LRC" : "NO-LRC";
145140
});
146141
142+
/** 歌曲解锁服务器名称映射 */
143+
const sourceMap: Record<string, string> = {
144+
[SongUnlockServer.NETEASE]: "Netease",
145+
[SongUnlockServer.KUWO]: "Kuwo",
146+
[SongUnlockServer.BODIAN]: "Bodian",
147+
[SongUnlockServer.GEQUBAO]: "Gequbao",
148+
};
149+
150+
const audioSourceText = computed(() => {
151+
if (musicStore.playSong.path) return "LOCAL";
152+
if (musicStore.playSong.type === "streaming") return "STREAMING";
153+
if (statusStore.audioSource) {
154+
return sourceMap[statusStore.audioSource] || statusStore.audioSource.toUpperCase();
155+
}
156+
return "ONLINE";
157+
});
158+
147159
const jumpPage = debounce(
148160
(go: RouteLocationRaw) => {
149161
if (!go) return;

src/core/player/LyricManager.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,7 @@ class LyricManager {
511511
const major = lang_filter(context_lang);
512512
const cleaned_ttml = ttml_cleaner(ttmlContent, major);
513513

514-
return cleaned_ttml;
514+
return cleaned_ttml.replace(/\n\s*/g, "");
515515
}
516516

517517
/**
@@ -554,7 +554,7 @@ class LyricManager {
554554
try {
555555
const ttmlContent = typeof ttml === "string" ? ttml : "";
556556
if (ttmlContent) {
557-
ttmlLines = parseTTML(ttmlContent).lines || [];
557+
ttmlLines = parseTTML(this.cleanTTMLTranslations(ttmlContent)).lines || [];
558558
console.log("检测到本地TTML歌词覆盖", ttmlLines);
559559
}
560560
} catch (err) {
@@ -620,7 +620,6 @@ class LyricManager {
620620
};
621621

622622
const lrcData = stripLyricMetadata(lyricData.lrcData || [], options);
623-
624623
let yrcData = lyricData.yrcData || [];
625624

626625
if (!statusStore.usingTTMLLyric || settingStore.enableExcludeTTML) {

src/core/player/PlayerController.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ class PlayerController {
132132
// 更新音质和解锁状态
133133
statusStore.songQuality = audioSource.quality;
134134
statusStore.playUblock = audioSource.isUnlocked ?? false;
135+
statusStore.audioSource = audioSource.source;
135136
// 执行底层播放
136137
await this.loadAndPlay(audioSource.url, autoPlay, seek);
137138
if (requestToken !== this.currentRequestToken) return;
@@ -176,6 +177,7 @@ class PlayerController {
176177
// 更新音质和解锁状态
177178
statusStore.songQuality = audioSource.quality;
178179
statusStore.playUblock = audioSource.isUnlocked ?? false;
180+
statusStore.audioSource = audioSource.source;
179181
// 停止当前播放
180182
audioManager.stop();
181183
// 执行底层播放,保持进度,保持原播放状态

src/core/player/SongManager.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ export type AudioSource = {
3737
isTrial?: boolean;
3838
/** 音质 */
3939
quality?: QualityType;
40+
/** 音源 */
41+
source?: string;
4042
};
4143

4244
class SongManager {
@@ -206,13 +208,15 @@ class SongManager {
206208
// 推断音质
207209
let quality = QualityType.HQ;
208210
if (unlockUrl && (unlockUrl.includes(".flac") || unlockUrl.includes(".wav"))) {
209-
quality = QualityType.SQ;
211+
quality = QualityType.SQ;
210212
}
213+
console.log(`最终音质判断:详细输出:`, { unlockUrl, quality });
211214
return {
212215
id: songId,
213216
url: unlockUrl,
214217
isUnlocked: true,
215218
quality,
219+
source: r.value.server,
216220
};
217221
}
218222
}
@@ -358,20 +362,20 @@ class SongManager {
358362
// 如果官方链接有效且非试听(或者用户接受试听)
359363
if (officialUrl && (!isTrial || (isTrial && settingStore.playSongDemo))) {
360364
if (isTrial) window.$message.warning("当前歌曲仅可试听");
361-
return { id: songId, url: officialUrl, quality, isUnlocked: false };
365+
return { id: songId, url: officialUrl, quality, isUnlocked: false, source: "netease" };
362366
}
363367
// 尝试解锁
364368
if (canUnlock) {
365369
const unlockUrl = await this.getUnlockSongUrl(song);
366370
if (unlockUrl.url) {
367-
console.log(`🔓 [${songId}] 解锁成功`);
371+
console.log(`🔓 [${songId}] 解锁成功`, unlockUrl);
368372
return unlockUrl;
369373
}
370374
}
371375
// 最后的兜底:检查本地是否有缓存(不区分音质)
372376
const fallbackUrl = await this.checkLocalCache(songId);
373377
if (fallbackUrl) {
374-
console.log(`🚀 [${songId}] 网络请求失败,使用本地缓存兜底`);
378+
console.log(`🚀 [${songId}] 网络请求失败,使用本地缓存兜底`, fallbackUrl);
375379
return { id: songId, url: fallbackUrl, isUnlocked: true };
376380
}
377381
// 无可用源

src/stores/status.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ interface StatusState {
6060
usingQRCLyric: boolean;
6161
/** 当前歌曲音质 */
6262
songQuality: QualityType | undefined;
63+
/** 当前歌曲音源 */
64+
audioSource: string | undefined;
6365
/** 当前播放索引 */
6466
playIndex: number;
6567
/** 歌词播放索引 */
@@ -159,6 +161,7 @@ export const useStatusStore = defineStore("status", {
159161
usingTTMLLyric: false,
160162
usingQRCLyric: false,
161163
songQuality: undefined,
164+
audioSource: undefined,
162165
playIndex: -1,
163166
lyricIndex: -1,
164167
lyricLoading: false,

0 commit comments

Comments
 (0)