Skip to content

ASR and Video Analysis ja

Hermes Agent edited this page Oct 1, 2026 · 1 revision

ASR と動画解析

English | 中文 | 日本語 | 한국어 | Español | Português | Русский

字幕なしの Bilibili / YouTube 動画を添付すると、browsa はページ内で音声を取得し、クラウド ASR を実行して [mm:ss] のトランスクリプトを生成する — あるいは「视听精读」を実行する: 発話 + 映像をまとめた図入りのテキスト文書。現在の ASR プロバイダは Volcengine Ark。

「ダウンロード → ファイルアップロード」であり、URL 直渡しではない理由

両プラットフォームとも、URL 直渡しは死んでいる: Bilibili は CDN URL をユーザーのセッション IP に署名する(Ark サーバーは取得できない)。YouTube は PO トークン + セッション + Cookie 束縛を加える(サーバー側の取得は 403)。署名と一致する IP を持つクライアントであるブラウザ自身が、バイト列を取得して Files API へアップロードせねばならない。これは根因に基づく結論であって、いくつかの選択肢の 1 つではない。

パイプライン(8 ステップ)

  1. ATTACH_PAGE が {mode:'asr-pending'} を返す(遅延ストレージのハンドオフ)。
  2. buildAsrPendingCtx がプラットフォームでディスパッチ: Bilibili はコンテンツスクリプトを再注入してストリームを読む。YouTube は MAIN ワールドの __browsaFetchFreshYouTubeStreams を呼ぶ(新しい /player リクエストが現行の PO トークンを鋳造する)。
  3. ストリーム選択: 最小ビットレートの純音声(どうせトランスコードする)だが、真の動画長の 90% 未満しかないストリームは拒否する(実際に切り詰めストリームの事故があった)。AAC-LC を優先(decodeAudioData は HE-AAC を拒むことがある)。
  4. DNR ヘッダ注入(lib/sidepanel/media-headers.js): Bilibili は Referer が必要。YouTube はさらに Origin の書き換え + Cookie が要る(googlevideo はヘッダなしの拡張 fetch に 403 を返す — 実機検証済み)。
  5. 16kHz モノラル WAV へトランスコード: Bilibili の m4s は映像なし fMP4 の MP4。Ark はファイルを内容で分類し「video」とみなす → Invalid video_url → ステータス失敗。WAV が経験的に実証済みのフォーマット。Web Audio デコード + 手書きの線形補間リサンプル(純粋、Node でテスト可能)。
  6. Files API へアップロード(≤512MB のマルチパート): expire_at = 30 日、セマンティックなファイル名。browsaArkFileCache が file_id を保存し(キー = base|key-fingerprint|assetId)、同じ動画は 30 日以内なら再アップロードをスキップする(再利用前に生存プローブ)。
  7. ファイルステータスをポーリング → /responses でストリーミング文字起こし(input_audio.file_id)。プロンプトが行毎の [mm:ss] を強制する。
  8. ATTACH_ASR_CONFIRM がトランスクリプト + videoSrc スタンプを保存する(タイムスタンプピル/タイムラインドロワーの前提条件)。

切り詰め防御 — 部分トランスクリプトを黙って保存しない(4 層、事故駆動)

  1. /responses に明示的な max_output_tokens: 65536(モデルのデフォルト出力上限が、音声の途中で黙って切る)。
  2. SSE の incomplete / finish_reason:'length' シグナルをパース → truncated:true。
  3. 完全性ゲート: 最後のタイムスタンプが動画長の 90% 未満 → throw し、素のテキストへフェイルオープン + トースト(保存はしない)。
  4. 穴ゲート: largestTranscriptGapSec がタイムラインを区間マージする。300 秒超の欠落は拒否(81 分の動画が中間の 1 時間を失ったことがある)。

動画ディープリード(動画そのものをモデルへ渡す)

input_video(+ 任意の別 input_audio)、max_output_tokens 65536、図文のストリーミング出力。プロンプト規律(実ランで較正済み): 2 人目の声が現れたら必ず話者をラベル付けし、識別可能な名前を付ける。広告読みは 1 行に圧縮。キーフレームのスクリーンショットは、議論が「それを見ること」に依存する場合に限る(ソフトな密度ヒント + 明示的な撮影禁止リスト。唯一のハード上限はクライアント側の SAFETY_KEYFRAME_CAP 24 — 病的な出力へのガードであって、品質ノブではない)。[图N] マーカーは、ページ画像やタイムラインドロワーと 1 つのアンカリングプロトコルを共有する。

プラットフォーム注記

  • Bilibili: /x/player/wbi/v2 のトラックリスト + CDN 字幕 JSON を能動的に取得 — CC トグルに依存しない。
  • YouTube: timedtext はプレーヤー自身の POT 付きリクエストにしか実内容を提供しない(captionTracks.baseUrl の直接取得は空ボディを返す)。インターセプタが素材を捕捉するのは、CC が少なくとも 1 回オンだった場合だけ。フォールバックのステージ 2c は、プレーヤーの字幕モジュールを駆動して 1 件の認可済みリクエストを鋳造する(画面に一瞬字幕がフラッシュするのは想定内)。トラックリスト空の判定は videoId 毎にネガティブキャッシュされる。
  • 「字幕なし」の判定は、構造化された noTranscript フラグから行い、## 字幕 のテキストマーカーからは行わない(自動モードの無言 Jina フォールバックがテキストマーカーを呑む — 実バグ)。

第 2 の ASR プロバイダ向けの継ぎ目(予約済み)

lib/asr-providers.js(メタデータ登録簿。UI 変更ゼロ)+ attach-asr.js の ASR_ADAPTERS(同一シグネチャの {transcribeAudio, analyzeVideo})。難所は常に、エンドポイントのファイルアップロード能力(長い音声はインライン base64 には乗らない)。Qwen/DashScope の完全なアダプタが作られ、1 日で削除された(ブラウザ→OSS が不安定。git 履歴に保存済み)。tabCapture の「再生しながら録音」フォールバックは却下された(一時停止/スキップ区間は無音 — 未再生の動画は文字起こしできない)。


権威版: ASR-and-Video-Analysis(英語) / ASR-and-Video-Analysis-zh(中文) — AI による初翻スナップショット、同期日 2026-10-01。

Clone this wiki locally