指南

用词级时间戳制作泰语字幕

泰语句子没有可以切分字幕的空格,词级时间戳如何为每条字幕给出切分点,泰语字幕文件需要哪些规则,以及应当请求哪种书写格式。

· 阅读约 1 分钟

字幕就是把转写文本切成一段段,每段在说出的那几秒里显示,长度要放得进屏幕。英语切起来很容易。字幕条在空格处结束,一个对语言一无所知的工具也能切出可读的行。泰语却把整个短语写成一串连续的字符。按字符数切分的工具会从词的中间切开,观众在一行里读到半个词,两秒后才在下一行读到另一半。

泰语字幕条可以直接用 Paxa STT Lite 返回的词级时间戳来构建。每个时间区间都是一个完整的泰语词,带有开始和结束时间,这些位置恰好就是字幕条所有可以切分的地方。把区间转换成字幕条的规则一页就能写完,得到的是任何播放器都能读取的字幕文件。

什么是时间区间#

将 timestamps 设为 "word",响应就会在转写文本旁附带一个 words 数组。每一项是一个词,以及它以秒为单位的开始和结束时间。泰语的词在输出前已经切分好。一个区间总是覆盖完整的词,不会停在某个字符上。所有区间按顺序拼接,就能还原转写文本,一个字符也不少。

curl
AUDIO=$(base64 < meeting.m4a | tr -d '\n')
curl -X POST https://api.paxalabs.com/v1/stt \
  --max-time 300 \
  -H "Authorization: Bearer $PAXA_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"audio\": \"$AUDIO\", \"model\": \"paxa-stt-lite-v1-preview\", \"timestamps\": \"word\"}"
Response
{
  "text": "สวัสดีค่ะคุณสมชายยอดชำระของท่านจำนวน พันสองร้อยห้าสิบ บาทครบกำหนดวันที่ สิบห้า สิงหาคมนี้ชำระผ่านแอปได้ตลอด ยี่สิบสี่ ชั่วโมงค่ะ",
  "words": [
    {
      "text": "สวัสดี",
      "start": 0.12,
      "end": 0.44
    },
    {
      "text": "ค่ะ",
      "start": 0.52,
      "end": 0.66
    },
    {
      "text": "คุณ",
      "start": 1.08,
      "end": 1.24
    },
    {
      "text": "สมชาย",
      "start": 1.32,
      "end": 1.88
    },
    {
      "text": "ยอด",
      "start": 2.36,
      "end": 2.56
    },
    {
      "text": "ชำระ",
      "start": 2.6,
      "end": 2.879
    },
    {
      "text": "ของ",
      "start": 3,
      "end": 3.14
    },
    {
      "text": "ท่าน",
      "start": 3.2,
      "end": 3.359
    },
    {
      "text": "จำนวน",
      "start": 3.48,
      "end": 3.879
    },
    {
      "text": "พันสองร้อยห้าสิบ",
      "start": 4.24,
      "end": 5.4
    },
    {
      "text": "บาท",
      "start": 5.56,
      "end": 5.759
    },
    {
      "text": "ครบ",
      "start": 6.32,
      "end": 6.52
    },
    {
      "text": "กำหนด",
      "start": 6.56,
      "end": 6.84
    },
    {
      "text": "วัน",
      "start": 6.92,
      "end": 7.039
    },
    {
      "text": "ที่",
      "start": 7.04,
      "end": 7.119
    },
    {
      "text": "สิบห้า",
      "start": 7.24,
      "end": 7.48
    },
    {
      "text": "สิงหาคม",
      "start": 7.68,
      "end": 8.26
    },
    {
      "text": "นี้",
      "start": 8.36,
      "end": 8.5
    },
    {
      "text": "ชำระ",
      "start": 9.08,
      "end": 9.36
    },
    {
      "text": "ผ่าน",
      "start": 9.48,
      "end": 9.68
    },
    {
      "text": "แอป",
      "start": 9.76,
      "end": 9.92
    },
    {
      "text": "ได้",
      "start": 10,
      "end": 10.14
    },
    {
      "text": "ตลอด",
      "start": 10.2,
      "end": 10.46
    },
    {
      "text": "ยี่สิบสี่",
      "start": 10.56,
      "end": 10.96
    },
    {
      "text": "ชั่วโมง",
      "start": 11.08,
      "end": 11.4
    },
    {
      "text": "ค่ะ",
      "start": 11.52,
      "end": 11.66
    }
  ],
  "usage": {
    "seconds": 11.952,
    "credits": 1.66
  }
}

把区间切成字幕条#

按顺序遍历区间,把它们收进当前字幕条,直到触及以下三个限制之一。这时字幕条在最后一个区间的结束时间结束,下一条从下一个区间的开始时间开始。

  • 长度。泰语一行在三十五个字符左右读起来比较舒服,一条字幕最多两行。统计已收进的词的字符数,在会让长度超限的那个词之前切分。
  • 时长。一条字幕在屏幕上停留超过约六秒,看起来就像卡住了。只要下一个词会让字幕条超过时长限制就切分,即使这一行还有空间。
  • 停顿。前一个区间结束到下一个区间开始之间的间隔超过约半秒,就是一次换气或一句话的结束。在这里切分,字幕条会随说话人一起停下。

在停顿处结束的字幕条,比按字数截断的读起来更顺。为了切在停顿处,稍微超出长度限制也值得。如果一条字幕有两行,就在条内区间之间最宽的间隔处换行,那里通常是短语的边界。

一句话,两条字幕
words
  วันนี้      0.00  0.38
  เรา         0.38  0.55
  จะ          0.55  0.70
  คุย         0.70  0.98
  เรื่อง      0.98  1.30
  งบประมาณ    1.30  1.92
  ปีหน้า      1.92  2.40
  กัน         2.40  2.61
  นะครับ      2.61  3.05

cues
  1  00:00:00,000 --> 00:00:01,300
     วันนี้เราจะคุยเรื่อง
  2  00:00:01,300 --> 00:00:03,050
     งบประมาณปีหน้ากันนะครับ

应当请求的书写格式#

字幕需要口语体,也就是默认格式。观众听到 สองพันสามร้อยห้าสิบบาท,读到的也是同样的词。说话人念出七个音节时,屏幕上却是一串数字,读起来就对不上。用书面体构建的字幕条还会丢失数字内部的区间边界,因为这些数字是作为一个词元返回的。

出于同样的原因,请保留逐字风格。观众听到说话人说错重来,读到的却是整理过的句子,会察觉到差别。精简风格适合脱离音频单独阅读的转写文本。

写入文件#

SRT 为每条字幕编号,把开始和结束时间写成时、分、秒和毫秒,毫秒前用逗号,后面跟上文本。WebVTT 与之相同,只是毫秒前用句点,并多一行文件头。两者都是纯文本,都以 UTF-8 保存泰语,无需额外设置。把区间里的秒数保留三位小数写进去,文件就完成了。

要制作翻译字幕轨,就把每条字幕的文本作为一个分段发给翻译 API,并让 id 随结果原样返回。时间信息跟着 id 走。泰语视频由此得到一条切分点相同的英语字幕轨,两条字幕轨保持对齐。

下一步#

继续阅读

更多指南