動画や音声、画像ファイルを調べるのに ffmpeg で表示される以上のことを調べるときに使う ffprobe の使い方。出力フォーマット指定ができるので json、xml、iniからパースすれば正規表現で無理に取る必要はない。

ffprobe では-vf、-af、-filter_complexなどが使えないので lavfi デバイスで読み込み、そこからフィルタを使う。よって映像は rawvideo、音声は pcm_f32le になり元データとは異なるのに注意。デコーダの指定もできないので一部のピクセルフォーマット、具体的には VP9 の YUVA420 をデコードできない。

VP9(libvpx-vp9)のエンコード設定について | アルファチャンネル付き動画を読み込む

ffmpeg 5.0からcsv出力が直った。
ffprobe: add missing separator when printing side data in compact output · FFmpeg/FFmpeg@131dbb9

ffmpeg 5.1から出力指定の-oが追加され、無指定は今までと同じ標準出力、-oでファイル出力できるようになった。ファイル形式は拡張子から判断しないので-ofで指定する。
ffprobe: add -o option · FFmpeg/FFmpeg@ff07492

基本コマンド

オプションを何も付けなければ ffmpeg と同じ表示になる。
ffprobe -i input

コンテナストリームの情報を表示する。これが基本の出力内容になりこれから必要なものだけを出力したり、パケット単位で出力したりもできる。
ffprobe -i input -show_streams

ffmpeg などで表示される configure オプションやライブラリのバージョンは-hide_bannerで非表示にできる。
ffprobe -hide_banner -i input -show_streams

ffprobe の内容だけが必要なら-v errorを付ける。
ffprobe -v error -i input -show_streams

JSON に出力する。
ffprobe -v error -i input -show_streams -of json > output.json

CSV に出力する。目視なら CSV 出力が読みやすい。
ffprobe -v error -i input -show_streams -of csv > output.csv

解像度を表示する。カンマ区切りで複数指定できる。
ffprobe -v error -i input -select_streams v:0 -show_entries stream=width,height

フレームレート、映像の開始時間、映像の時間を表示する。
ffprobe -v error -i input -select_streams v:0 -show_entries stream=r_frame_rate,start_time,duration

pts_time,pict_typeだけを表示する。
ffprobe -v error -i input -select_streams v:0 -show_frames -show_entries frame=pts_time,pict_type -of csv=p=0

Iフレームの時間だけ表示する。
ffprobe -v error -i input -select_streams v:0 -show_frames -show_entries frame=pts_time,pict_type -of csv=print_section=0 | awk -F',' '/I/ {print $1}'

Iフレームのフレーム番号(0開始)だけ表示する。
ffprobe -v error -i input -select_streams v:0 -show_entries frame=pict_type -of flat | grep -e \\\"I\\\" - |sed -e "s/[^0-9]//g"

キーフレームの時間だけ表示する。
ffprobe -v error -i input -select_streams v:0 -show_entries packet=pts_time,flags -of csv=print_section=0 | awk -F',' '/K/ {print $1}'

Extracting I frames time stamps : ffmpeg
How to get time stamp of closest keyframe before a given timestamp with FFmpeg? – Super User

キーフレームのフレーム番号(0開始)だけ表示する。
ffprobe -v error -i input -select_streams v:0 -show_entries packet=flags -of flat | grep -e K - | sed -e "s/[^0-9]//g"

再生順に表示されるピクチャータイプをテキストに出力する。
ffprobe -v error -i input -show_frames -show_entries frame=pict_type -of csv=print_section=0 > input-pict_type.txt

FFmpegの使用方法より。

  • I:Iフレーム (Intra coded frame)
  • P:Pフレーム (Predicted frame)
  • B:Bフレーム (Bidirectional predicted picture)
  • S:(switch frame)
  • SI:(switching I frame)
  • SP:(switching P frame)
  • BI:(special intra frame)

Video compression picture types – Wikipedia
x264 – Get frame type for specific frame using ffmpeg – Stack Overflow

