ホーム / 全スキル / コンテンツ制作 / baoyu-youtube-transcript
コンテンツ制作 · JimLiu/baoyu-skills

baoyu-youtube-transcript

URLまたは動画IDからYouTube動画の文字起こし/字幕およびカバー画像をダウンロードします。多言語、翻訳、チャプター、話者識別の機能を備えています。高速な再フォーマット用に元データをキャッシュします。ユーザーが「YouTubeの文字起こしを取得」「字幕をダウンロード」「キャプションを取得」「YouTube字幕」「YouTube封面」「视频封面」「動画サムネイル」「動画カバー画像」と要求した場合、またはYouTube URLを提供して文字起こし/字幕テキストやカバー画像の抽出を希望した場合に使用します。

L5 厳格管理 · 隔離環境と厳格な監査V2 人間監査済リバースAPI認証情報/セッションコマンド実行ネットワーク通信ファイル書き込みDual-pass Audit
Author JimLiuGitHub JimLiu/baoyu-skills ↗Stars 25926License MIT(仓库根 LICENSE:Copyright (c) 2026 Jim Liu;根 package.json 同声明 "license": "MIT")Commit 1567581c26
管理レベルは Skill の能力と推奨統制措置を示すものであり、品質や安全性の認証、利用可否の判定ではありません。使用の可否はユーザーおよび管理者が決定します。Agent 環境によって制約が異なるため、自動保護を仮定しないでください。第三者製 Skill の著作権は原著作者に帰属し、利用リスクは利用者が負います。

1仕組みと動作原理

字幕の取得元は公式Data APIではなく、YouTube内蔵のInnerTubeプレーヤーエンドポイントです。スクリプトがwatchページのHTMLから正規表現でINNERTUBE_API_KEYをその場で抽出し、それを付与してプレーヤーエンドポイントにPOSTリクエストを送信します。

skills/baoyu-youtube-transcript/scripts/youtube.ts
const apiKey = html.match(/"INNERTUBE_API_KEY":\s*"([a-zA-Z0-9_-]+)"/)?.[1];
処理内容:キーは公開Webキーであり随時取得されるため、本スキルは「No API key」と謳うことができます。同一HTMLからvisitorDataも取得してX-Goog-Visitor-Idとして使用し、ログイン不要の匿名セッション識別子として機能します。エンドポイント定数は同ファイル内に記載:INNERTUBE_URL = https://www.youtube.com/youtubei/v1/player —— 公式Data APIを経由せず、非公開エンドポイントへの独自リクエストを構築しています。

YouTubeからbot判定された場合、単純なリトライは行わずクライアント識別子を変更します。ANDROID / WEB / IOSの3種類のクライアント宣言とUser-Agentを順に切り替えてリトライし、すべて失敗した場合にのみyt-dlpへフォールバックします。

skills/baoyu-youtube-transcript/scripts/youtube.ts
com.google.android.youtube/20.10.38 (Linux; U; Android 14; en_US; Pixel 8 Pro; Build/AP1A.240405.002)
処理内容:リクエストをYouTube Appクライアントに偽装し(X-YouTube-Client-Name / X-YouTube-Client-Version / X-Goog-Visitor-Idヘッダーを設定)、Web版のbot検知を回避します。

yt-dlpへのフォールバックは「事前プローブ後に機能に応じてコマンドを選択」する方式です。yt-dlp、uvx --from yt-dlp yt-dlp、python3 -m yt_dlpを順次試し、--helpに--js-runtimesと--remote-componentsの両方が含まれている場合のみ適合と判定します。

skills/baoyu-youtube-transcript/scripts/youtube.ts
helpText.includes("--js-runtimes") &&
条件を満たさない旧バージョンのyt-dlpはスキップされます。これはスクリプトがシグネチャ解除に--js-runtimes bunを使用し、EJSコンポーネント取得に--remote-components ejs:githubを必要とするためです。またSKILL.mdは、不足依存関係の解決権限をユーザーではなくエージェントに委任しています。

最終的な実行はspawnSync(コマンド, argv配列)で行われ、シェル文字列の連結は存在しません。プローブと実行の両方にmaxBuffer上限が設定されています。

