FFmpeg 8.0で文字起こしができるようになるんだってさ

Share
FFmpeg 8.0で文字起こしができるようになるんだってさ
Photo by Aaron Burden / Unsplash

この前Whisperでの文字起こしをするために試行錯誤する記事を書いたばかり。

AIを使って寝てる間に文字起こしをしてもらいたい!
文字起こしをAIにやらせることができたらいいなあと思い立ち、とにかくやってみた。 私のラップトップはLenovoの「ThinkBook 16p G2 ACH Laptop - Type 20YM」。詳細スペックはこんな感じ。 構成 ハードウェア構成 * CPU: AMD Ryzen 7 5800H (3.20 GHz、8コア16スレッド) * GPU: NVIDIA GeForce RTX 3060 Laptop GPU (6GB VRAM) * メモリ: 40GB DDR4-3200 ※標準16GBから増設済み * ストレージ: 512GB SSD PCIe ソフトウェア環境 * OS: Windows 11 Pro (64bit) * バージョン: 24H2 パフォーマンス的なお話 このスペックでは、

まさか、FFmpegで文字起こし機能が直接使えるようになるっぽい。

ソースコードを見ると、OpenAI謹製のWhisperではなく、C++で書き直されたwhisper.cppライブラリが使用されていますね。元祖Whsperに比べて高速に処理ができそう。

というか、面倒だった環境構築がいらなくなりそうだね。PyTorchは依存関係にうるさくて、バージョン管理が面倒だったのだけれど、whisper.cppさえ入れておけば、あとはFFmpegのほうで指定するだけでうまいこと動くことになりそう!ワクワク!

FFmpegのメーリングリストみててびっくり!

いろいろ記事で取り上げられていたこともあって、2025年7月、FFmpegの開発メーリングリストに投稿されたパッチを見てみました。

重い腰を上げて作ってみたWhisperの文字起こし環境がいらなくなるみたい。

Whisper.csppよる文字起こし機能をFFmpegのフィルター機能として統合するみたいで、使うまでのステップが劇的に簡素化されそう。

出典情報

主要ソース

  • FFmpeg開発メーリングリスト: [PATCH] Whisper audio filter(2025年7月9日投稿)
  • 投稿者: Vittorio Palmisano氏
[FFmpeg-devel] [PATCH] Whisper audio filter

参考記事

  • Vittorio Palmisano氏による解説記事(Medium)
Run Whisper audio transcriptions with one FFmpeg command
Introduction

技術的な実装をチラッと見てみる

採用されたライブラリについて

ソースコードを見ると、FFmpegに統合されるのはOpenAI謹製のPython版Whisperではなく、whisper.cppのほうであるのがわかるね。

#include "whisper.h"  // whisper.cppのヘッダファイル

struct whisper_context *ctx_wsp;
struct whisper_state *whisper_state;

whisper.cppはC++で書き直されたWhisperの実装で、元のPython版と比較して3〜10倍の高速化を実現しているっぽいです。同じ精度ならそりゃあ速いほうがいいよね。しかもGPUなしで高速に動作するんだってさ。

GitHub - ggml-org/whisper.cpp: Port of OpenAI’s Whisper model in C/C++
Port of OpenAI’s Whisper model in C/C++. Contribute to ggml-org/whisper.cpp development by creating an account on GitHub.

ビルド設定も見てみる

configureスクリプトに追加されたオプションを見ると、どんな感じで統合されていてどんな感じで使うのかなあと雰囲気だけ知れます。

--enable-whisper enable whisper filter [no]

この設定から、FFmpegのビルド時にWhisper機能を有効化できるようですね。ソースコードの依存関係設定では以下のように定義されています。

whisper_filter_deps="whisper"
enabled whisper && require_pkg_config whisper "whisper >= 1.7.5" whisper.h whisper_init_from_file_with_params

whisper.cppライブラリのバージョン1.7.5以上が必要で、pkg-configを通じて自動的に依存関係が解決される仕組みになっていますね。

フィルターの詳細機能解説

基本的なパラメータ構成

新しく追加されたaf_whisper.cファイルには、いろいろな設定オプションが定義されました。