nb_read_packets だけを表示する。1スタートの総パケット数なのでそのままの意味になる。
ffprobe -v error -i input -select_streams v:0 -show_entries stream=nb_read_packets -count_packets -of csv=p=0

メタデータを元としたnb_framesだけを表示する。1スタートの総フレーム数なのでそのままの意味になる。処理が速い。
ffprobe -v error -i input -select_streams v:0 -show_entries stream=nb_frames -of csv=p=0

デコードしたすべてのフレーム数nb_read_framesも表示する。
ffprobe -v error -i input -select_streams v:0 -show_entries stream=nb_frames,nb_read_frames -count_frames -of default=noprint_wrappers=1:nokey=0

ffprobe – FFMPEG nb_frames vs nb_read_frames – Stack Overflow

-skip_frame nokeyを使ってキーフレームの時間だけ表示する。
ffprobe -v error -i input -select_streams v:0 -skip_frame nokey -show_entries frame=pts_time -of csv=print_section=0

字幕コーデックを表示する。
ffprobe -v error -i input -select_streams s -show_entries stream=index,disposition=forced,stream_tags=language,codec_name -of csv=nk=1:p=0

再生時に強制表示しているのを調べるにはDISPOSITION:default=1を確認する。
ffprobe -v error -i input -select_streams s -show_entries stream

Print subtitles type with ffprobe : ffmpeg

フォーマット(コンテナ)の時間。-sexagesimalをつければ読みやすくなる。
ffprobe -v error -i input -show_entries format=duration -of default=noprint_wrappers=1:nokey=1

ビデオストリームの時間だけを表示する。
ffprobe -v error -i input -select_streams v:0 -show_entries stream=duration -of default=noprint_wrappers=1:nokey=1

映像のtimebaseを表示する。
ffprobe -v error -i input -select_streams v:0 -show_entries stream=time_base -of csv=print_section=0

デコードできるフレーム数、時間を調べるにはログの最後の行(frame=34047 fps=3280 q=-0.0 Lsize=N/A time=00:23:40.05 bitrate=N/A speed= 137x)を見る。
ffmpeg -i input -f null -

パケット毎のpts_time,dts_time,size,flags(フレームタイプ, K_ がキーフレーム)を開始から10秒間 log.txt に出力する。
ffprobe -v error -i input -select_streams v:0 -show_entries packet=pts_time,dts_time,size,flags -read_intervals "%+10" > log.txt

トラック別の音声のチャンネルレイアウトと言語を調べる。
ffprobe -v error -i input -select_streams a -show_entries stream=channel_layout:stream_tags=language -of json > log.json

pts_timesignalstatsフィルタから YMIN を開始から1秒間 YMIN.txt に出力する。
ffprobe -v error -f lavfi -i movie=input.mp4,signalstats -show_entries packet=pts_time -show_entries packet_tags=lavfi.signalstats.YMIN -read_intervals "%1" > YMIN.txt
ffprobe -v error -f lavfi -i movie=input.mp4,signalstats -show_entries packet=pts_time -show_entries packet_tags=lavfi.signalstats.YMIN -read_intervals "%1" -of csv > YMIN.csv

YUV のデータを数値で表示する signalstats

複数のpacket_tags=lavfi.XXXをつなげるにはカンマ,でつなげる。
ffprobe -v error -f lavfi -i movie=input.mp4,signalstats -show_entries packet=pts_time -show_entries packet_tags=lavfi.signalstats.YMIN,lavfi.signalstats.YMAX -read_intervals "%1" > YMIN-YMAX.txt
ffprobe -v error -f lavfi -i movie=input.mp4,signalstats -show_entries packet=pts_time -show_entries packet_tags=lavfi.signalstats.YMIN,lavfi.signalstats.YMAX -read_intervals "%1" -of csv > YMIN-YMAX.csv

packet_tagsの数値をフィルタするにはmetadata、ametadatフィルタを使う。
ffprobe -v error -f lavfi -i movie=input.mp4,scdet,metadata=select:key=lavfi.scd.score:value=10:function=greater -select_streams v:0 -show_entries packet=pts_time -show_entries packet_tags=lavfi.scd.score -of csv > output.csv

