Skip to content

Commit 6d8a438

Browse files
committed
core: 修正部分排版,允许背景传入空值以指示当前没有背景
player: 修正导入歌曲流程,修正 Safari 不能正确抓取 AMLL TTML DB 歌词的问题
1 parent fec5a37 commit 6d8a438

File tree

6 files changed

+75
-41
lines changed

6 files changed

+75
-41
lines changed

packages/core/src/bg-render/mesh-renderer/index.ts

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,7 @@ export class MeshGradientRenderer extends BaseRenderer {
733733
) as HTMLCanvasElement;
734734
private targetSize = Vec2.fromValues(0, 0);
735735
private currentSize = Vec2.fromValues(0, 0);
736+
private isNoCover = true;
736737
private meshStates: MeshState[] = [];
737738
private _disposed = false;
738739

@@ -812,16 +813,34 @@ export class MeshGradientRenderer extends BaseRenderer {
812813
latestMeshState.mesh.bind();
813814
// 考虑到我们并不逐帧更新网格控制点,因此也不需要重复调用 updateMesh
814815
if (this.manualControl) latestMeshState.mesh.updateMesh();
815-
latestMeshState.alpha = Math.min(1, latestMeshState.alpha + delta / 500);
816-
if (latestMeshState.alpha >= 1) {
817-
const deleted = this.meshStates.splice(0, this.meshStates.length - 1);
816+
if (this.isNoCover) {
817+
for (const state of this.meshStates) {
818+
state.alpha = Math.max(0, state.alpha - delta / 500);
819+
}
820+
const deleted = this.meshStates.filter((s) => s.alpha === 0);
821+
this.meshStates = this.meshStates.filter((s) => s.alpha > 0);
818822
for (const state of deleted) {
819823
state.mesh.dispose();
820824
state.texture.dispose();
821825
}
822-
}
823-
if (this.meshStates.length === 1 && latestMeshState.alpha >= 1) {
824-
canBeStatic = true;
826+
if (this.meshStates.length === 0) {
827+
canBeStatic = true;
828+
}
829+
} else {
830+
latestMeshState.alpha = Math.min(
831+
1,
832+
latestMeshState.alpha + delta / 500,
833+
);
834+
if (latestMeshState.alpha >= 1) {
835+
const deleted = this.meshStates.splice(0, this.meshStates.length - 1);
836+
for (const state of deleted) {
837+
state.mesh.dispose();
838+
state.texture.dispose();
839+
}
840+
}
841+
if (this.meshStates.length === 1 && latestMeshState.alpha >= 1) {
842+
canBeStatic = true;
843+
}
825844
}
826845
}
827846

@@ -922,11 +941,16 @@ export class MeshGradientRenderer extends BaseRenderer {
922941
this.requestTick();
923942
}
924943
override async setAlbum(
925-
albumSource: string | HTMLImageElement | HTMLVideoElement,
944+
albumSource?: string | HTMLImageElement | HTMLVideoElement,
926945
isVideo?: boolean,
927946
): Promise<void> {
928-
if (typeof albumSource === "string" && albumSource.trim().length === 0)
929-
throw new Error("Empty album url");
947+
if (
948+
albumSource === undefined ||
949+
(typeof albumSource === "string" && albumSource.trim().length === 0)
950+
) {
951+
this.isNoCover = true;
952+
return;
953+
}
930954
let res: HTMLImageElement | HTMLVideoElement | null = null;
931955
let remainRetryTimes = 5;
932956
while (!res && remainRetryTimes > 0) {
@@ -947,7 +971,12 @@ export class MeshGradientRenderer extends BaseRenderer {
947971
remainRetryTimes--;
948972
}
949973
}
950-
if (!res) return;
974+
if (!res) {
975+
console.error("Failed to load album resource", albumSource);
976+
this.isNoCover = true;
977+
return;
978+
}
979+
this.isNoCover = false;
951980
// resize image
952981
const c = this.reduceImageSizeCanvas;
953982
const ctx = c.getContext("2d", {

packages/core/src/bg-render/pixi-renderer.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,10 +195,13 @@ export class PixiRenderer extends BaseRenderer {
195195
}
196196

197197
override async setAlbum(
198-
albumSource: string | HTMLImageElement | HTMLVideoElement,
198+
albumSource?: string | HTMLImageElement | HTMLVideoElement,
199199
isVideo?: boolean,
200200
): Promise<void> {
201-
if (typeof albumSource === "string" && albumSource.trim().length === 0)
201+
if (
202+
!albumSource ||
203+
(typeof albumSource === "string" && albumSource.trim().length === 0)
204+
)
202205
return;
203206
let res: HTMLImageElement | HTMLVideoElement | null = null;
204207
let remainRetryTimes = 5;

packages/core/src/lyric-player/base.ts

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -410,26 +410,28 @@ export abstract class LyricPlayerBase
410410
this.hasDuetLine = this.processedLines.some((line) => line.isDuet);
411411

412412
// 将行间有较短空隙的两个歌词行的结束时间拉长,与下一行歌词行的开始时间一致,以便于更好的显示
413-
this.processedLines.forEach((line, i, lines) => {
414-
const nextLine = lines[i + 1];
415-
const lastWord = line.words[line.words.length - 1];
416-
if (lastWord) {
417-
if (nextLine) {
418-
if (nextLine.startTime > line.endTime) {
419-
line.endTime = Math.min(line.endTime + 1500, nextLine.startTime);
420-
}
421-
} else {
422-
line.endTime = line.endTime + 1500;
423-
}
424-
}
425-
});
426-
427-
// 让背景歌词和上一行歌词一同出现
413+
// Update: 感觉还是不太适用,所以移除了
414+
// this.processedLines.forEach((line, i, lines) => {
415+
// const nextLine = lines[i + 1];
416+
// const lastWord = line.words[line.words.length - 1];
417+
// if (lastWord) {
418+
// if (nextLine) {
419+
// if (nextLine.startTime > line.endTime) {
420+
// line.endTime = Math.min(line.endTime + 1500, nextLine.startTime);
421+
// }
422+
// } else {
423+
// line.endTime = line.endTime + 1500;
424+
// }
425+
// }
426+
// });
427+
428+
// 让背景歌词和上一行歌词一同出现并一同消失
428429
this.processedLines.forEach((line, i, lines) => {
429430
if (line.isBG) return;
430431
const nextLine = lines[i + 1];
431432
if (nextLine?.isBG) {
432433
nextLine.startTime = Math.min(nextLine.startTime, line.startTime);
434+
nextLine.endTime = Math.max(nextLine.endTime, line.endTime);
433435
}
434436
});
435437
for (const line of this.currentLyricLineObjects) {
@@ -440,6 +442,9 @@ export abstract class LyricPlayerBase
440442
this.hotLines.clear();
441443
this.bufferedLines.clear();
442444
this.setCurrentTime(0, true);
445+
if (import.meta.env.DEV) {
446+
console.log("歌词处理完成", this.processedLines);
447+
}
443448
}
444449

445450
/**
@@ -460,15 +465,7 @@ export abstract class LyricPlayerBase
460465
// 如果当前所有缓冲行都将被删除且没有新热行加入,则删除所有缓冲行,且也不会修改当前滚动位置
461466
// 如果当前所有缓冲行都将被删除且有新热行加入,则删除所有缓冲行并加入新热行作为缓冲行,然后修改当前滚动位置
462467

463-
// this.initializeSeeking = isSeek;
464468
this.currentTime = time;
465-
// if (Math.abs(this.currentTime - this.lastCurrentTime) >= 100) {
466-
// this.initializeSeeking = true;
467-
// } else this.initializeSeeking = false;
468-
// if (!this.isPageVisible) return;
469-
// if (!this._getIsNonDynamic() && !this.supportMaskImage)
470-
// this.element.style.setProperty("--amll-player-time", `${time}`);
471-
// if (this.isScrolled) return;
472469

473470
if (!this.initialLayoutFinished && !isSeek) return;
474471

packages/player/src-tauri/capabilities/migrated.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ identifier = "fs:allow-rename"
5454
identifier = "fs:allow-remove"
5555
[[permissions]]
5656
identifier = "fs:scope"
57-
allow = ["$APPDATA/**"]
57+
allow = ["$APPDATA/**", "$HOME/**"]
5858
[[permissions]]
5959
identifier = "fs:allow-stat"
6060
[[permissions]]

packages/player/src/components/LocalMusicContext/index.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -282,8 +282,11 @@ const LyricContext: FC = () => {
282282
let synced = 0;
283283
let errored = 0;
284284

285-
await Promise.all(
286-
shouldFetchList.keys().map(async (fileName: string) => {
285+
const fetchTasks = [];
286+
287+
// Safari 目前不支持对迭代器对象使用 map 方法
288+
for (const fileName of shouldFetchList.keys()) {
289+
fetchTasks.push((async () => {
287290
const lyricRes = await fetch(fileMap[fileName].download_url, {
288291
signal: sig.signal,
289292
redirect: "follow",
@@ -315,8 +318,10 @@ const LyricContext: FC = () => {
315318
console.warn("下载并解析歌词文件", fileName, "失败", err);
316319
errored++;
317320
}
318-
}),
319-
);
321+
})())
322+
}
323+
324+
await Promise.all(fetchTasks);
320325

321326
console.log(
322327
TTML_LOG_TAG,

packages/player/src/pages/playlist/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,8 @@ export const Component: FC = () => {
158158
if (platform() !== "android" && platform() !== "ios") {
159159
normalized = (await path.normalize(v)).replace(/\\/gi, "/");
160160
}
161-
console.log(await stat(v));
162161
try {
162+
console.log(await stat(v));
163163
const pathMd5 = md5(normalized);
164164
const musicInfo = await readLocalMusicMetadata(normalized);
165165

0 commit comments

Comments
 (0)