问答

怎么拿到指定语言的 YouTube 字幕?

简短回答

调用 YouTube 视频字幕接口时传 lang(比如 en、es),视频有这种语言的字幕轨就返回它,返回结果里带一个 lang 字段,入库前可以先核对。每份字幕 $0.004,所以先看 lang 再决定要不要重查;视频只有别的语言时,自己翻译分段即可。

假设你在帮一个美国食品品牌盯 50 个西班牙语美食频道,团队只看英文。这些视频里有一部分带英文字幕轨,大多数只有西语。你想要的是:YouTube 有英文就拿英文,没有的给个明确标记,而且每个视频只付一次钱。

怎么指定语言

YouTube 视频字幕传 id(11 位视频 ID),另外可以传 lang,填 en、es、ja 这样的语言代码。lang 是偏好,不是保证。一个视频有哪些字幕轨,由作者和 YouTube 决定,所以返回的字幕自带一个 lang。每次入库前都看一眼它,再决定这段文字归到哪种语言下。

每个视频只付一次的写法

import os, requests

API = "https://api.okdata.online/v1/youtube/videos/transcript/get"
H = {"Authorization": f"Bearer {os.environ['OKDATA_API_KEY']}"}

def transcript(video_id, want="en"):
    body = requests.get(API, headers=H, params={"id": video_id, "lang": want}, timeout=60).json()
    if body["code"] == "not_found":
        return None                      # 完全没有字幕,不扣费
    if body["code"] != "ok":
        raise RuntimeError(f"{body['code']}: {body['message']}")
    t = body["data"]["item"]
    t["needs_translation"] = t["lang"].split("-")[0] != want
    return t

t = transcript("VIDEO_ID", want="en")
if t and t["needs_translation"]:
    print("拿到", t["lang"], ",需要翻译", len(t["segments"]), "段")

翻译时按分段逐段翻,别整段 text 一起翻,这样 start、end 时间还能继续用来引用原话和做字幕。

费用

方案 调用次数 费用
50 个视频,每个请求一种语言 50 $0.20
同样 50 个视频,每个再多要一种语言 100 $0.40
1,000 个视频 1000 $4.00

只要返回了字幕就计费,哪怕返回的语言和你要的不一样。所以上面的代码只问一次,剩下的在本地翻译,而不是挨个语言代码试过去。

容易踩的坑

  • 比较语言时只看主代码,en-US 和 en 对大多数用途来说是同一种语言。
  • 视频有多条字幕轨时,lang 标注的有可能是视频列出的第一条字幕轨,而不是你实际拿到的那条。语言会影响后续处理的话,抽几段文字用语言检测库再核对一遍。
  • 返回结果不标明字幕是作者上传的还是自动生成的。
  • 没有字幕的视频返回 not_found,不扣费;这里没有语音转文字。
  • 从 youtube-transcript-api 迁过来的话:它的 find_transcript 要传语言代码列表,有些视频取翻译字幕会失败。这里只传一个代码,回来再比对。

其他做法

  • 自己的频道,可以在 YouTube Studio 或官方 Data API 里添加、下载任意语言的字幕轨。
  • 只看几个视频的话,YouTube 播放器的自动翻译字幕给人看就够了,免费。
  • 对译文质量要求高的,找人工翻译字幕全文,效果比任何自动字幕都好。

更多批量取字幕的做法见视频转文字方案。

更新于