すべてのメタデータを一度に出力するには-show_entries frame=pkt_pts_time:frame_tagsをつける。
ffprobe -v error -f lavfi -i movie=input.mp4,signalstats -select_streams v:0 -show_entries frame=pkt_pts_time:frame_tags -read_intervals "%1" > signalstats.txt

メタデータをコンソールに表示する metadata, ametadata
lavfi デバイスで読み込む方法は movie, amovie 入力の設定内容を参照。
packet_tagsで使えるフィルタは meta | ニコラボで検索。

16進数 ASCII のテキスト(show_data.txt)にリダイレクトする。コンソールにそのまま表示するとデータ量が多くおそらく固まるので必ずリダイレクトさせる。
ffprobe -v error -i img.png -show_packets -show_data > show_data.txt

チャプターをXML形式で出力する。
ffprobe -i input -show_chapters -of xml > chapters.xml

複数ファイルの処理に便利な右クリックメニューの「送る」に登録する。エクスプローラで「shell:sendto」を開いてバットファイルを置く。

for %%f in (%*) do (
  echo %%f
  ffprobe -v error -f lavfi -i movie=%%~xnf,scdet,metadata=select:key=lavfi.scd.score:value=10:function=greater -select_streams v:0 -show_entries packet=pts_time -show_entries packet_tags=lavfi.scd.score -of csv > %%~xnf.csv
)

ffmpegから標準入力する。適宜コピーするストリームを指定する。
ffmpeg -ss 10 -i input -t 10 -c copy -an -sn -dn -f nut - | ffprobe -f lavfi -i movie=pipe\\:0,idet -show_entries packet_tags=lavfi.idet.multiple.current_frame -of json > foo.json

公式ドキュメント : ffprobe Documentation
公式のWiki : FFprobeTips – FFmpeg

オプション

  • -unit
    start_time, duration, bit_rate, sample_rateに単位が付く
  • -prefix
    start_time, sample_rate, bit_rateの表示が2進接頭辞(K)表示に変わる
  • -sexagesimal
    start_time, durationの書式が60進数の時間表示に変わる
  • -pretty
    表示が KHz, Kbit/s になり読みやすくなる
  • -print_format, of
    default, csv, flat, ini, json, xmlが使える。詳しくは後述
  • -select_streams
    ストリーム単位で表示。-show_streams, -show_packetsなどと併用する。ffprobeでは使えない-mapと同じようにv, a, v:0, a:0などと指定する
  • -sections
    セクション階層の表示
  • -show_data
    パケット毎のデータを16進数 ASCII のテキストで表示。-show_packetsを指定すればパケットのデータを出力し、-show_streamsを指定すればコーデックのextradataを出力する
  • -show_data_hash
    -show_packetsを指定すればパケット毎の指定したアルゴリズムのハッシュを表示。-show_streamsを指定すればコーデックのextradata_hash を表示
  • -show_error
    “ERROR”セクションにエラーを表示。何もなければ出力しない
  • -show_format
    “FORMAT”セクションにコンテナフォーマットを表示。シンプルにデータ表示されるので使い勝手がよい
    表示内容はfilename, nb_streams, nb_programs, format_name, format_long_name, start_time, duration, size, bit_rate, probe_score
  • -show_frames
    フレーム単位で表示
  • -show_entries
    表示する内容の指定。section_entries を指定しなければすべてを表示。詳しくは後述
  • -show_packets
    パケット単位で表示
  • -show_programs
    “PROGRAM”セクションをプログラム内容を表示。HLSなどのプレイリストで使える
    表示内容はprogram_id, program_num, nb_streams, pmt_pid, pcr_pid, start_pts, start_time, end_pts, end_time, TAG:service_name, TAG:service_provider
    表示例:ffprobe show_programs sample
  • -show_streams
    ストリーム内容の表示
  • -show_chapters
    “CHAPTER”セクションにチャプター別のデータを表示
    表示内容はid, time_base, start, start_time, end, end_time, TAG:title
    チャプターを書き込む方法:ffmpeg でメタデータを加える
  • -count_frames
    フレーム数の表示。-show_entries streamと併用。nb_read_framesに表示される。実際にすべてのフレームをデコードするので時間がかかる
  • -count_packets
    パケット数の表示。-show_entries streamと併用。nb_read_packetsに表示される。実際にすべてのパケットをデコードするので時間がかかる
  • -show_program_version
    “PROGRAM_VERSION”セクションにプログラムのバージョン表示
    表示内容はversion, copyright, compiler_ident, configuration
  • -show_library_versions
    “LIBRARY_VERSION”セクションにライブラリのバージョン表示
    表示内容はlibavutil, libavcodec, libavformat, libavdevice, libavfilter, libswscale, libswresample, libpostproc
  • -show_versions
    -show_program_version, -show_library_versionsを同時指定
  • -show_pixel_formats
    “PIXEL_FORMAT”セクションに対応したピクセルフォーマットを表示
  • -show_optional_fields
    -ofでjosnやxmlを指定したときに一部のフィールド出力を制御する
    • -1:自動。既定値
    • 0:無効
    • 1:有効
  • -bitexact
    特定のビルドに依存しない出力に役立つbitexact出力を強制する。既定値は無効
  • -read_intervals
    調べるデータの範囲指定。パケット単位と秒単位がある。詳しくは後述
  • -i
    入力ファイルの指定。無指定でも入力ファイルとして扱える。ffplay と同じ

