Communitygithub.com

Lumos12345/影片音訊文字提取

從本機影片/音訊檔案提取歌詞或字幕(含時間戳記):使用 Whisper 進行語音辨識,並對內嵌文字(硬字幕)進行 OCR 辨識。

影片音訊文字提取 是什麼?

這個技能專門用於從本機多媒體檔案(如 .mp4、.m4s、.mkv、.m4a、.mp3)中提取帶有時間戳記的歌詞或字幕。它主要處理兩種常見情況:一是下載的影片只有內嵌在畫面中的硬字幕(hardsub)而無軟字幕軌,二是只有音訊檔的情況。技能會依優先順序嘗試三種策略:先檢查是否有軟字幕軌(直接提取最快),其次若影片有可見的內嵌歌詞/字幕則使用 Tesseract OCR 進行光學字元辨識(可獲得官方正確拼寫),最後才使用 faster-whisper 進行音訊轉錄(需注意 Whisper 對歌唱類語音的拼寫錯誤)。此外,當同時有 OCR 與 Whisper 結果時,技能建議以 OCR 文字為準、Whisper 時間戳為輔,並透過 vision_analyze 輔助定位字幕區域與填補低對比度文字的辨識缺口。此技能支援 Bilibili/YouTube 常見格式、產出 .lrc 或 MM:SS 格式輸出,且可與「guitar-tabs」技能串接,直接提供時間同步的和弦譜。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add Lumos12345/video-text-extraction

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

影片 / 音訊文字提取

從本機多媒體檔案(.mp4、.m4s、.mkv、.m4a、.mp3)產出帶有時間戳記的轉錄稿或歌詞檔案。處理兩種常見情況:下載的影片沒有軟字幕軌但有內嵌(硬字幕)的畫面上文字,以及只有音訊的情況。

何時使用

  • 「從這個影片提取歌詞/字幕,並標記每行的開始時間。」
  • 「將此音訊轉錄成附帶時間戳記的文字。」
  • 下載的 Bilibili/YouTube .m4s/.m4a 檔案;歌詞已渲染在畫面中的卡拉OK/AMV/音樂錄影帶。
  • 任何要求輸出 .lrc 或 .srt 格式的請求。

步驟 0 — 務必先檢查

ffprobe -v quiet -print_format json -show_streams -show_format FILE | python3 -m json.tool

需了解的重點:

  • 存在的串流。 來自 Bilibili 的 .m4s 通常是僅含視訊(音訊存在於另一個 .m4s/.m4a 檔案)。如果沒有音訊串流,請在同一個資料夾中尋找持續時間相符的同伴音訊檔。
  • 軟字幕? ffprobe ... -select_streams s — 如果存在字幕串流,直接提取(ffmpeg -i FILE -map 0:s:0 out.srt),跳過所有 OCR/Whisper 工作。這是最快的路徑。
  • 持續時間。 當視訊沒有音訊時,用它來匹配正確的音訊檔。
  • 標題/演出者卡片不是字幕區域。 第 0 幀通常帶有大型標題和演出者疊加,位置和字體都與實際歌詞字幕不同。從它推導出的裁切區域會錯過所有歌詞。改為從歌曲中間(顯示長歌詞行)取樣一幀;如果需要歌曲/演出者名稱,再另外讀取標題卡。
  • 在轉錄前確認歌曲。 檔名和標題卡可能與使用者所稱的曲目不一致。如果音訊/歌詞與您預期的名稱不符,請在產出完整轉錄稿前先說明;如果影片是數首歌曲之一,請指明您實際轉錄的是哪一首。

步驟 1 — 決定文字來源(優先順序)

  1. 軟字幕串流 → 直接提取。完成。
  2. 內嵌的畫面上文字(硬字幕) → OCR 辨識幀(步驟 3)。這會得到官方、正確拼寫的文字。每當影片明顯渲染歌詞/字幕時,優先使用這個方法。
  3. 僅音訊,無畫面上文字 → Whisper 轉錄(步驟 2)。

如果同時存在畫面上文字和音訊轉錄,請使用 OCR 取得文字,使用 Whisper 獲取時間/定向 — OCR 文字是權威拼寫,Whisper 能精準掌握時間網格,但對於歌唱的文字可能會誤聽(例如它把 "petals" 聽成 "pedophiles",把歌唱的母音聽成 "fry right")。互相交叉比對。

步驟 2 — 音訊轉錄(Whisper)

一次性安裝(關於中國大陸的 HF 鏡像修正,請參閱 references/whisper-setup.md):

uv venv /tmp/wvenv
/tmp/wvenv/bin/python -m pip install faster-whisper

提取 16 kHz 單聲道 WAV,可選擇正規化:

ffmpeg -y -i AUDIO -af "loudnorm=I=-16:TP=-1.5:LRA=11,highpass=f=80" -ar 16000 -ac 1 -c:a pcm_s16le /tmp/song.wav

轉錄(腳本位於 scripts/transcribe.py):