パラメータ 型 デフォルト値 説明
model STRING - whisper.cppモデルファイルのパス(必須)
language STRING "auto" 言語指定(自動検出も可能)
queue INT 3000 音声バッファサイズ(ミリ秒)
use_gpu BOOL true GPU使用の有効化
gpu_device INT 0 使用するGPUデバイス番号
destination STRING "" 出力先(ファイル、URL、標準出力)
format STRING "text" 出力フォーマット(text/srt/json)

VAD(Voice Activity Detection)の高度な統合

これは便利だろうなと思ったのが、Silero VADモデルとの統合ですよ。音声認識システム自体は音声があるのかどうかを識別できないので、BGMなんかを必死に文字お越ししようと頑張ってくれるのだよね。BGMならまだしも無音区間を一生懸命認識したって時間が無駄なので、無音区間はスキップしてくれるよって機能だと思う。効率的。

VADパラメータ 型 デフォルト値 説明
vad_model STRING - VADモデルファイルのパス
vad_threshold FLOAT 0.5 音声検出の閾値(0.0-1.0)
vad_min_speech_duration INT 50 最小音声継続時間(ミリ秒)
vad_min_silence_duration INT 500 最小無音継続時間(ミリ秒)

実際、当該ソースコードの実装を見ると、VAD機能でWhisperの処理効率を向上させる仕組みなんだなあってわかります。

struct whisper_vad_segments *segments = whisper_vad_segments_from_samples(
    wctx->ctx_vad, wctx->vad_params, wctx->audio_buffer, wctx->audio_buffer_fill_size);

さっきも言った通り、この機能によって音声が含まれる区間のみを処理し、無音部分をスキップすることで効率的に処理が進むようになります。

処理フローの技術的詳細についてちょこっと

音声データの前処理要件

ソースコードから、Whisperフィルターが要求する音声形式についても見てみましょう。

FILTER_SAMPLEFMTS(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP)

このフィルターは32ビット浮動小数点形式(FLT/FLTP)の音声データのみを受け付けます。また、Whisperの仕様により16kHzのサンプリングレートとモノラルチャンネルが必要です。

出力フォーマットについて

FFmpegなので当然実装されている出力フォーマットはいろいろ選べて、超実用的。

SRT形式の出力例

buf = av_asprintf("%d\n%02ld:%02ld:%02ld.%03ld --> %02ld:%02ld:%02ld.%03ld\n%s\n\n",
                  wctx->index,
                  start_t / 3600000, (start_t / 60000) % 60, (start_t / 1000) % 60, start_t % 1000,
                  end_t / 3600000, (end_t / 60000) % 60, (end_t / 1000) % 60, end_t % 1000,
                  text_cleaned);

JSON形式の出力例

buf = av_asprintf("{\"start\":%ld,\"end\":%ld,\"text\":\"%s\",\"turn\":%s}\n",
                  start_t, end_t, text_cleaned, turn ? "true" : "false");

従来の実装との比較分析

環境構築の複雑さの解消

従来のWhisper環境構築で必要だった手順と新しい統合版を比較してみましょう。

私がやってた従来のPython版Whisperセットアップ(複雑)
  1. Python環境の準備
    • Anacondaまたは仮想環境の構築
    • Python 3.8以上の確認
  2. GPU関連の複雑な設定
    • CUDAツールキットのインストール
    • nvidia-smiでの対応バージョン確認
    • cuDNNライブラリの手動設定
  3. PyTorchの慎重なインストール
    • CUDA版PyTorchの正確なバージョン選択
    • 依存関係の手動解決
  4. Whisperライブラリの導入
    • OpenAI Whisperパッケージのインストール
    • モデルファイルの個別ダウンロード
新しいFFmpeg統合版(簡単!たぶん)

即座に実行可能

ffmpeg -i input.wav -af "whisper=model=ggml-base.bin" output.srt

モデルファイルの準備

# whisper.cppからモデルをダウンロード
wget https://huggingface.co/ggml-org/whisper.cpp/resolve/main/ggml-base.bin

ビルド時の簡単な設定

./configure --enable-whisper
make && make install

パフォーマンスの大幅改善

whisper.cppの採用により実現される性能向上について、技術的な背景を解説します。

メモリ使用量の最適化

C++実装により、Pythonインタープリターのオーバーヘッドが完全に排除されます。また、whisper.cppは量子化技術を活用して、モデルサイズを大幅に削減しています。