print_format, of

default

無指定だとこれになり、対応する FORMAT, STREAM と PROGRAM_STREAM セクションにメタデータタグを表示する。

表示形式
[SECTION]
key1=val1
...
keyN=valN
[/SECTION]

結果の1つだけを他のプログラムに再利用するときには、-of default=nk=1:nw=1をつける。

オプション内容

  • nokey, nk[boolean]
    有効にすると key=val の key を表示しない
    既定値:0(表示する)
  • noprint_wrappers, nw[boolean]
    有効にするとセクション名を表示しない
    既定値:0(表示する)
compact, csv

1つのセクションを1行でカンマ区切りに表示し、対応する “FORMAT”, “STREAM” セクションのメタデータタグを表示する。メタデータタグキーが表示される場合は接頭辞 “tag:” が付く。

表示形式
section|key1=val1| ... |keyN=valN

結果の1つだけを他のプログラムに再利用するときには、-of csv=print_section=0をつける。

オプション内容

  • item_sep, s[string]
    セパレータの指定
    既定値:”,”(カンマ)
  • nokey, nk[boolean]
    有効にすると key=val の key を表示しない
    既定値:1(表示しない)
  • escape, e[string]
    エスケープ方法の指定
    • c
      C言語のようなエスケープ。既定値
    • csv
      CSVのようなエスケープ
    • none
      エスケープしない
  • rint_section, p[boolean]
    セクション名の表示指定
    既定値:1(表示する)
flat

スクリプトと連携しやすい形式。key=value 形式が “streams.stream.3.tags.foo=bar” 形式になる。

オプション内容

  • sep_char, s[string]
    セパレータの指定
    既定値:”.”(ピリオド)
  • hierarchical, h[boolean]
    セクション名の表示指定
    既定値:1(表示する)
ini

ini 形式で表示する。

  • メタデータファイルは UTF-8 でエンコードされた INI 形式のテキストファイルで構成される
  • ‘.’はサブグループのセパレータである
  • 改行の ‘t’, ‘f’, ‘b’ 文字はエスケープされる
  • ‘’ はエスケープ文字である
  • ‘#’ の後ろはコメント扱いになる
  • ‘=’ は key/value のセパレータである
  • ‘:’ は使われないが key/value セパレータをパースする

オプション内容
hierarchical, h[boolean]
セクション名の表示指定
既定値:1(表示する)

json

json 形式で表示する。

オプション内容
compact, c[boolean]
有効にすると1行表示になる
既定値:0(1行で表示しない)

xml

xml 形式で表示する。

  • fully_qualified, q[boolean]
    完全に XSD ファイルの仕様に沿った形で表示する
    既定値:0(厳格ではない)
  • xsd_compliant, x[boolean]
    完全に XSD ファイルの仕様に沿った形か確認する。有効にするとfully_qualified, qも有効になる
    既定値:0(確認しない)