HF_HUB_DISABLE_XET=1 HF_ENDPOINT=https://hf-mirror.com \
  /tmp/wvenv/bin/python scripts/transcribe.py /tmp/song.wav medium
  • 模型 medium 是甜蜜點;large-v3 更準確但在 CPU 上慢。
  • medium 在 CPU(int8)上轉錄一首約 2.5 分鐘的歌曲需要幾分鐘;載入模型時 RSS 低,然後在實際轉錄時跳到約 1.4 GB RSS — 不要在載入階段恐慌地殺死它,請檢查 /proc/<pid>/status 的 VmRSS。
  • 請勿對歌唱音樂使用 VAD 過濾。 vad_filter=True 會捨棄安靜/帶迴音的人聲線條,可能將一首 3 分鐘的歌曲減少為少數段落。請轉錄整個音軌。
  • 適用於「歌唱」的參數(無 VAD):beam_size=5、condition_on_previous_text=True、溫度回退 [0.0,0.2,0.4,0.6,0.8,1.0]、no_speech_threshold=0.8、log_prob_threshold=-1.5、compression_ratio_threshold=2.8、word_timestamps=True、hallucination_silence_threshold=1.5。(預設值會捨棄整個短語,並在樂器間隔中產出沉默幻覺。)

步驟 3 — 內嵌文字 OCR(高價值路徑)

完整操作手冊:references/hardsub-ocr.md。摘要:

  1. 安裝 tesseract 不使用 sudo,方法是將 .deb 解壓縮到某個前綴目錄(詳情見參考文件)。文件中記錄了 liblept.so.5 和 libarchive.so.13 的符號連結修正。
  2. 尋找文字區域:用 vision_analyze 讀取一幀,要求提供字幕區域的像素座標。在音樂錄影帶中,字幕通常位於左下角 — 請勿猜測。
  3. 密集提取幀:ffmpeg -i SRC -vf fps=2 /tmp/frames/f_%04d.png(2 fps → 約 0.5 秒解析度;第 N 幀時間為 t = N/2 秒)。
  4. 裁切區域、放大 2–3 倍、轉灰階、對每一幀進行 OCR(--psm 6 或 --psm 7)。
  5. 去除重複:連續幀重複同一行 = 一行歌詞;第一次清晰讀取即為其開始時間。
  6. 低對比度文字:使用 vision_analyze 作為備援。 Tesseract 在淺色襯線字體搭配明亮/照片背景時會失敗。視覺模型可以可靠讀取 — 對 Tesseract 輸出亂碼的幀使用它。這種混合方式(Tesseract 大量處理 + 視覺模型填補)是生產模式。

輸出

當使用者要求歌詞和時間戳時產出 .lrc([mm:ss.xx]line),否則產出純文字 MM:SS 文字。儲存到使用者指定的路徑(通常是在 WSL 上的 Windows 桌面,例如 /mnt/c/Users/<user>/Desktop/)。

交接: 您在此產出的 .lrc 正是 guitar-tabs 技能進行 LRC 同步和絃譜/每行和絃對齊所需的輸入。當歌詞然後和絃譜的請求作為一個任務提出時,請保留 .lrc 並直接餵給 guitar-tabs(其 scripts/chord_analyze.py 接受 <音訊> <歌詞.lrc>,並為每一行歌詞印出一個和絃)。這兩個技能串聯:video-text-extraction → 時間同步歌詞 → guitar-tabs → 彈唱譜。

陷阱

  • .m4s 通常只有視訊。 不要假設它有音訊。用持續時間匹配同伴音訊檔。
  • 不要相信 Whisper 對歌唱人聲的拼寫。 有畫面文字時請與之核對。
  • VAD 會殺死安靜的人聲 — 見步驟 2。
  • Tesseract 需要精確的裁切。 垂直方向偏移約 100 像素的文字區域就會產出雜訊。先用視覺分析取得座標。
  • Tesseract 的共享庫相依性是一個一個出現的。 每次執行都會因不同的 error while loading shared libraries: X 而失敗 — 先是 liblept.so.5,然後 libarchive.so.13,接著 libgif.so.7,依此類推。不要放棄也不要逐個安裝:一次下載完整列表(見參考文件),解壓縮,然後用 ldd … | grep "not found" 一次查看所有仍然缺失的項目。兩個額外加分題:libarchive13 在較新的 Ubuntu 上沒有候選套件(改使用 libarchive13t64),而 liblept5 是攜帶真正 liblept.so.5.0.4 的套件 — -dev 套件只提供懸空的符號連結。
  • 短小/混亂的 OCR 讀取通常是裁切問題,而不是 OCR 問題。 在調整 --psm 或閾值之前,先用 vision_analyze 分析裁切後的區域本身。如果視覺分析也看不到文字,那就是裁切錯了。這一步檢查可以省去很多無謂的濾波器調整。
  • 帶有 export / 管線的終端命令可能需要核准。 將 tesseract 的環境變數打包成 .sh 腳本,執行 bash script.sh 而不是內聯的 export ...; tesseract ...。
  • HuggingFace 在中國大陸很慢/被屏蔽。 務必設定 HF_ENDPOINT=https://hf-mirror.com 和 HF_HUB_DISABLE_XET=1(xet 後端對鏡像回傳 401)。
  • 檢查模型下載是否確實進行中。 一個 faster-whisper 執行若 RSS 約 5 MB 且 CPU 無活動,表示卡在抓取模型;真正執行時 RSS 會升到約 1.4 GB。檢查 /proc/<pid>/status(VmRSS)而非殺死它或盲目等待。

相關技能