TTML 从入门到入土

一、入门篇:TTML 基础与 AMLL Editor 快速上手

1.1 什么是 TTML?

TTML(Timed Text Markup Language)是 W3C 定义的时序文本标记语言标准。Apple Music 使用 TTML 作为逐字歌词格式,因此 AMLL 生态也主要采用 TTML 为歌词存储与交换格式。

TTML 的核心能力

  • 逐字时间轴(Word-level timing)
  • 对唱/多人演唱者信息(ttm:agent
  • 背景人声(x-bg
  • 翻译与音译(x-translation / x-roman
  • 歌曲分段(itunes:song-part
  • Ruby 注音(日语振假名、拼音等)

1.2 TTML 文件的最小结构

<tt xmlns="http://www.w3.org/ns/ttml"
    xmlns:ttm="http://www.w3.org/ns/ttml#metadata"
    xmlns:itunes="http://music.apple.com/lyric-ttml-internal"
    xmlns:amll="http://www.example.com/ns/amll">
  <head>
    <metadata>
      <!-- 定义演唱者 -->
      <ttm:agent type="person" xml:id="v1"/>
      <ttm:agent type="other" xml:id="v2"/>
    </metadata>
  </head>
  <body dur="03:12.915">
    <div begin="00:02.207" end="03:12.915">
      <p begin="00:02.207" end="00:06.042" ttm:agent="v1" itunes:key="L1">
        <span begin="00:02.207" end="00:02.967">紧</span>
        <span begin="00:02.967" end="00:03.845">握</span>
        <!-- ... -->
      </p>
    </div>
  </body>
</tt>

关键要素

元素 作用
<tt> 根节点,声明所有命名空间
<head><metadata> 元数据区,定义演唱者(agent)
<body> 歌词主体容器,dur 属性标注歌曲总时长
<div> 段落容器,可用 itunes:song-part 标记主歌/副歌
<p> 每一行歌词,带 begin/end 时间码,ttm:agent 指定演唱者
<span> 每一个字/词,带独立的 begin/end 时间码

命名空间说明

  • xmlns="http://www.w3.org/ns/ttml" — TTML 标准
  • xmlns:ttm="http://www.w3.org/ns/ttml#metadata" — 元数据(agent、role)
  • xmlns:itunes="http://music.apple.com/lyric-ttml-internal" — Apple 扩展(song-part、key)
  • xmlns:amll="http://www.example.com/ns/amll" — AMLL 扩展元数据

时间格式

  • 时钟格式:MM:SS.fffHH:MM:SS.fff(小数点后可保留 1~3 位)
  • 秒值格式:12.3s

1.3 AMLL Editor 入门操作

AMLL 生态提供两个编辑器:

工具 技术栈 地址 特点
AMLL TTML Tool React https://tool.amll.dev/ 稳定版,功能完整
AMLL Editor Vue https://editor.amll.dev/ 下一代,早期开发,支持查找替换等便利功能

基本工作流

  1. 导入歌曲与歌词:在编辑器中加载音频文件和纯文本歌词
  2. 一键分词:工具自动将歌词拆解为逐字/逐词结构
  3. 打轴(时间标记) :使用快捷键逐字标记时间轴
    • F — 标记该行起始时间
    • G — 标记每个字的起始时间(逐字打轴)
    • H — 标记长空白停顿处
  4. 配置行属性:标记该行是主唱(v1)、对唱(v2)还是背景和声(x-bg)
  5. 导出 TTML:生成标准的 .ttml 文件

1.4 最简 TTML 模板(可直接复制使用)

<tt xmlns="http://www.w3.org/ns/ttml"
    xmlns:ttm="http://www.w3.org/ns/ttml#metadata"
    xmlns:itunes="http://music.apple.com/lyric-ttml-internal"
    xmlns:amll="http://www.example.com/ns/amll">
  <head>
    <metadata>
      <ttm:agent type="person" xml:id="v1"/>
    </metadata>
  </head>
  <body dur="00:30.000">
    <div begin="00:00.000" end="00:30.000">
      <p begin="00:00.000" end="00:05.000" ttm:agent="v1" itunes:key="L1">
        <span begin="00:00.000" end="00:00.500">你</span>
        <span begin="00:00.500" end="00:01.000">好</span>
        <span begin="00:01.000" end="00:01.500">世</span>
        <span begin="00:01.500" end="00:02.000">界</span>
      </p>
    </div>
  </body>
</tt>

二、进阶篇:时间轴特效与高级技法

以下技法均来自你之前分析的实际歌词文件,是“用时间轴画画”的核心手段。

2.1 多演唱者(对唱/二重唱):ttm:agent

<head><metadata> 中定义多个 agent:

<ttm:agent type="person" xml:id="v1"/>  <!-- 主唱 -->
<ttm:agent type="person" xml:id="v2"/>  <!-- 对唱 -->

<p><span> 中通过 ttm:agent 指定演唱者:

<!-- V1 主唱 -->
<p begin="00:19.919" end="00:22.713" ttm:agent="v1" itunes:key="L7">
  <span begin="00:19.919" end="00:20.054">幸</span>
  <span begin="00:20.054" end="00:20.313">福</span>
</p>
<!-- V2 对唱 -->
<p begin="00:22.974" end="00:25.708" ttm:agent="v2" itunes:key="L8">
  <span begin="00:22.974" end="00:23.070">是</span>
  <span begin="00:23.070" end="00:23.323">否</span>
</p>

渲染效果:不同 agent 的歌词行在播放器中以不同颜色显示(如 V1 亮白、V2 淡蓝),实现“声部可视化”。

2.2 背景和声:ttm:role="x-bg"

<span> 中嵌套 ttm:role="x-bg" 标记背景人声/和声:

<p begin="00:09.581" end="00:10.294" ttm:agent="v1" itunes:key="L4">
  <span begin="00:09.581" end="00:09.914">怯</span>
  <span begin="00:09.914" end="00:10.294">懦</span>
  <!-- 背景和声:与主唱时间重叠,独立起止 -->
  <span ttm:role="x-bg" begin="00:10.059" end="00:13.206">
    <span begin="00:10.059" end="00:11.565">Ahhh</span>
    <span begin="00:11.885" end="00:13.206">Ahhh</span>
  </span>
</p>

关键点:背景和声的 begin/end 可以与主唱歌词完全重叠甚至超出,播放器会将其渲染为更小字号、更低透明度的副歌层。

2.3 翻译与音译:ttm:role="x-translation" / x-roman

在行内嵌入翻译或音译文本:

<p begin="00:11.460" end="00:13.770" ttm:agent="v1" itunes:key="L1">
  <span begin="00:11.460" end="00:11.700">Hello</span>
  <span ttm:role="x-translation" xml:lang="zh-CN">你好</span>
</p>

2.4 时间轴高级技法(“用时间轴画画”)

技法一:占位拍(Sustain Hold / 长尾占位)

定义:给某个字符分配远超实际发音时长的时间跨度,让这个字“霸占”屏幕直到下一个强拍到来。

实现方式:将某个 <span>end 时间大幅延长

<!-- “睡”字从 00:58.481 一直拖到 01:00.079,长达 1.6 秒 -->
<p begin="00:55.638" end="01:00.079" ttm:agent="v1" itunes:key="L31">
  <span begin="00:58.137" end="00:58.481">沉</span>
  <span begin="00:58.481" end="01:00.079">睡</span>  <!-- 占位拍! -->
</p>

效果:视觉上这个字“钉”在屏幕上,对应歌手的长高音尾音颤音,填补主唱换气时的情绪空白。

技法二:幽灵字 / 零时长陷阱(Zero-Duration Ghost)

定义:将某个 <span>beginend 都设为 00:00.000,让该字在渲染时被跳过(“吞字”效果)。

实现方式

<p begin="01:59.098" end="01:59.221" ttm:agent="v1" itunes:key="L54">
  <span begin="01:59.098" end="01:59.177">繁</span>
  <span begin="00:00.000" end="00:00.000">茂</span>  <!-- 幽灵字!被渲染器跳过 -->
</p>

效果:观众只看到“繁”,紧接着下一句以“繁碌”开头,制造出“词穷而意转”的撕裂感和抢拍效果。

⚠️ 注意:在留声机(Gramophone)中,零时长 span 会被直接跳过不渲染;在 Flamingo 中可能闪一下半透明状态。

技法三:抢拍 / 提前进入(Snap Beat / Negative Gap)

定义:下一句第一个字的 begin 时间早于上一句最后一个字的 end 时间(时间轴重叠)。

实现方式

<!-- L13 背景和声拖到 00:36.418 -->
<p begin="00:33.200" end="00:35.964" ...>
  <span ttm:role="x-bg" begin="00:33.939" end="00:36.418">(言说 描摹 定夺)</span>
</p>
<!-- L14 “盛”在 00:36.248 就开始了,重叠了 170ms -->
<p begin="00:36.248" end="00:36.748" ...>
  <span begin="00:36.248" end="00:36.279">盛</span>
</p>

效果:字幕还没结束,下一句的字就“冲”出来了,制造急切、逼迫感。

技法四:负间隙呼吸(Negative Gap)

定义:前后两句之间故意留出 200ms 以上的时间真空(没有高亮字)。

实现方式

<p begin="00:07.134" end="00:08.531" ...>法</p>
<!-- 420ms 的空白 -->
<p begin="00:08.951" end="00:09.236" ...>和</p>

效果:屏幕突然“黑”了一下,对应歌手的深呼吸/换气口

技法五:双轨叠录(Dual-Track Overlay)

定义:V1 和 V2 在同一时间段内完全重叠,各自拥有独立的时间轴。

实现方式

<!-- V1 在唱 -->
<p begin="02:28.065" end="02:30.832" ttm:agent="v1" itunes:key="L62">
  <span begin="02:28.065" end="02:28.188">我</span>
  <span begin="02:28.188" end="02:28.419">写</span>
  <!-- ... -->
</p>
<!-- V2 几乎同时也在唱(仅差 7ms) -->
<p begin="02:28.058" end="02:30.878" ttm:agent="v2" itunes:key="L66">
  <span begin="02:28.058" end="02:28.061">再</span>
  <span begin="02:28.061" end="02:28.110">次</span>
  <!-- ... -->
</p>

⚠️ 这是渲染极限测试

  • 留声机:V1 和 V2 因 agent 不同而独立渲染,但性能开销瞬间拉满
  • Flamingo:模糊过渡被放大,形成迷幻叠影效果,但边界精度下降

2.5 AMLL Editor 中实现进阶特效的操作指南

特效 在 AMLL Editor 中的操作
多演唱者 在元数据侧边栏添加多个 agent,每行歌词选择对应的 ttm:agent
背景和声 在歌词行行为设置中勾选“背景歌词”(x-bg)
占位拍 手动拖拽该字的结束时间点,向后延长
幽灵字 将该字的 beginend 都设为 00:00.000(需手动编辑或利用零时长快捷键)
抢拍/重叠 拖拽下一句第一个字的开始时间点,使其早于上一句的结束时间
双轨叠录 创建两个独立行,分别赋予 v1 和 v2,让它们的时间轴完全重叠

2.6 开发工作流建议(基于你的实践验证)

阶段 工具 任务 原因
精修时间轴(Debug) 留声机(Gramophone) 抓虫、规范语法 对时间轴重叠/零时长极其敏感,会直接跳过或报错,倒逼语法规范
最终展示(Polish) Flamingo 视觉呈现 内置缓动函数和模糊过渡,让干净的时间轴产生高级的呼吸感

三、参考资源

posted @ 2026-08-24 14:31  Labyrinth_in_Kowloon  阅读(59)  评论(0)    收藏  举报