集計期間は週間のニコ生統計の1ヶ月分である。2018年からカテゴリタグの割合は今までと変わらないが、1枠30分の割合が少なくなったので来場者数とコメント数の6000以上を除かないすべての放送を対象にした。それに伴い平均値は除外した。来場者数はTS視聴可能時間が来れば増え、TS来場者数を含まずに計算することは困難な仕様なので、翌日(当日)の朝に前日の6時から当日の6時までを取得している。
全放送を対象にしたので改めて以前の放送のデータを使って調べ直している。
niconicoとffmpegのことを中心に書いてる
集計期間は週間のニコ生統計の1ヶ月分である。2018年からカテゴリタグの割合は今までと変わらないが、1枠30分の割合が少なくなったので来場者数とコメント数の6000以上を除かないすべての放送を対象にした。それに伴い平均値は除外した。来場者数はTS視聴可能時間が来れば増え、TS来場者数を含まずに計算することは困難な仕様なので、翌日(当日)の朝に前日の6時から当日の6時までを取得している。
全放送を対象にしたので改めて以前の放送のデータを使って調べ直している。
分離フィールドを交互に挟んだフレームにするseparatefields
フィルタ。フレーム数とフレームレートを2倍に、出力映像の縦解像度を半分にする。トップ、ボトムどちらのフィールドを先に出力するかは動画情報による。もし間違っているのならsetfield
フィルタを先に指定する。
ffmpeg -i input -vf separatefields output
ffplay -i input -vf separatefields
分離フィールドを元の映像に戻すにはweave
フィルタを使う。
ffmpeg -i input -vf separatefields,weave output
ffplay -i input -vf separatefields,weave
各フィールドを縦に並べるにはselect
フィルタで偶数奇数に分割して、hstack
フィルタで縦に並べる。上のフレームが先に動けばトップフィールドファースト。下のフレームが先に動けばボトムフィールドファーストになる。
ffplay -i input -vf separatefields,select='1*mod(n-1\,2)+2*mod(n\,2)':n=2,vstack
上のままだとPTSが一致してないので揃えるならsetpts
フィルタを使う。
ffplay -i input -vf separatefields,select='1*mod(n-1\,2)+2*mod(n\,2)':n=2[1],setpts=PTS-STARTPTS[0v];[1]setpts=PTS-STARTPTS,[0v]vstack
il
フィルタでも同じことができる。PTSリセットが不要なのでこちらの方が扱いやすい。
ffplay -i input -vf il=l=d:c=d
元の映像を左に、フィールドを積み重ねた映像を右に並べる。
ffplay -i input -vf split[0],separatefields,select='1*mod(n-1\,2)+2*mod(n\,2)':n=2,vstack,[0]hstack
23プルダウンを逆テレシネする。
-vf "separatefields,shuffleframes=0 1 4 3 6 5 8 9 -1 -1,setfield=tff,weave,setpts=(N*1001)/(24000*TB),setparams=field_mode=prog" -r 24000/1001 -fps_mode vfr
末尾フレーム抜けを抑えるためにtpad
フィルタで末尾フレームをコピーして増やす。
-vf "tpad=stop=2:stop_mode=1,separatefields,shuffleframes=0 1 4 3 6 5 8 9 -1 -1,setfield=tff,weave,setpts=(N*1001)/(24000*TB),setparams=field_mode=prog" -r 24000/1001 -fps_mode vfr
インターレースの映像でトップとボトムのどちらが最初なのかを指定するsetfield
フィルタ。フィールドオーダーが明示されてないときに使い、フレーム自体に変更を加えない。フィールドタイプを変更するのはfieldorder
フィルタ。おそらく同じことがsetparams
フィルタでもできる。
本格的なフレーム補間はminterpolate
フィルタがあるが、framerate
は前後フレームを平均化してフレーム補間を行う。
公式ドキュメント:FFmpeg Filters Documentation : framerate
ffmpeg -i input -vf framerate=fps=50:interp_start=15:interp_end=240:scene=8.2:flags=scd output
ffplay -i input -vf framerate=50:15:240:8.2:scd
可変フレームか固定フレームかを調べることが出来るvfrdet
(Variable frame rate detect)フィルタ。コンソールには可変フレーム数と固定フレーム数、 PTS間隔の最小値、最大値と平均値が表示される。
2019年10月29日に平均値が追加された
ffmpeg.git/commitdiff : avfilter/vf_vfrdet: also report average delta
公式ドキュメント:FFmpeg Filters Documentation : vfrdet
ffmpeg -i input -an -vf vfrdet -f null -
表示ログの例。固定フレームなら右に総フレーム数、左に可変フレーム数。0開始のフレーム数なので実際のフレーム数は1を足す。
[Parsed_vfrdet_0 @ 000000000295fe80] VFR:0.000000 (0/34046)
可変フレームなら右(15123)が固定フレーム数、左(60562)が可変フレーム数。min, max, avgはPTS間隔の最小値、最大値と平均値。max: 133は前後のPTS間隔の最大値が 133*timebase の意味になる。可変フレーム数はおそらくPTS間隔がその動画の一般的な間隔とは違う前後フレームを可変フレーム数として計算している。
VFR:0.800185 (60562/15123) min: -166 max: 133 avg: 33
5分の1フレーム間引いた可変フレームレートの動画サンプルを作る。
ffmpeg -f lavfi -i testsrc2=d=10 -vf select='mod(n,5)' -c:v ffv1 output.mkv
ffmpeg でのフレームレート設定の違い
特定の映像フレームや音声サンプルを出力する select, aselect
timebaseを調べる方法。
ffprobe -v error -i input -select_streams v:0 -show_entries stream=time_base -of csv=print_section=0
PTS間隔を調べるにはffprobeで調べる方法と、mkvtimestamp_v2で調べる方法があるが、2つの方法が一致するとは限らない。
ffprobeで調べる。
ffprobe -v error -i input -select_streams v:0 -show_entries packet=pts_time -of default=noprint_wrappers=1:nokey=1 > pts_time.txt
フレーム当たりのタイムスタンプミリ秒。
ffmpeg -i input -an -f mkvtimestamp_v2 mkvtimestamp_v2.txt
タイムスタンプファイルを元にPTSを修正するにはmp4fpsmodを使う。ただしバイナリは配布されていない。
mp4fpsmod -t mkvtimestamp_v2.txt input.mp4 -o output.mp4
動画や音声、画像ファイルを調べるのに 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
パケットのKのフレーム番号(0開始)だけ表示する。IDRフレームでないIフレームも含まれる。
ffprobe -v error -i input -select_streams v:0 -show_entries packet=flags -of flat | grep -e K - | sed -e "s/[^0-9]//g"
IDRなキーフレーム番号(0開始)だけ表示する。
ffprobe -v error -i input -select_streams v:0 -show_frames -show_entries frame=key_frame -of flat | grep key_frame=1 - | awk -F '.' '{print $3}'
再生順に表示されるピクチャータイプをテキストに出力する。
ffprobe -v error -i input -show_frames -show_entries frame=pict_type -of csv=print_section=0 > input-pict_type.txt
FFmpegの使用方法より。
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
-tで指定して特定時間時点のフレーム数を取得する。
ffmpeg -t 10 -i input -nostats -c:v copy -f null - 2>&1 | grep -Po "frame= *\K[0-9]*?(?= )"
video – How to get frame number given a timestamp using ffmpeg – Stack Overflow
字幕コーデックを表示する。
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
ffmpeg – Difference between duration from mvhd box and ffprobe for mp4 file – Stack Overflow
映像の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_timeとsignalstats
フィルタから 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
複数の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 )
レジストリを書き換えて右クリックのメニューに登録する。
windows – FFmpeg converting by a context menu entry – Super User
kachurovskiy/VideoContextMenu: Common ffmpeg actions in Windows Explorer context menu
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
HDRに関わるCLL、MDCVのメタデータを出力する。
ffprobe -v error -i input -show_frames -show_entries frame=side_data_list -read_intervals %+#1 -of json
公式ドキュメント : ffprobe Documentation
公式のWiki : FFprobeTips – FFmpeg
2018年11月2日 4.0.3 がリリースされた。アップデート内容は修正ばかりで新しいフィルタは入ってない。てっきり 4.1 が先にリリースするかと思ったがまだこなかった。
Changelog: update release version 4.0.3 – ffmpeg.git/commitdiff
git.videolan.org Git – ffmpeg.git/shortlog : n4.0.3
集計期間は週間のニコ生統計の1ヶ月分である。2018年からカテゴリタグの割合は今までと変わらないが、1枠30分の割合が少なくなったので来場者数とコメント数の6000以上を除かないすべての放送を対象にした。それに伴い平均値は除外した。来場者数はTS視聴可能時間が来れば増え、TS来場者数を含まずに計算することは困難な仕様なので、翌日(当日)の朝に前日の6時から当日の6時までを取得している。
全放送を対象にしたので改めて以前の放送のデータを使って調べ直している。
YUV(A) や RGB(A)、GRAY の数値を16進数で映像にオーバーレイして確認できるdatascope
フィルタの使い方。数値ではなく映像で表示するフィルタにhistogram
フィルタがあるがdatascope
フィルタの方が直感的に任意の場所の数値が読み取れる。ただし表示できる範囲は全画面ではなく1px毎に表示されるので全体の変化を大まかに調べるのには向かない。
ffplay input -vf datascope=s=1280x720:x=0:y=0:mode=0:axis=0
チャンネル数の数だけ 1px に表示される数が変わる。上から順番にチャンネルが割り振られる。チャンネルが増えるだけ表示できる解像度が狭くなる。