skills/baoyu-youtube-transcript/scripts/youtube.ts
const result = spawnSync(command.command, args, {
実行対象は固定のargv(-J、--skip-download、--js-runtimes、bun、--remote-components、ejs:github、任意の--cookies-from-browser)に限定されているため、シェルインジェクションは発生しません。動画IDパラメータはユーザー入力に由来します。

--translateは外部の翻訳APIを呼び出さず、字幕トラックURLに&tlang=<code>を追加してYouTube独自の機械翻訳トラックを利用します。

skills/baoyu-youtube-transcript/scripts/youtube.ts
url += `&tlang=${translateTo}`;
事前チェックとしてinfo.isTranslatableがtrueであり、対象言語がtranslationLanguagesに含まれていることを確認します。yt-dlp分岐に進む場合はtlangを付与するのではなく、言語リストを再選択する処理に切り替わります。

--speakersは「スクリプトによる素材出力 + サブエージェントによる加工」を採用しています。スクリプトはSRTタイムスタンプ付きの元markdownを1件出力するにとどめ、エージェントが安価なモデルのサブエージェントに話者ラベリングとチャプター分割を委託します。

skills/baoyu-youtube-transcript/SKILL.md
spawn a sub-agent (use a cheaper model like Sonnet for cost efficiency)
プロンプトテンプレートはprompts/speaker-transcript.mdにあり、逐語的な忠実性の保持、既存SRTタイムスタンプを使用した段落への統合、**Speaker Name:**で始まる段落の作成が厳格に要求されます。

キャッシュがデータ面として機能します。初回実行時にmeta.json + transcript-raw.json + transcript-sentences.json + imgs/cover.jpgを出力し、`.index.json`がvideoId→ディレクトリのマッピングを管理するため、同一動画の次回実行時はネットワーク通信ゼロで動作します。

skills/baoyu-youtube-transcript/scripts/storage.ts
return existsSync(join(videoDir, "meta.json")) && existsSync(join(videoDir, "transcript-raw.json"));
言語の変更または--refreshの指定により強制再取得が行われます。SRTはraw snippetsから生成され、markdownはsentencesを使用するため、単一のキャッシュから2種類のレンダリング形式に対応します。

テキスト出力は未加工のsnippetsではなく「文(sentences)」単位です。句読点で分割され、タイムスタンプは文字長の比率に応じて配分され、CJKテキストは適切に結合されます。

skills/baoyu-youtube-transcript/SKILL.md
split by sentence-ending punctuation (`.?!…。?!` etc.), timestamps proportionally allocated by character length, CJK-aware text merging
これによりmarkdown出力が未加工の字幕よりも格段に読みやすくなります。段落の境界が数秒ごとの短いキューではなく文単位で構成されるためです。

2コア機能

01URLまたは動画IDから字幕を取得しmarkdown / SRTを出力(APIキー不要、ブラウザ不要)
02多言語の優先順位付けと利用可能トラックのリスト表示(--languages / --list)
03機械翻訳字幕トラックの取得(--translate zh-Hans、YouTube独自の翻訳トラックを利用)
04動画概要欄のタイムスタンプに基づくチャプター分割(--chapters)
05話者識別(--speakers):スクリプトが素材を出力し、サブエージェントが逐語的な話者ラベル付与と段落分割を実行
06カバー画像およびメタデータの取得とローカルキャッシュ(imgs/cover.jpg + meta.json)
07スクレイピング対策のフォールバックチェーン:3種のクライアント識別子リトライ → yt-dlp
08キャッシュの再利用と強制更新(--refresh / 言語変更による自動無効化)

3外部依存関係

KindDependency / Endpoint
apiYouTube InnerTube player API(非公开接口)
networkYouTube watch 页(抓 INNERTUBE_API_KEY / visitorData)
network字幕轨 baseUrl(InnerTube/yt-dlp 返回,fmt=json3/xml)
networkYouTube 缩略图 CDN(封面)
networkconsent.youtube.com 表单(仅字符串匹配,重试用 CONSENT cookie 再请求 watch 页)
cliyt-dlp(直接二进制)
cliuvx --from yt-dlp yt-dlp(免安装形态)
clipython3 -m yt_dlp(已安装模块形态)
clibun / npx -y bun(脚本运行时)
networkyt-dlp --remote-components ejs:github 拉取的 GitHub 远端 EJS 组件

4推奨統制措置と判定根拠

安全運用のための推奨統制措置
Agent 向け
隔離環境で実行、都度明示的な認可
管理者向け
厳格な認可、全量監査、コンプライアンス確認
判定根拠(ファイルパスと抜粋)
  • SKILL.md / 脚本: 未公開またはリバースエンジニアリングされたプライベートAPIの呼び出し/クライアント識別子の偽装
  • SKILL.md / 会话存储: ブラウザのユーザーログイン状態およびセッションCookieの読み取りまたは再利用
  • 本地凭据 / 浏览器配置: ユーザーログインCookie/セッション/キーリングの読み取り: process.env.YOUTUBE_TRANSCRIPT_COOKIES_FROM_BROWSER(スキル全体で唯一の環境変数読み取り箇所)→ yt-dlpパラメータとして使用
  • scripts/: ローカルスクリプトまたはコマンドの実行: ${BUN_X} {baseDir}/scripts/main.ts <url|id>(bunまたはnpx -y bun経由。スキルディレクトリ内はTSファイルのみ)
  • 网络端点: 外部ネットワークアクセスの宣言: https://www.youtube.com/watch?v=<id>&hl=en&persist_hl=1&has_verified=1&bpct
  • 本地工作目录: ファイル読み書きおよび成果物出力: youtube-transcript/(デフォルト、--output-dirで変更可能)
監査ノート: (機能およびポリシーレベルでの判定であり、悪意のあるコード注入ではありません。コードは簡潔で可読性が高く、難読化やハードコードされたキーはなく、想定外の送信先への外部送信もありません)。Red(高リスク)判定とした3つの理由:①【リバースエンジニアリング/偽装】公式Data APIを呼び出さず、youtubei/v1/playerへの独自リクエストを構築し、watchページのHTMLから毎回正規表現でINNERTUBE_API_KEYを抽出し('const apiKey = html.match(/"INNERTUBE_API_KEY":\s*"([a-zA-Z0-9_-]+)"/)?.[1];')、ANDROID / IOS / WEBの3種のクライアント宣言とモバイルUAで公式クライアントに成りすましてbot検知を回避している点(UA原文:'com.google.android.youtube/20.10.38 (Linux; U; Android 14; en_US; Pixel 8 Pro; Build/AP1A.240405.002)')。②【認証情報の露出面】スキルの組み込みロジックによりYOUTUBE_TRANSCRIPT_COOKIES_FROM_BROWSERをyt-dlp --cookies-from-browserに透過させ、サードパーティCLIがローカルブラウザのCookieストアを読み取り有効なログイン状態で外部通信することを許容している点(環境変数による制限があり、サードパーティへの委任であり、CDPを経由せず、トークンをディスク保存しない形態)。③【サードパーティCLIのオンデマンドブートストラップ】フォールバックパスでuvx --from yt-dlp yt-dlp / python3 -m yt_dlpをその場で取得・実行可能とし、--js-runtimes bun --remote-components ejs:githubによりGitHubのリモートコンポーネントを取得して実行する点。さらにSKILL.mdはユーザーへの確認なしに不足依存関係をエージェント自身で取得するよう指示している点。既存の判定例との比較:bilibili-sourceは「Cookieへの接触」のみでOrange判定を受けていますが、本件はリバースエンジニアリングによる偽装と認証情報の外部委任の両方に該当するためRedと判定されます。なお、デフォルト(環境変数未設定)パス自体は固定の公開エンドポイントへのアクセスのみで認証情報も含まないためYellow相当ですが、プラットフォームの機能レベル評価基準に基づき、潜在的な最大権限・機能に基づいて判定ランクを決定しています。

5二重目の独立検証

  • [ok] InnerTube 端点与 key 现场抓取(无硬编码 key) — youtube.ts 含 INNERTUBE_URL/WATCH_URL 常量与 html.match(/"INNERTUBE_API_KEY":...) 抓取逻辑;全仓无硬编码 API key,只有会随版本过期的客户端版本号与 UA 常量。
  • [ok] 三套客户端身份轮换(ANDROID/WEB/IOS)+ 对应头 — clientName "ANDROID"/"WEB"/"IOS"、X-YouTube-Client-Name / X-YouTube-Client-Version / X-Goog-Visitor-Id 头与 Pixel 8 Pro UA 均在源码中;与 SKILL.md 的『bot detected』说明一致。
  • [ok] yt-dlp 回退的探测与参数 — 三个候选命令(yt-dlp / uvx / python3 -m yt_dlp),--version 探测后还要 --help 命中 --js-runtimes 与 --remote-components;执行参数为 -J --skip-download --js-runtimes bun --remote-components ejs:github(可选 --cookies-from-browser)。
  • [ok] --translate 无任何外部翻译服务 — 只有 url += `&tlang=${translateTo}` 与 isTranslatable / translationLanguages 前置检查;无 Google Translate / LLM / HTTP 翻译调用,依赖面为零 npm 包。
  • [ok] 零 npm 依赖、skill 内无 package.json — skill 目录仅 .ts 与 prompt 模板;全部 import 为 node 内置(fs/path/child_process/node:test/node:assert)与相对 .ts;根 package.json 的 workspaces 只覆盖 packages/*。
  • [ok] 全 skill 唯一 env 读取 = YOUTUBE_TRANSCRIPT_COOKIES_FROM_BROWSER — 跨目录 grep process.env / env[ / YOUTUBE_ 仅命中该变量(读取一处、拼参数一处);未设置时回退路径不带 cookie,故凭证面为『闸门 + 委派』而非默认开启。
  • [ok] 写盘清单与 SKILL.md 输出树一致 — 代码写入 .index.json / meta.json / transcript-raw.json / transcript-sentences.json / imgs/cover.jpg / transcript.md|.srt,与 SKILL.md 目录树逐项对齐;不落盘任何 token。
  • [ok] 文档与代码的次要出入 — SKILL.md 工作流小节出现两个编号为 3 的步骤(文档笔误,不影响结论);--speakers 隐含 --chapters 的说明与代码分支一致。

6結論

  • 依存関係ゼロ・ビルド不要:bun + Node.js組み込みモジュールのみを使用し、クローン後すぐに実行可能でサプライチェーンリスクがほぼ皆無。
  • APIキーやブラウザなしで字幕を取得でき、スクレイピング検知への対策を回復可能なフォールバックパス(識別子ローテーション → yt-dlp)として設計。
  • 標準字幕を超える出力品質:句読点ベースの文分割 + チャプター + 話者 + タイムスタンプの組み合わせが可能で、markdownとSRTを同一ソースから生成。
  • キャッシュファーストのデータ構造:初回取得後の再フォーマット(テキスト取得後のSRT生成など)で再通信が発生せず、高速かつYouTubeに負荷をかけない設計。
  • 規律あるドキュメント:zshのクォートに関する注意点、任意のCookie環境変数、エラーコードの対処方法を明確に記述。
  • 最適な用途: インタビュー、講演、ポッドキャストなどのYouTube動画を読みやすい文字起こし文書や字幕に整理したい個人およびコンテンツ制作チームに最適です。長文markdown、プレーヤー用SRT、チャプターおよび話者アノテーション、機械翻訳の対訳が必要で、同一動画の反復処理において再通信を避けたい場合に適しています。Bun環境があれば即座に利用可能です。リバースエンジニアリング、クライアント偽装、任意のCookie委任動作を理解・把握した上での個人利用に最も適しています。
    不向きな用途: 企業のコンプライアンス要件が厳しい環境や高度なプライバシー保護が求められる環境には不向きです(クライアント識別子の偽装、任意のブラウザCookie委任、リモートコンポーネントの取得を含むため)。安定した公式APIの保証を必要とする本番パイプラインには不向きです。人間のレビューなしで書き込み権限を持つエージェントに外部動画テキストを直接入力する用途には適しません。動画ファイル自体のダウンロードを必要とする場合にも不向きです(本スキルは字幕とカバー画像のみを取得します)。
    Install Agent-Ready
    ① Verified Mirror 2026-09-15
    Option A · Direct DownloadDownload baoyu-youtube-transcript.tar.gz
    sha256: dbf11afd644a4963…
    Option B · Copy Guide for Agent
    install.json
    Agent はこの JSON ガイドから自動的にダウンロードして検証します。
    ② Upstream GitHub
    GitHub Repo ↗
    Pinned to commit 1567581c26.