テクノロジー · 実用ガイド

FFprobe がカバー画像を選んだ?動画ストリームを確認してからマッピングする

添付画像を除外し、候補数を確認。同じファイルの実際のストリーム番号でプレビューを検証します。

画像を除いた映像候補がゼロ、一つ、複数の場合を分ける図
独自の解説用概念図:候補の数を確認してから選択します。 Watch at Ease

ファイル内の映像ストリームが、実はカバー画像だけという場合があります。スクリプトが最初の映像行を本編とみなすと、画像の寸法を取得したり、違うサムネイルを作ったりします。まずストリーム一覧を確認しましょう。出力コーデックを変えても、正しい入力を選んだ証明にはなりません。

この手順は、書き換わらない完全なローカルファイルから、単一映像ストリームの確認用プレビューを作るためのものです。候補がゼロ、一つ、複数の場合を分けます。ライブラリの画像削除、好みのカメラアングルの自動判定、ライブ配信のマッピング修復は対象外です。

1. 絞り込む前に一覧を保存する

パス、サイズ、更新時刻、FFmpeg と ffprobe のビルドを記録します。他のアプリがダウンロードや書き換えを続けている場合は特に、変化しないコピーを使ってください。ffprobe -v error -show_streams -show_format -of json "INPUT" を実行し、標準出力、標準エラー、終了コードを保存します。INPUT は実際のパスに置き換えます。プローブ失敗は別の問題です。不完全な JSON や空の出力を成功扱いしません。

各ストリームの index、codec_type、codec_name、寸法、タグ、disposition を確認します。あるカバーが MJPEG だったからといって、MJPEG をすべて除外してはいけません。フレーム数の欠落やゼロに見えるフレームレートだけでも本編は特定できません。独立した Stack Overflow の質問には、H.264 映像より前に添付 MJPEG 画像が並ぶ例があります。

2. 選ぶ前に候補数を確かめる

ffprobe -v error -select_streams V -show_entries stream=index,codec_name,width,height:stream_disposition=default,attached_pic:stream_tags=title,language -of json "INPUT" を実行します。大文字 V は意図した指定です。成功を確認してから streams 配列を読み、存在しない任意項目は不明のまま扱います。認識された画像は除外できますが、誤ったタグの静止画をすべて識別できるわけではありません。

ゼロなら一覧を残して動画プレビューを停止します。カバー付き音声ファイルなら正常な結果かもしれません。一つなら実際の index を保持し、画面を確認します。複数ならラベル、寸法、プレビューを比較して目的のトラックを選びます。default フラグや高解像度は手掛かりであり、編集上の目的を決めるものではありません。曖昧さを隠すためだけに :0 を付けないでください。

3. 配列位置ではなく index を引き継ぐ

絞り込み後の JSON に一行だけあり、index: 1 とします。配列上は streams[0] でも、入力ストリーム番号は 1 のままです。同じファイルを FFmpeg の最初の入力にするなら、明示的なマップは 0:1 です。前の 0 は入力ファイル、後ろの 1 はそのストリームを示します。スクリプトでは index と選んだファイル、選択理由を一緒に保持します。

ファイル、入力順、デマルチプレクサーの設定が変わったら再プローブします。ライブ URL、更新されるプレイリスト、録画中のファイルにこの手順をそのまま使わないでください。別のオープンで一覧が変わる可能性があります。Jellyfin のライブ TV 報告には、この列挙のずれが記載されています。個別の報告であり、すべてのローカル形式や配信で同じ動作になるという意味ではありません。

4. 別ファイルでプレビューし、失敗の種類を分ける

確認済み番号が 1 なら、ffmpeg -hide_banner -loglevel error -nostdin -n -i "INPUT" -map 0:1 -frames:v 1 "preview-check.jpg" で画像を作ります。番号は実際の値にし、未使用の出力名を使います。これは音声や他のトラックを含まない、一枚の画像だけを作るコマンドです。開いて見覚えのある内容が目的の動画か確認します。冒頭が黒なら、後の位置を別途サンプルにして確認できます。

画像は正しいのにコーデックやビットストリームフィルターで失敗するなら、カバーを削除せずコマンド全体を調べます。Immich の過去の障害では、HEVC メタデータフィルターが MJPEG 添付画像を含む映像ストリームに広く適用されていました。承認された修正は対象を選択済みストリームに限定し、2026 年 5 月 1 日にマージされました。これはオプションの適用範囲という別の問題の例で、現在の全環境に同じ不具合がある証拠ではありません。

5. 検証した範囲を明確にする

合成テストには Ubuntu FFmpeg 6.1.1-3ubuntu5 を使いました。カバー付き MP3 は v が一つ、V がゼロ。音声が先の MP4 は V 候補が一つで、配列位置は 0 でも絶対番号は 1 でした。映像二本入り MP4 は候補が二つとなり、人が選ぶまで停止しました。単一候補のプレビューは開け、選択ストリームの全体デコードは終了コード 0。三つの入力ファイルのハッシュは変わりませんでした。

Immich 報告の DJI ファイル、ライブ入力、すべての FFmpeg ビルドを試したわけではありません。実際の作業では一覧、番号、正確なコマンド、結果を保存します。追加のデコード確認は ffmpeg -hide_banner -loglevel error -nostdin -i "INPUT" -map 0:1 -f null - です。番号を正しく置き換えてください。選択ストリームを読むため、動画全体の処理時間がかかる場合があります。終了コードと標準エラーを確認します。一枚の正しい画像や正常デコードだけでは、好みのアングルや後の書き出しで全トラックを保持したことまでは証明できません。

配列位置ゼロが入力ストリーム番号一を参照する例
独自の解説用概念図:JSON の配列位置と入力ストリーム番号は別の座標です。 Watch at Ease