例で学ぶFFmpeg
(ffmpegbyexample.com)- FFmpegの作業はオプションの組み合わせが複雑になりがちだが、FFmpeg By Exampleは実際のコマンド例から必要なメディア処理方法をすばやく探せるドキュメントサイト
- GitHubリポジトリ、Discordコミュニティ、貢献ページも用意されており、ユーザーが新しいFFmpeg活用アイデアを直接投稿できる
testsrcフィルタの例のように、入力ソース、解像度、フレームレート、出力ファイルを1つのコマンドで示しており、コマンド構造をそのまま試せる- 例には、ビットレート計算、画像リサイズ、音声ノイズ低減、トランジション効果、ストリームマッピング、ハードウェアアクセラレーション、メタデータ処理など、メディア処理作業全般が含まれる
- 各例はタグと個別ページに分かれており、特定のフィルタや変換目的を基準に必要なFFmpegコマンドを探しやすい
例中心のFFmpegドキュメントサイト
- FFmpeg By Exampleは、FFmpegのさまざまな使い方をサンプル単位で整理したWebサイト
- コミュニティ参加とコントリビュートのためのリンクも提供している
testsrcテスト動画生成の例
- Generate test video color pattern with 'testsrc' filterは、
testsrcフィルタでテスト用のカラーパターン動画を作る例 - コマンドはlavfi入力で10秒、1280x720、30fpsの動画を
testsrc.mpgとして生成する
ffmpeg -f lavfi -i testsrc=duration=10:size=1280x720:rate=30 testsrc.mpg
エンコード・変換・ハードウェアアクセラレーション
- 動画エンコードやフォーマット変換に関する例が含まれている
- Recode Your Video With a Modern Codec, Often Saving Space: H.265エンコード関連の例
- Convert Video to Telegram Video Sticker Format (512px Max, 256KB Limit): Telegramビデオステッカー形式への変換例
- Use Intel QuickSync Video Hardware Acceleration for Transcoding Video: Intel QuickSync Videoハードウェアアクセラレーションによるトランスコード例
音声処理
- ノイズ除去、正規化、変換、抽出といった、よく使う音声処理を例で確認できる
- Audio Noise Reduction Using Arnndn:
arnndnを使った音声ノイズ低減 - Normalize Audio to EBU R128 Loudness Standard (-23 LUFS): EBU R128基準の
-23 LUFS正規化 - Convert Wav to Mp3 File: WAVをMP3に変換
- Extract an AAC Audio Track From a Video File: 動画ファイルからAAC音声トラックを抽出
- Audio Noise Reduction Using Arnndn:
画像とアニメーション
- 静止画処理からWebPアニメーション生成まで、画像ベースのワークフローも扱っている
- Resize PNG Images While Preserving Transparency and Aspect Ratio: 透明度とアスペクト比を保ったPNGリサイズ
- Generate Looping WebP Animation From Image Sequence With Variable Quality: 画像シーケンスからループするWebPアニメーションを生成
- Slow Animated WebP Image Sequence (Carousel): ゆっくりしたアニメーションWebP画像シーケンスの例
フィルタと視覚効果
- FFmpegフィルタを使ったアニメーション、トランジション、テキスト効果の例が整理されている
- Animate an Image Using Zoompan Filter:
zoompanフィルタで画像アニメーションを生成 - XFade Video Transitions Examples:
xfadeベースのトランジション効果 - Video Echo Effect With Delay and Hue Using Lagfun:
lagfunによるディレイと色相変化のあるビデオエコー効果 - Fade in and Out Text Using the 'Drawtext' Filter:
drawtextフィルタでテキストをフェードイン・フェードアウト - "Drawtext" and "Drawbox" Using "Sendcmd" Manifest:
sendcmdマニフェストでdrawtextとdrawboxを使用
- Animate an Image Using Zoompan Filter:
抽出・分析・メタデータ
- ファイルから必要なストリームを取り出したり、フレームやメタデータを分析したりする作業も含まれる
- Extract Audio From Video Files With Stream Mapping: ストリームマッピングで動画ファイルから音声を抽出
- Extract Multiple Video Clips From Single Input With Precise Timestamps: 1つの入力から正確なタイムスタンプで複数のクリップを抽出
- Analyze Video Frames, Timecode and Metadata With Showinfo Filter:
showinfoフィルタでフレーム、タイムコード、メタデータを分析 - Getting Streams Information of a Video File: 動画ファイルのストリーム情報を確認
- Copy Metadata From One Mp3 to Another: MP3間でメタデータをコピー
生成ソースと出力パイプ
- テストソース生成、個別フレームの記録、STDOUT出力のように、自動化やデバッグに役立つ例も提供している
- Generate Solid Color Video With Custom Hex Color Code: カスタムHexカラーコードで単色動画を生成
- Create SMPTE Color Bars With Centered Text Overlay: SMPTEカラーバーと中央テキストオーバーレイを生成
- Generate "Game of Life" Video Using Lavfi Video Source:
lavfiビデオソースでGame of Life動画を生成 - Print a Data Channel to STDOUT Using Ffmpeg: データチャネルをSTDOUTに出力
- Record a Video From Individual Frames: 個別フレームから動画を記録
1件のコメント
Hacker News のコメント
ffmpegを使う楽しさが1000%は増えた
以前は退屈に Google で Stack Overflow の回答を探してつなぎ合わせ、コマンドを作っていたが、今は ChatGPT が代わりにコマンドを書いてくれるのでずっと楽になった
LLM のおかげで ffmpegを週に何度も使っている
私の
llm cmdツールの最高の活用先だ:uv tool install llmllm install llm-cmdllm cmd use ffmpeg to extract audio from myfile.mov and save that as mp3https://github.com/simonw/llm-cmd
長いあいだ ffmpeg を正規表現と同じ箱に入れていた。「本当に学ぶべきだけど、ものすごく嫌いになりそうだ」という感じだった
ところが ChatGPT が現れて、その両方を解決してくれた
私も同じだ。こういう作業はAI が完全に引き受けてしまい、私はエラートレースをコピー&ペーストする仲介者でしかない
ほかにもツールはたくさん出ているが、こうした連鎖的なコマンドをかなり単純化してくれるスクリプトをちょうど作った: llmpeg https://github.com/jjcm/llmpeg
ffmpeg がインストールされていて、OpenAI の環境変数 API キーが設定されていればすぐ動くはず
デモ: https://image.non.io/1c7a92ef-0917-49ef-9460-6298c7a9116c.we...
複合フィルタがどう動くのかを学んでから、ffmpeg の使用体験はさらに良くなった
デジタル化した家庭用ビデオテープを、シーン検出でクリップに変換する方法をまとめて公開すべきだと思い出した
誰かが検索するかもしれないので、かなりうまく動いた gist を残しておく [0]。ただしカメラのフラッシュや手ぶれにだまされることがあり、開始/終了ファイルを別に渡して ffmpeg で再度つなぎ直す必要があった [1]
奇妙なのは、最新の Mac アップデートでは
-c:v h264_videotoolboxなしのほうが性能が良かったことだ。Sequoia の性能回帰かもしれないが、よく分からない。Nvidia GPU を搭載した Windows マシンで対応するフラグは-c:v h264_nvencだ。ffmpeg がなぜ自動検出しないのか気になる。これで約8倍の性能向上が得られた会社で本当に給料分の働きをした唯一の瞬間は、動画処理のために GPU 付きクラウドサーバーへ高い追加料金を払おうとしていたところで、インストール済みの ffmpeg がGPU アクセラレーションなしでコンパイルされていることに気づいた時だった
[0] https://gist.githubusercontent.com/nielsbom/c86c504fa5fd61ae...
[1] https://gist.githubusercontent.com/jazzyjackson/bf9282df0a40...
クラウド CPU の問題は、コンシューマー向け CPU に入っているハードウェア動画エンコーダがない点で、そのためずっと高価な GPU マシンに行く必要がある
正直なところ、クラウドでハードウェアアクセラレーションを使ってきちんと価格比較をしたことはないのだが、実際に試してコストに見合ったという意味なのか気になる
ffmpeg で空のシーン検出を試したことがある
SFO の飛行経路に向けたカメラがあり、動きのないフレームをすべて削除したところ、退屈な区間なしに飛行機が通過する連続映像だけが残った
-c:v h264_nvencは、複数の動画を一度にエンコードするバッチエンコードに有用だ。エンコードのスループットをさらに高められるからだただし以前に限定的に試したとき、出力品質は libx264 より少し悪かった。回避策があるのかは分からないが、私だけの経験ではなかった
ffmpeg がこれを自動検出しない理由は、ハードウェアエンコードはたいてい設定の幅が狭く、精巧なソフトウェアコーデックより妥協が大きく、同じパラメータでも正確に同じ結果を出すとは限らないからだ
さらに、システム上に選択可能なハードウェア API が複数あることも多く、機能も互いに異なる
FFmpeg は複雑なコマンドラインツールで、細部を学ぶ意欲のあるユーザーを対象にしているので、仮定にもとづいてデフォルトを決めるのが正しいのかはよく分からない
スニペットを見ると、デインターレースをしていないようだ
デジタル化前のクリップがすでにデインターレース済みなら問題ないが、そうでなければインターレース素材をプログレッシブとしてエンコードして品質を台無しにしていることになる。
bwdifフィルタを追加して、30i コンテンツが 60p としてエンコードされるようにしてみるとよい。元のビデオテープにより近く見えるはずだ時間がたつにつれ、ffmpeg のさまざまな部分にかなり慣れてきた。CLI にはそれなりの論理があり、順序依存だ。すべての Unix CLI がそうというわけではない
最近はもう少し難解な機能を触っている。たとえば、かなり遅いマシンでビデオカメラの生映像をそのまま保存する作業だ。顕微鏡を作り、カメラから 120FPS で生の動画形式(YUYV 1280x720)のフレームを読み取っているが、そのままディスクに保存すると分単位でギガバイト規模に膨らむ。ディスクは安いとはいえ無駄に思えるので、正確な画像を高速に圧縮して保存できる、ほぼロスレスの手法を調べた
ffmpeg で RGB24 変換が非常に遅いことが分かったので、コマンドラインをいろいろいじった末に次に落ち着いた:
ffmpeg -f rawvideo -pix_fmt yuyv422 -s 1280x720 -i test.raw -vcodec libx264 -pix_fmt yuv420p movie.mp4 -crf 13 -y生の動画にはコンテナがないため、「ピクセル形式」や「画像サイズ」のようなメタデータがなく、自分で指定する必要がある。順序に依存していて、
-i test.rawより前にあるものはすべて入力のデコード用、後ろにあるものはすべて出力の書き込み用。ごく小さなピクセル形式変換を1つだけ行い(ffmpeg は非常に高速に処理できる)、コンテナ付きのほぼロスレスな形式でデータを書き出す。ほとんどの場合、コンテナは.mkvが最適だったコマンドラインが嫌いなので、最終的に ffmpeg-python を使い、次のコードでコマンドラインを組み立てさせた:
self.process = (ffmpeg.input("pipe:",format="rawvideo",pix_fmt="yuyv422",s="{}x{}".format(1280, 720),threads=8).output(fname, pix_fmt="yuv422p", vcodec="libx264", crf=13).overwrite_output().global_args("-threads", "8").run_async(pipe_stdin=True))そして実際には、そのプロセスの標準入力にフレームを
write()している。マシンには12コアあり、顕微鏡の駆動に常に少なくとも2コアを使うので、スレッド数を制限する必要があったいまもなお、より良く、より速い ロスレス YUV エンコーディングを探している
順序依存であること自体は妥当。Unix パイプラインも構成要素の順序に依存しているし、複雑な FFMpeg 呼び出しはそれに似たことをしているから
ffmpeg-pythonのような「流れるようなインターフェース」の美学を好む人は多いが、Python ではしばしば Python らしくないと見なされる。ffmpeg-python はコマンドラインの順序をかなり忠実に反映するよう設計されているのだと理解している標準ライブラリと組み込み型の設計が後押ししている嗜好は、強い https://en.wikipedia.org/wiki/Command%E2%80%93query_separati... だ。この原則に従うなら、おおよそ次のような形になるはず:
ffmpeg(global_args=..., overwrite_output=True).process_async(piped_input(...), output(...))入力を別の構成プロセスにすれば、別のランタイム型が生まれ、処理コードにも標準入力から読むべきだというシグナルを与えられる
これ以上探す必要はない: FFV1 https://trac.ffmpeg.org/wiki/Encode/FFV1
一語だけ勧めたい: RAM ディスク
中間段階の処理はするが保存しておきたくないファイルがあるなら、RAM ディスクだ。本当に良い
FFmpeg の熟練者たちが蓄積してきた知識を集めて管理するウェブサイトなのだろうと思ったが、最初にクリックした例でいきなり失望した
https://www.ffmpegbyexample.com/examples/l1bilxyl/get_the_du...
文字列処理のためにツールをさらに2つも呼び出すべきではない。FFprobe だけで持続時間や欲しい値を直接返せる:
ffprobe -loglevel quiet -output_format csv=p=0 -show_entries format=duration video.mp4最初に動いたところで止まらず、動いた後にはもっと改善する方法がないか考えるべき
それでも、提示された解法のほうが気に入っている
良い。自分が使っている ffmpeg チートシートを思い出した。ffmpeg をよく使う人は、みんな似たようなメモ集を持っていそう
https://github.com/fastily/cheatsheet/blob/master/ffmpeg.md
https://github.com/ericfortis/quick-reference/blob/main/ffmp...
FFmpeg はあまりにたまにしか使わないので、正確な構文が絶対に頭に残らないツールの一つ。結局、必要なコマンドラインは LLM に作ってもらうことになる
同じくらい苦労した唯一のツールは、LSI Logic の1990年代風 MegaCLI だった。あれも年にほとんど使わないのに、プレッシャーの中で正確に使わなければならない類いのものだった
FFMPEG を15年以上使ってきたが、いまだにコマンドはほとんど覚えていない。それでも FFMPEG を使うときの LLM は本当にすごい
ChatGPT と Claude に「動画を mkv にリマックスし、subtitle.srt をファイルに含め、0:00:05 から 0:01:00 までだけ欲しい」と言うと、見事に処理してくれる。気になる人のために結果はこうだった:
ffmpeg -i input.mp4 -i subtitle.srt -ss 00:00:05 -to 00:01:00 -map 0 -map 1 -c copy -c:s mov_text output.mkvffmpeg コマンドの生成だけを目的にするなら、どれほど小さな LLM を作れるのか気になる。静的ウェブページに載せてローカルで実行できるくらい小さくできるのではないか?
15年間、自分がよく使う構文を入れた 個人用メモ文書を保守してきた。それでも駄目なら bash の履歴を
grepする自分も同じ。頭に残っているのは、形式 X から
.mp4に変えることだけ。残りは毎回調べ直す必要がある関連 XKCD https://xkcd.com/1168/
数日前、冗談半分本気半分で、LLM が自分の欲しい ffmpeg フラグを教えてくれるだけなら、熱帯雨林を全部燃やしてもそれだけの価値があるかもしれない、と言った
GStreamer もあることを忘れてはいけない。パイプラインベースなので、コマンドラインとドキュメントが ffmpeg より少し理解しやすく、組み合わせ方ももう少しまともに感じる
私は重い動画処理では ffmpeg を完全にやめて、GStreamer だけを使っている
ただし一回限りの作業には ffmpeg のほうがずっと親切に見える。たとえば ffmpeg には妥当な x264 のデフォルト値があるが、
gst-launchで高品質な x264 エンコードをするには、自分が何をしているのかを本当に理解している必要があるソース、シンク、変換フィルターからなる複雑なグラフを構成できる
このサイトを補完するのによさそうな ffmpeg の本 の GitHub リポジトリがある:
https://github.com/jdriselvato/FFmpeg-For-Beginners-Ebook
ffmpeg はいつも GUI アプリケーションを TUI 形式に無理やり押し込めたもの のように感じていた
C API も何度か不快な思いをしながら使ったことがある。多くの面で直感的ではあるが、不正な状態を表現できてしまうのが簡単すぎる。「ただ動く」リアルタイム AV1 エンコードフレームワークがあればいいのにと思う
基本的に GUI の代替ツールである HandBrake をまず探しに行く、ほとんど唯一のツールだ。例外はバッチ処理をするときだけ
純粋な ffmpeg GUI もいくつかある。動画作業には、コマンドラインが自分の頭の中の処理の仕方とうまく合わない何かがある
API としては GStreamer を勧められる。Rust バインディングを使ったので C API にはそれほど詳しくないが、良さそうに見えた
GObject のせいで冗長になる部分はあるが、理解してしまえば API のすべてのオブジェクトと一貫してやり取りできる。必要な複雑さは本当に多いが(動画は難しい)、設計、実装、ドキュメントはかなりよくできている
一般的なユースケースなら Bins(
decodebin,transcodebin,playbin)がかなり簡単にしてくれる。より複雑なユースケースでも、設計の柔軟性のおかげで対応できる洞察は気に入っているが、TUI はグラフィカルな何かであって、ffmpeg はただの CLI だ
TUI ツールがあれば素晴らしいと思う。https://github.com/Twinklebear/fbed のようなものだが、機能がもっと完成された形だとよい
Linux システムでは ffmpeg を 静的ビルド するのが好きだ。ディストリビューションのバージョンが古すぎたり、好みのモジュールが抜けていたりすることがあるからだ
このコンテナ化されたバージョンはとても便利だった: https://github.com/wader/static-ffmpeg