開発ガイド · アプリ開発者

YouTube動画内の発言を検索できるエンジンの作り方

YouTube検索が照合するのはタイトル、説明文、タグだけです。400本のポッドキャストのうち、どの回で特定のゲスト・本・アイデアに触れたのか、それが何分目なのかまでは教えてくれません。文字起こしを使った検索エンジンならそれが可能で、APIを使って最も早く作れる実用的なプロダクトのひとつです。

対象ユーザー
ポッドキャストネットワーク、オンライン講座プラットフォーム、ファンコミュニティ、社内動画ライブラリ
開発期間
週末
APIエンドポイント
/channels/resolve/batch/transcripts/{video_id}

解決する課題

大規模な動画ライブラリは、事実上検索できません。ファンはうろ覚えの場面を探して何時間も映像を早送りし、受講生はひとつの説明を探すために講義全体を見直し、企業は録画された講演に埋もれた組織のナレッジを失っています。タイムスタンプ付きで文字起こしをインデックス化すれば、どんなライブラリもドキュメントのように検索でき、結果から該当箇所へ直接ジャンプできます。

最初のバージョンに含めるべき機能

  • チャンネルや再生リスト内のすべての動画を対象にしたフレーズ・キーワード検索
  • 一致した文と、その正確なタイムスタンプへのリンクを表示する検索結果
  • 「商品の価格をどう決める?」で「料金設定」もヒットするセマンティック検索
  • 日付、動画、話者による絞り込み
  • 新しくアップロードされた動画の自動インデックス化

開発手順(ステップごとに解説)

  1. 01

    動画リストを取得する

    チャンネルハンドルまたは再生リストURLを指定して/channels/resolveまたは/playlists/resolveを呼び出し、すべての動画IDとタイトルを取得します。

  2. 02

    文字起こしを一括取得する

    format.timestampとformat.paragraphsを有効にしてIDを/batchに送信します。大きなバッチは非同期で処理されるため、/batch/{batch_id}をポーリングするかWebhookを使います。

  3. 03

    セグメントをインデックス化する

    各段落を動画IDと開始時刻とともに保存します。キーワード検索ならPostgresの全文検索で十分です。意味ベースの検索にはpgvectorやベクトルデータベースで埋め込みを追加します。

  4. 04

    検索UIを作る

    上位の一致結果を前後のテキストとともに返し、youtube.com/watch?v=ID&t=SECONDS形式のリンクで、ユーザーがその瞬間に直接移動できるようにします。

  5. 05

    常に最新に保つ

    定期ジョブでチャンネルを再度解決し、新しい動画IDを見つけて、それだけを文字起こしします。

サンプルコード

このアイデアは「レシピ3:再生リストをナレッジベースに一括登録」パターンをベースにしています。チャンネル、プロンプト、保存先はご自身のものに置き換えてください。

import requests

API = "https://www.youtubetranscript.dev/api/v2"
HEADERS = {"Authorization": "Bearer yt_sk_live_YOUR_KEY"}

playlist = requests.post(f"{API}/playlists/resolve", headers=HEADERS,
                         json={"playlist_url": "https://www.youtube.com/playlist?list=PLAYLIST_ID",
                               "limit": 100}).json()

ids = [v["video_id"] for v in playlist["items"]]
batch = requests.post(f"{API}/batch", headers=HEADERS, json={
    "video_ids": ids,
    "format": {"timestamp": True, "paragraphs": True},
}).json()

# Large batches run async: poll GET /batch/{batch_id} until status is "completed"
for r in batch.get("results", []):
    if r["status"] == "completed":
        for p in r["data"]["transcript"].get("paragraphs") or []:
            store(video_id=r["video_id"], start=p["start"], text=p["text"])  # your vector DB

作る価値がある理由

視聴者ではなくライブラリの所有者に販売しましょう。ポッドキャストネットワーク、講座プラットフォーム、社内動画アーカイブを持つ企業は、視聴者のエンゲージメントを維持する検索機能に月額料金を払います。ファンコミュニティ向けには、無料の公開検索に通知やAPIアクセスの有料プランを組み合わせる方法も有効です。

避けるべき失敗

  • 文字起こし全体を1つのドキュメントとしてインデックス化すること:段落単位のタイムスタンプがないと検索結果が役に立ちません。
  • 更新のたびにチャンネル全体を再文字起こしすること:処理済みの動画IDを記録しておきましょう。
  • 完全一致のキーワード検索だけに頼ること:話し言葉は表現が揺れるため、早い段階でセマンティック検索を追加しましょう。

このアイデアに関する質問

YouTubeの文字起こしを検索するのにベクトルデータベースは必要ですか?

いいえ。ほとんどのライブラリでは、Postgresの全文検索で十分にキーワード検索ができます。完全一致ではなく意味で一致させたい場合に埋め込みを追加してください。

検索結果を動画内の正確な場面にリンクするには?

文字起こしの各セグメントには秒単位の開始時刻が含まれています。YouTubeのURLに&t=とその数値を付け加えてください。

字幕のない動画もインデックス化できますか?

はい。allow_asrとWebhook URLを有効にすると、字幕がない場合はAI音声認識で音声を文字起こしします。

今日から作り始めよう

毎月10クレジット無料。クレジットカードは不要です。

YouTube動画内検索エンジンの作り方 | YouTubeTranscript.dev