YouTube 轉錄稿
從 YouTube 影片下載轉錄稿(字幕/隱藏式字幕)。適用於手動建立和自動產生的轉錄稿。無需 API 金鑰或瀏覽器 — 直接使用 YouTube 的 InnerTube API,並在 YouTube 封鎖直接 API 路徑時自動備援至 yt-dlp。
首次執行時會擷取影片中繼資料和封面圖片,並快取原始資料以便快速重新格式化。
腳本目錄
腳本存放在 scripts/ 子目錄中。{baseDir} = 此 SKILL.md 的目錄路徑。解析 ${BUN_X} 執行環境:如果已安裝 bun → bun;如果有 npx → npx -y bun;否則建議安裝 bun。請將 {baseDir} 和 ${BUN_X} 替換為實際值。
| 腳本 | 用途 |
|---|---|
scripts/main.ts | 轉錄稿下載 CLI |
用法
# 預設:附時間戳記的 Markdown(英文)
${BUN_X} {baseDir}/scripts/main.ts <youtube-url-or-id>
# 指定語言(優先順序)
${BUN_X} {baseDir}/scripts/main.ts <url> --languages zh,en,ja
# 不含時間戳記
${BUN_X} {baseDir}/scripts/main.ts <url> --no-timestamps
# 含章節分段
${BUN_X} {baseDir}/scripts/main.ts <url> --chapters
# 含說話者識別(需要 AI 後處理)
${BUN_X} {baseDir}/scripts/main.ts <url> --speakers
# SRT 字幕檔
${BUN_X} {baseDir}/scripts/main.ts <url> --format srt
# 翻譯轉錄稿
${BUN_X} {baseDir}/scripts/main.ts <url> --translate zh-Hans
# 列出可用的轉錄稿
${BUN_X} {baseDir}/scripts/main.ts <url> --list
# 強制重新擷取(忽略快取)
${BUN_X} {baseDir}/scripts/main.ts <url> --refresh
選項
| 選項 | 說明 | 預設值 |
|---|---|---|
<url-or-id> | YouTube 網址或影片 ID(允許多個) | 必要 |
--languages <codes> | 語言代碼,以逗號分隔,依優先順序排列 | en |
--format <fmt> | 輸出格式:text、srt | text |
--translate <code> | 翻譯為指定的語言代碼 | |
--list | 列出可用的轉錄稿,而不進行擷取 | |
--timestamps | 每個段落包含 [HH:MM:SS → HH:MM:SS] 時間戳記 | 開啟 |
--no-timestamps | 停用時間戳記 | |
--chapters | 從影片描述進行章節分段 | |
--speakers | 包含中繼資料的原始轉錄稿,用於說話者識別 | |
--exclude-generated | 跳過自動產生的轉錄稿 | |
--exclude-manually-created | 跳過手動建立的轉錄稿 | |
--refresh | 強制重新擷取,忽略快取資料 | |
-o, --output <path> | 儲存到指定的檔案路徑 | 自動產生 |
--output-dir <dir> | 基礎輸出目錄 | youtube-transcript |
可選的環境變數
| 變數 | 說明 |
|---|---|
YOUTUBE_TRANSCRIPT_COOKIES_FROM_BROWSER | 在備援時傳遞給 yt-dlp --cookies-from-browser,例如 chrome、safari、firefox 或 chrome:Profile 1 |
輸入格式
接受以下任何一種影片輸入:
- 完整網址:
https://www.youtube.com/watch?v=dQw4w9WgXcQ - 短網址:
https://youtu.be/dQw4w9WgXcQ - 嵌入網址:
https://www.youtube.com/embed/dQw4w9WgXcQ - Shorts 網址:
https://www.youtube.com/shorts/dQw4w9WgXcQ - 影片 ID:
dQw4w9WgXcQ
輸出格式
| 格式 | 副檔名 | 說明 |
|---|---|---|
text | .md | Markdown 格式,包含 frontmatter(含 description)、標題、摘要,以及可選的目錄/封面/時間戳記/章節/說話者 |
srt | .srt | 用於影片播放器的 SubRip 字幕格式 |
輸出目錄
youtube-transcript/
├── .index.json # 影片 ID → 目錄路徑對應(用於快取查找)
└── {channel-slug}/{title-full-slug}/
├── meta.json # 影片中繼資料(標題、頻道、描述、長度、章節等)
├── transcript-raw.json # 來自 YouTube API 的原始轉錄稿片段(已快取)
├── transcript-sentences.json # 句子分段的轉錄稿(依標點符號分割,跨片段合併)
├── imgs/
│ └── cover.jpg # 影片縮圖
├── transcript.md # Markdown 轉錄稿(從句子產生)
└── transcript.srt # SRT 字幕(從原始片段產生,若指定 --format srt)
{channel-slug}:頻道名稱,使用 kebab-case{title-full-slug}:完整影片標題,使用 kebab-case
--list 模式僅輸出至 stdout(不儲存檔案)。
快取
首次擷取時,腳本會儲存:
meta.json— 影片中繼資料、章節、封面圖片路徑、語言資訊transcript-raw.json— 來自 YouTube API 的原始轉錄稿片段({ text, start, duration }[])transcript-sentences.json— 句子分段的轉錄稿({ text, start: "HH:mm:ss", end: "HH:mm:ss" }[]),依句子結尾標點符號(.?!…。?!等)分割,時間戳記依字元長度按比例分配,並具備 CJK 文字合併感知能力imgs/cover.jpg— 影片縮圖
同一影片的後續執行會使用快取資料(無網路呼叫)。使用 --refresh 可強制重新擷取。若要求不同語言,快取會自動重新整理。
當 YouTube 在直接 InnerTube 路徑上返回反機器人/封鎖回應時,腳本會以替代的客戶端身分重試,然後在有 yt-dlp 可用時備援至它。如果需要備援但 yt-dlp 不可用,代理應自行決定如何使 yt-dlp 可用並繼續執行,而不是將安裝決策推給使用者。
SRT 輸出(--format srt)是從 transcript-raw.json 產生的。文字/Markdown 輸出則使用 transcript-sentences.json 以獲得自然的句子邊界。
工作流程
當使用者提供 YouTube 網址並想要轉錄稿時:
- 如果使用者尚未指定語言,請先使用
--list執行,以顯示可用選項 - 執行腳本時,請務必使用單引號括住網址 — zsh 會將
?視為 glob 萬用字元,因此未加引號的 YouTube 網址會導致「no matches found」:請使用'https://www.youtube.com/watch?v=ID' - 預設:使用
--chapters --speakers執行以獲得最豐富的輸出(章節 + 說話者識別) - 腳本會自動儲存快取資料 + 輸出檔,並印出檔案路徑
- 對於
--speakers模式:腳本儲存原始檔案後,請依照下方的說話者識別工作流程,使用說話者標籤進行後處理
當使用者只想要封面圖片或中繼資料時,使用任何選項執行腳本也會快取 meta.json 和 imgs/cover.jpg。
當重新格式化同一影片(例如,先取得文字再取得 SRT)時,快取資料會被重複使用 — 無需重新擷取。
章節與說話者工作流程
章節(--chapters)
腳本會從影片描述中解析章節時間戳記(例如 0:00 介紹),根據章節邊界將轉錄稿分段,將片段分組為易讀的段落,並儲存為附有目錄的 .md 檔案。無需進一步處理。
如果描述中不存在章節時間戳記,轉錄稿將以分組段落輸出,不含章節標題。
說話者識別(--speakers)
說話者識別需要 AI 處理。腳本會輸出一個原始的 .md 檔案,包含:
- 包含影片中繼資料的 YAML frontmatter(標題、頻道、日期、封面、描述、語言)
- 影片描述(用於提取說話者名稱)
- 來自描述的章節列表(如果有)
- SRT 格式的原始轉錄稿(預先計算的開始/結束時間戳記,節省 token)
腳本儲存原始檔案後,生成一個子代理(為了成本效益,使用較便宜的模型,如 Sonnet)來處理說話者識別:
- 讀取已儲存的
.md檔案 - 讀取位於
{baseDir}/prompts/speaker-transcript.md的提示模板 - 依照提示處理原始轉錄稿:
- 使用影片中繼資料識別說話者(標題 → 來賓,頻道 → 主持人,描述 → 名稱)
- 從對話流程、問答模式和上下文線索中偵測說話者輪次
- 分段為章節(若有描述中的章節則使用,否則從主題變化中建立)
- 使用
**說話者名稱:**標籤、段落分組(2-4 個句子)和[HH:MM:SS → HH:MM:SS]時間戳記進行格式化
- 用處理後的轉錄稿覆寫
.md檔案(保留 YAML frontmatter)
使用 --speakers 時,會隱含 --chapters — 處理後的輸出始終包含章節分段。
錯誤情況
| 錯誤 | 說明 |
|---|---|
| 轉錄稿已停用 | 影片完全沒有字幕 |
| 找不到轉錄稿 | 請求的語言不可用 |
| 影片無法使用 | 影片已刪除、私人或受地區限制 |
| IP 被封鎖 | 請求過多,請稍後再試 |
| 年齡限制 | 影片需要登入以進行年齡驗證 |
| 偵測到機器人 | 腳本重試替代客戶端,然後使用 yt-dlp;如果備援工具缺失,代理應自行解決該問題;若仍然失敗,請嘗試 YOUTUBE_TRANSCRIPT_COOKIES_FROM_BROWSER=safari(或您的瀏覽器) |


