| 1072 | |
| 1073 | for (const line of lines) { |
| 1074 | // 跳过注释行 |
| 1075 | if (line.startsWith("#")) continue; |
| 1076 | |
| 1077 | // 检测是否是 Netscape 格式(包含多个空格分隔的字段) |
| 1078 | const fields = line.split(/\s+/); |
| 1079 | if (fields.length === 7) { |
| 1080 | // 这是空格分隔的 Netscape 格式,转换为制表符分隔 |
| 1081 | fixedLines.push(fields.join("\t")); |
| 1082 | continue; |
| 1083 | } |
| 1084 | } |
| 1085 | |
| 1086 | // 如果成功转换了至少一个 cookie 条目,返回修复后的结果 |
| 1087 | if (fixedLines.length > 2) { |
| 1088 | return fixedLines.join("\n"); |
| 1089 | } |
| 1090 | |
| 1091 | // 3. 否则,尝试从 key=value 格式转换 |
| 1092 | const resultLines = ["# Netscape HTTP Cookie File", ""]; |
| 1093 | const pairs = cookie.split(/;\s*/).filter((p) => p.includes("=")); |
| 1094 | |
| 1095 | for (const pair of pairs) { |
| 1096 | const [name, value] = pair.split("="); |
| 1097 | if (name && value) { |
| 1098 | // YouTube cookie defaults |
| 1099 | resultLines.push( |
| 1100 | `.youtube.com\tTRUE\t/\tTRUE\t${ |
| 1101 | Math.floor(Date.now() / 1000) + 31536000 |
| 1102 | }\t${name.trim()}\t${value.trim()}` |
| 1103 | ); |
| 1104 | } |
| 1105 | } |
| 1106 | |
| 1107 | return resultLines.join("\n"); |
| 1108 | } |
| 1109 | |
| 1110 | // 使用 gdstudio 音乐 API 获取专辑封面,保存到 destPath |
| 1111 | // 元数据优先使用 AI 解析结果(artist/title/album) |
| 1112 | private async fetchAlbumCoverUsingAPI( |
| 1113 | metadata: SongInfo | undefined, |
| 1114 | destPath: string |
| 1115 | ): Promise<boolean> { |
| 1116 | try { |
| 1117 | if (!metadata || !metadata.title) return false; |
| 1118 | const COVER_SOURCES = [ |
| 1119 | "tencent", |
| 1120 | "kuwo", |
| 1121 | "kugou", |
| 1122 | "migu", |