並列処理の効率化

ソースコードに見られるGPU処理の実装もあったので、CPUだけでなくGPUのCUDAを使って高速に処理することも考えられていますね。

struct whisper_context_params params = whisper_context_default_params();
params.use_gpu = wctx->use_gpu;
params.gpu_device = wctx->gpu_device;

実践的な使用例とその解説

多分こんな感じで使えるようになるんじゃないかなあっていう。

基本的な動画からの文字起こし

ffmpeg -i presentation.mp4 -vn \
  -af "aformat=sample_rates=16000:channel_layouts=mono,whisper=model=./ggml-base.en.bin:language=en:destination=transcript.srt:format=srt" \
  -f null -

このコマンドの各部分を詳しく解説します。

  • -vn: 動画ストリームを無効化(音声のみ処理)
  • aformat=sample_rates=16000:channel_layouts=mono: Whisperが要求する音声形式に変換
  • whisper=model=./ggml-base.en.bin: whisper.cppモデルファイルを指定
  • language=en: 英語として処理
  • destination=transcript.srt: SRT形式で出力
  • -f null -: 音声出力は破棄(文字起こしのみが目的)

リアルタイム文字起こしの実現

ffmpeg -f alsa -i hw:0 \
  -af 'highpass=f=200,lowpass=f=3000,aformat=sample_rates=16000:channel_layouts=mono,whisper=model=./ggml-medium.bin:language=ja:queue=10000:destination=-:format=json:vad_model=./ggml-silero-v5.1.2.bin' \
  -f null -

こんな感じで処理ができるかなあと。

  1. 音声フィルタリング: ハイパス(200Hz)とローパス(3000Hz)フィルターで会話部分を強調
  2. 拡張バッファ: 10秒間のキューで長い発話にも対応
  3. VAD統合: Sileroモデルで音声区間を自動検出
  4. 標準出力: リアルタイムでJSON形式の結果を出力

まとめ

FFmpeg 8.0はwhisper.cppを採用して統合するようですね。複雑な環境構築から解放されそうなのがうれしい。それに高速で軽量な文字起こし処理が実現できるなら本当にいろいろな場面で有効活用できそうです。

現在の開発状況から、FFmpeg 8.0は2025年8月中のリリースが予定されています。

8月のリリースが待ち遠しいですねえ。


本記事は2025年7月のFFmpeg開発メーリングリストに投稿されたパッチコードを雰囲気で分析しているだけです。実際のリリース版では仕様が変更される可能性があります。

Read more

Dependabotの対応が面倒なのでRenovateを導入する

Dependabotくんはある程度の依存関係の更新を通知してくれるが、山のようにprojectを抱えているとなんとも痒いところに手が届かない。 ということで、Renovateを使ってみる。 Build software better, togetherGitHub is where people build software. More than 150 million people use GitHub to discover, fork, and contribute to over 420 million projects.GitHub ここからGitHub Appを入れる。 あとは、指示に従ってポチポチするだけで、超かんたんだった。 感想 自動化最高。

By Sakashita Yasunobu

nodejsのバグを見つけたのでPRを投げてみた

概要 要するに、node --testで特定のバイナリを標準出力に書くと、テストランナーが固まったり、異常終了したりするバグです。 バグ自体は既知のものだったようで、修正がされていました。 test_runner: infinite loop in FileTest#drainRawBuffer when child stdout contains FF 0F followed by large size bytes · Issue #62693 · nodejs/nodeVersion v25.9.0 (also reproduced on v24.14.1 LTS, v22.21.0 LTS, v23.4.0) Platform Darwin 25.

By Sakashita Yasunobu
青空文庫のParser

青空文庫のParser

青空文庫のParserを作ってます。 GitHub - P4suta/aozora: Pure-functional Rust parser for 青空文庫記法 (Aozora Bunko notation): ルビ, 傍点, 縦中横, 外字, 返り点, indent containers, page breaks.Pure-functional Rust parser for 青空文庫記法 (Aozora Bunko notation): ルビ, 傍点, 縦中横, 外字, 返り点, indent containers, page breaks. - P4suta/aozoraGitHubP4suta Rustで作ってますが、配布物はcargoのほかにnpm/pypiでも入手できます Documentation * Playground — try it in

By Sakashita Yasunobu