Skip to content

feat(lyric): implement precise pinyin filtering using xml:lang for TTML#970

Open
kid141252010 wants to merge 2 commits intoimsyy:devfrom
kid141252010:feat/ttml-pinyin-filter
Open

feat(lyric): implement precise pinyin filtering using xml:lang for TTML#970
kid141252010 wants to merge 2 commits intoimsyy:devfrom
kid141252010:feat/ttml-pinyin-filter

Conversation

@kid141252010
Copy link

Description

基于标准 TTML 语言标签实现的“拒绝胎教”模式增强。

主要改动:

  • 精确过滤: 不再依赖脆弱的正则声调检测,而是直接在 TTML XML 层级针对 xml:lang="zh-Hans-Latn" 的音译标签进行过滤。
  • 零误伤: 确保日语罗马音、英语音标等非汉语拼音音译在开启“拒绝胎教”模式时依然能正常显示。
  • 优先级修复: 修复了在近期上游重构后导致的部分 TTML 翻译优先级判定失效的问题。

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

此拉取请求旨在增强 TTML 歌词的“拒绝胎教”模式,通过利用 TTML XML 结构中的 xml:lang 属性,实现对汉语拼音音译的精确识别和过滤。这一改进避免了以往基于正则表达式可能出现的误判,同时修复了翻译优先级的问题,从而提供更准确、无干扰的歌词显示体验。

Highlights

  • 精确拼音过滤: 使用 xml:lang="zh-Hans-Latn" 标签对 TTML 中的拼音进行精确过滤,取代了原有的正则声调检测。
  • 避免误伤: 确保日语罗马音、英语音标等非汉语拼音的音译在“拒绝胎教”模式下能正常显示。
  • 修复优先级: 解决了近期上游重构导致的 TTML 翻译优先级判断失效问题。
Changelog
  • .gitignore
    • 新增了对构建时自动生成文件(如 *.tsbuildinfo, auto-imports.d.ts)的忽略规则。
    • 新增了对 .vscode 目录下的部分文件(除特定配置文件外)的忽略规则。
    • 新增了对本地环境变量文件(如 .env.local)的忽略规则。
  • src/core/player/LyricManager.ts
    • 在处理歌词数据时,添加了一条注释,明确指出汉语拼音音译已在 cleanTTMLTranslations 函数中基于 xml:lang 声明被精确剔除。
  • src/utils/lyric/parseTTML.ts
    • 新增了无条件剔除繁体替换翻译段落 () 的逻辑。
    • 新增了无条件剔除语言声明为汉语拼音的音译 标签 () 的逻辑,以支持“拒绝胎教”模式。
    • 修改了 langCounter 函数,使其仅提取 translation 标签的语言属性,避免对 span 标签进行匹配。
    • 调整了 replacer 函数,不再清理 span 标签,以保留原始词汇和非拼音音译内容。
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

本次 Pull Request 通过利用 xml:lang 属性,为 TTML 歌词实现了更精确的拼音过滤机制,替代了之前脆弱的声调正则表达式检测,这是一个很好的改进。同时,此变更还修复了翻译优先级判定的问题。代码改动与目标一致,整体实现良好。我主要有一个建议,即在 src/utils/lyric/parseTTML.ts 中使用正则表达式来解析 TTML 内容。虽然目前的实现很巧妙,但正则表达式处理 XML/HTML 格式的字符串通常不够健壮。我建议重构此部分代码,改用标准的 DOMParser API,以提高代码的鲁棒性和长期可维护性。

Comment on lines +200 to +209
// 无条件剔除繁体替换翻译段 <translation type="replacement" xml:lang="zh-Hant*">
ttmlContent = ttmlContent.replace(
/<translation(?=[^>]*type="replacement")(?=[^>]*xml:lang="zh-Hant[^"]*")[^>]*>[\s\S]*?<\/translation>/g,
"",
);
// 无条件剔除音译类型且语言声明为汉语拼音的 span (拒绝胎教 Mode)
ttmlContent = ttmlContent.replace(
/<span(?=[^>]*ttm:role="x-roman")(?=[^>]*xml:lang="zh-Hans-Latn")[^>]*>[\s\S]*?<\/span>/g,
"",
);
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

虽然使用正则表达式处理 XML 字符串在特定场景下性能较好,但这种方法通常比较脆弱,并且难以维护。当 TTML 结构稍微复杂或属性顺序、格式有变动时,正则表达式可能会失效或产生意想不到的结果。

为了提高代码的健壮性和可读性,建议使用标准的 DOM 解析器(如 DOMParser)来处理 TTML 内容。通过操作 DOM 树来移除或修改节点,可以更安全、更清晰地实现过滤逻辑,避免潜在的解析错误。

例如,可以这样重构:

const parser = new DOMParser();
const xmlDoc = parser.parseFromString(ttmlContent, "application/xml");

// 无条件剔除繁体替换翻译段
const hantTranslations = xmlDoc.querySelectorAll('translation[type=\"replacement\"][xml\\:lang^=\"zh-Hant\"]');
hantTranslations.forEach(node => node.remove());

// 无条件剔除汉语拼音音译
const pinyinSpans = xmlDoc.querySelectorAll('span[ttm\\:role=\"x-roman\"][xml\\:lang=\"zh-Hans-Latn\"]');
pinyinSpans.forEach(node => node.remove());

// ... 其他逻辑也可以在 DOM 上操作 ...

const serializer = new XMLSerializer();
ttmlContent = serializer.serializeToString(xmlDoc);

考虑到函数内其他部分也使用了正则表达式,这可能需要对整个函数进行重构。如果这是一个有意的性能优化,可以添加注释说明。否则,为了长期的可维护性,迁移到 DOM 解析器是更优的选择。

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.

1 participant