show_entries

-show_entries foo 形式で指定。このfooに入るのはformat, frame, packet, packet_tags, stream, stream_tagsである。frameはフレーム毎、packet, packet_tagsはパケット毎なのでログが長くなる。このように内容を抜粋できるのは-show_entriesだけ。

書式
LOCAL_SECTION_ENTRIES ::= SECTION_ENTRY_NAME[,LOCAL_SECTION_ENTRIES]
SECTION_ENTRY ::= SECTION_NAME[=[LOCAL_SECTION_ENTRIES]]
SECTION_ENTRIES ::= SECTION_ENTRY[:SECTION_ENTRIES]

fooの中から抜粋したいものだけbar,hoge,piyoをカンマ,で並べる。
-show_entries foo=bar,hoge,piyo

複数のfooはコロン:でつなげる。
-show_entries foo1=bar1,hoge,piyo:foo2=bar2

パケットにはpts_time,duration_time,stream_indexを表示し、ストリームにはindex,codec_typeを表示する。
-show_entries packet=pts_time,duration_time,stream_index:stream=index,codec_type

formatセクションはすべてを表示し、formatセクションではcodec_typeだけを表示する。
-show_entries format:stream=codec_type

format_tagsだけ表示。
-show_entries format_tags

stream, formatセクションですべてのタグを表示する。
-show_entries stream_tags:format_tags

streamセクションで表示可能ならタイトルタグを表示する。
-show_entries stream_tags=title

packetセクションで表示可能ならsignalstatsフィルタのYAVGを表示する。
-show_entries packet_tags=lavfi.signalstats.YAVG

ストリームのヘッダ情報は-show_entries stream。コンテナフォーマットの情報は-show_entries format。パケット毎の-show_entries packet、フレーム毎の-show_entries show_framesは適宜-select_streamsで必要なストリームを選択する。フィルタのメタデータを調べるのが-show_entries packet_tags

-show_entries streamの表示例。coded_widthcoded_heightは x264 などの特定のエンコーダなどで16の倍数である必要がありそれに併せて、適切な余白をつけてデコーダのクロッピング値を保存している。コード化されたサイズはトリミング前のサイズになる。

video – What’s the difference between coded width and width in FFprobe – Super User

-show_entries packetの抜粋。パケット毎に表示される。frameセクションよりpacketセクションのほうが速いので同じ内容を取るpts_time、キーフレームを調べるframekey_framepacketflagsflagsほうがよさそう。

-show_entries formatの表示例。

-select_streams v:0 -show_framesの表示例。途中から映像のアスペクト比が変わるsample_aspect_ratioを調べるにはframeセクションを使う。

-select_streams a:0 -show_framesの表示例。

-show_entries format_tagsの表示例。

read_intervals

書式
INTERVAL ::= [START|+START_OFFSET][%[END|+END_OFFSET]]
INTERVALS ::= INTERVAL[,INTERVALS]

  • 実際に使うには “” で数値を囲む
  • 指定した値は完璧ではないので多少の余分を持って指定する
  • %” から左が1セクション(開始位置)、右が2セクション(終了位置)
  • 1セクションが無記入なら最初から、2セクションが無記入なら最後まで
  • +” は相対位置、無指定は絶対位置
  • #” はパケット数、数値なら時間(ss, hh:mm:ss 形式)
  • 複数の位置を指定するには “,” でつなげる

10秒から始まり、そこから20秒間(相対位置)と、1分30秒から1分45秒(絶対位置)までの例。
-read_intervals 10%+20,01:30%01:45

1分23秒から始まり、そこから42パケット(相対位置)。
-read_intervals 01:23%+#42

開始0秒(1セクション無指定)から3パケットまで。
-read_intervals %+#3

開始0秒(1セクション無指定)から20秒まで。
-read_intervals %+20

開始0秒(1セクション無指定)から2分30秒まで。
-read_intervals %02:30

One thought on “ffprobe の使い方”

コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)