Skip to content

feat: 将 AMLL 格式歌词自动转换为安卓端 Apple Music 可正常解析的格式 - #37

Merged
Zennmn merged 12 commits into
Zennmn:mainfrom
ITManCHINA:feat/ttml-convert-amll-to-am-format
Aug 9, 2026
Merged

feat: 将 AMLL 格式歌词自动转换为安卓端 Apple Music 可正常解析的格式#37
Zennmn merged 12 commits into
Zennmn:mainfrom
ITManCHINA:feat/ttml-convert-amll-to-am-format

Conversation

@ITManCHINA

@ITManCHINA ITManCHINA commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Note

以下内容由 Claude 进行总结。


改动内容

新增 AmllTtmlFormatConverter

app/src/main/java/dev/amenhancer/module/lyrics/AmllTtmlFormatConverter.kt,无新增依赖。

轨道迁移:把内联的翻译 / 音译 span 收拢到头部 <iTunesMetadata><translations> / <transliterations> 中,通过 itunes:key 与歌词行关联,body 只留歌词。<text> 原样承载来源 span 的内容,逐行轨道保持纯文本,逐词轨道保留带时间戳的 <span>

空洞补齐:安卓 Apple Music 是按顺序遍历 entry 而非解析 for 属性,轨道中缺一行会让后续所有条目整体错位,有空洞的轨道会被直接丢弃。因此写出的轨道会列出每一个带 key 的行,源文件未翻译的行填入单个空格占位;完全没有内容的轨道则整条省略,而不是写成一列空格。

背景人声x-bg 内的辅助 span 并入同一个 <text>,用 x-bg span 包裹并加圆括号(已有括号不会重复包)。留在 body 里的背景 span 去掉 begin / end(Apple 从其音节自行推断区间),起始时间早于主歌词首音节时移到行首(Apple 按文档顺序放置高亮)。

根节点与命名空间:移除 xmlns="";根节点补 itunes:timing(body 有逐词时间戳则 Word,否则 Line)。语言标签为固定值而非沿用来源——安卓端解析器只有在歌词语言为韩语时才会同时渲染翻译和音译,因此根节点标记 ko、翻译 zh-Hans、音译 ko-Latn;受此限制每种轨道只能存活一条,故每行取第一条翻译和第一条音译。

混合格式:文件可能一半一半——头部已有 Apple 格式的逐词音译,翻译却仍是 AMLL 内联 span(AMLL 对音译来自 Apple 的歌曲就是这么给的)。两种轨道各自判断:头部已声明的种类保留其内联 span 不再迁移(否则会重复),只有头部缺失的种类才迁移,并按 Apple 的顺序插到已有轨道之前。

实现方式:刻意采用文本改写而非 DOM 往返——<span> 标签之间的空白承载着分词信息,DOM 序列化会丢失。内部是一个最小化的 XML 扫描器,只检查标记,歌词文本节点、注释、CDATA、处理指令原样复制。转换幂等,已是 Apple 格式的文档原样返回。

接入导入流程

  • CustomLyricsOnlineImporter.importAmll 在取回 TTML 后先转换再走 TtmlInputPolicy 校验,Imported 新增 reformatted 标志。
  • SettingsActivity 在发生转换时提示「已导入 AMLL 歌词,已自动转为 Apple Music 格式,请确认后保存」。
  • 转换只作用于用户主动触发的 AMLL 在线导入,播放期的 hook 路径不受影响。
  • README 补充一句说明。

版本号

versionCode 99 → 100,versionName 1.4.2 → 1.4.3(区间内含 release: AM++ 1.4.3)。

测试

新增 33 个单元测试:AmllTtmlFormatConverterTest 31 个,CustomLyricsOnlineImporterTest 2 个。覆盖轨道迁移、逐词时间戳保留、背景人声的三种改写、占位空格、空 span 视为无翻译、每种轨道取第一条、命名空间清理、空白保留、注释 / CDATA 原样、混合格式的四种情形、幂等性、畸形与空输入不抛异常,以及转换结果仍满足 TtmlInputPolicy

./gradlew :app:testDebugUnitTest 全部通过。

另用一份真实的混合格式文件(87 行,头部 Apple 逐词音译 + AMLL 内联翻译)验证:87 行全部生成 <text>,body 内联翻译清零,8 条背景翻译带括号进入 x-bg,原音译轨道未被改动或复制,根节点补上 xml:lang="ko",重复转换结果一致。


歌词格式差异

AMLL 格式 Apple Music 格式
amll-format am-format

@Zennmn

Zennmn commented Aug 9, 2026

Copy link
Copy Markdown
Owner

@codex

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7aa5d11a46

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread app/src/main/java/dev/amenhancer/module/lyrics/AmllTtmlFormatConverter.kt Outdated
Comment thread app/src/main/java/dev/amenhancer/module/lyrics/AmllTtmlFormatConverter.kt Outdated
@Zennmn

Zennmn commented Aug 9, 2026

Copy link
Copy Markdown
Owner

@codex

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

Reviewed commit: 38933f2dcb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@Zennmn
Zennmn merged commit cc4fbd7 into Zennmn:main Aug 9, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants