Quantcast
Channel: FFmpeg | ニコラボ
Viewing all 310 articles
Browse latest View live

新しい映像の品質評価 libvmaf

$
0
0

Netflix が使っているエンコードされる前と後の動画の品質評価に使われている VMAF(Video Multimethod Assessment Fusion)スコアを ffmpeg で調べる。以前の記事に異なる解像度でも調べられると書いていたが間違いである。同じ解像度でないと調べられない。対応フォーマットは yuv420p, yuv422p, yuv444p, yuv420p10le, yuv422p10le, yuv444p10le になる。外部ライブラリフィルタなので別途インストールが必要である。しかし現在のところ Windows 環境ではおそらくリンクできていない。

2つの映像の画質評価をする SSIM
新しい映像の動きの評価 vmafmotion

VMAF の解説記事

基本コマンド

最終的な品質評価になる VMAF スコアは 100 が最高画質。配信向けには 80 程度を目標とするビットレートになるようにする。ログファイルに書いてある adm2, vif_scalex スコアは VMAF スコアの元となり 0(最低画質)から 1(最高画質)。motion2 は 0(動かない映像)から 20(ものすごく動く映像)。
ffmpeg -i main.mp4 -i reference.mp4 -filter_complex "libvmaf=model_path=vmaf_v0.6.1.pkl:log_path=log.xml:log_fmt=xml:enable_transform=0:phone_model=0:psnr=0:ssim=0:ms_ssim=0:pool=mean" -an -f null -
ffmpeg -i main.mp4 -i reference.mp4 -filter_complex "libvmaf=vmaf_v0.6.1.pkl:log.xml:xml:0:0:0:0:0:mean" -an -f null -

エンコードが終わるとコンソールの最後に以下のような結果が表示される。ログファイルで出力する場合はフレーム毎に指定オプション内容が出力される。Exec FPS は処理速度。

Exec FPS: 4.940972
VMAF score = 96.147066

リサイズした前後での VMAF スコアを調べるには同じアルゴリズムでエンコードする前の動画をフィルタでリサイズして調べる。

リサイズする前が 1920 x 1080、リサイズした後が 1280 x 720 で、リサイズ方法が scale フィルタの場合。
ffmpeg -i original.mp4 -vf scale=1280:720 -acodec copy 720p.mp4
ffmpeg -i original.mp4 -i 720p.mp4 -filter_complex "scale=1280:720,[1]libvmaf" -an -f null -

リサイズのアルゴリズムについては以下を参照。
Windows の ffmpeg で生放送する方法 : scale
Zライブラリを使ったリサイズフィルタ zscale

YUV の動画を比較する場合。
ffmpeg -video_size 1280x720 -pixel_format yuv420p -framerate 30 -i original.yuv -video_size 1280x720 -pixel_format yuv420p -framerate 30 -i reference.yuv -filter_complex libvmaf -an -f null -

公式ドキュメント:FFmpeg Filters Documentation : libvmaf

オプション

調べる内容を増やすほど処理速度が遅くなる。

  • model_path[string]
    SVM(Support Vector Machines) で使われるモデルのパス指定
    既定値:”vmaf_v0.6.1.pkl”(インストールされているパス)
  • log_path[string]
    出力されるログファイルのパス指定
    既定値:無指定(指定するとログファイルが出力される)
  • log_fmt[string]
    ログファイルのフォーマット指定。xml, json が指定できる
    既定値:xml
  • enable_transform[boolean]
    transform を計算する
    既定値:0
  • phone_model[boolean]
    電話モデルを呼び出してノートPCやTVに適した通常より高い VMAFスコアを計算する。携帯電話などのモバイル端末は画面サイズが大きくなく視聴距離が近いためにビットレートを高くしてもそれほど高画質に見えないからである。詳細は ここを参照
    既定値:0(ノートPC、TV向け)
  • psnr[boolean]
    psnr も一緒にを計算する。60 が最高画質
    既定値:0
  • ssim[boolean]
    ssim も一緒にを計算する。1 が最高画質
    既定値:0
  • ms_ssim[boolean]
    ms_ssim も一緒にを計算する。1 が最高画質
    既定値:0
  • pool[string]
    VMAFスコアの計算方法。mean, min, harmonic mean(調和平均) が指定できる
    既定値:”mean”

2ファイル入力するフィルタの挙動設定 framesync にも対応している。


ffplay で時間とフレーム数を表示する

$
0
0

drawtext フィルタを使って時間とフレーム数を表示する方法。ただしこの方法は固定フレームでしか使えない。30000/1001 などの部分を動画のフレーム数で指定する。表示される内容は左から秒時間、hms時間、フレーム数、フレーム数を5で割った余り、ピクチャータイプ。

30000/1001 fps の動画
ffplay -i input -vf drawtext="fontsize=30:box=1:boxcolor=white@0.5:fontcolor=black:fontfile='C\://WINDOWS/Fonts/arial.ttf':text='%{pts\:flt}-%{pts\:hms}-%{eif\:t*(30000/1001)\:d}-%{eif\:mod(t*(30000/1001),5)\:d}-%{pict_type}'"

24000/1001 fps の動画
ffplay -i input -vf drawtext="fontsize=30:box=1:boxcolor=white@0.5:fontcolor=black:fontfile='C\://WINDOWS/Fonts/arial.ttf':text='%{pts\:flt}-%{pts\:hms}-%{eif\:t*(24000/1001)\:d}-%{eif\:mod(t*(24000/1001),5)\:d}-%{pict_type}'"

上のコマンドを使っても時間やフレーム数が正しく表示されない動画。時に .ts ファイルなどの場合、ずれる時間を先に調べ下のコマンドで再生する。
ffmpeg -i input.ts -copyts -vf drawtext="fontsize=30:box=1:boxcolor=white:fontcolor=black:fontfile='C\://WINDOWS/Fonts/arial.ttf':text='%{pts\:flt}-%{eif\:t*(30000/1001)\:d}-%{eif\:mod(t*(30000/1001),5)\:d}-%{pict_type}'" -vframes 1 output.jpg

画像に表示される秒時間を setpts フィルタに指定する。
ffmpeg -i input.ts -vf "setpts=PTS-秒時間/TB,drawtext="fontsize=30:box=1:boxcolor=white:fontcolor=black:fontfile='C\://WINDOWS/Fonts/arial.ttf':text='%{pts\:hms}-%{eif\:t*(30000/1001)\:d}-%{eif\:mod(t*(30000/1001),5)\:d}-%{pict_type}'"

.ts ファイルのフレームを tile フィルタで前フレームを下に表示しながら確認する。適宜出力解像度を scale フィルタで指定する。
ffplay -i input.ts -vf "setpts=PTS-7276.221467/TB,drawtext="fontsize=130:box=1:boxcolor=white:fontcolor=black:fontfile='C\://WINDOWS/Fonts/arial.ttf':text='%{pts\:hms}-%{eif\:t*(30000/1001)\:d}-%{eif\:mod(t*(30000/1001),5)\:d}-%{pict_type}'",crop=iw:3*ih/4:0:0,split[a],tile=8x1:overlap=8,scale=1440:-1,[a]vstack

調べたフレームから trim フィルタを使ってカットして連結するもできる。ただしこの方法だと音声はカットできないので atrim フィルタを使いフレーム数を pts 変換、またはサンプル数に変換する。さらに concat フィルタで連結する場合、動画時間が長くなるほど、カット数が多くなるほど時間がかかる。

参考記事
windows – Displaying the current frame of a video after skipping using drawtext/start_number not evaluation any variables – Stack Overflow

ffmpeg で音楽CDをリップする libcdio の使い方

$
0
0

libcdio で手軽に音楽CDを再生したり、リッピングすることができるが、個別に時間指定しないとトラック毎にファイルが出力されないので他のプログラムと併用しないとあまり実用的ではない。

Zeranoe は非対応なので「お気に入りの動画を携帯で見よう」から保存する。
FFmpegダウンロード お気に入りの動画を携帯で見よう

コマンドサンプル

再生(ドライブレターを指定する)。
ffplay -f libcdio -ss 0 -i D:

エンコードする。
ffmpeg -f libcdio -ss 0 -i D: output.wav
ffmpeg -f libcdio -ss 0 -i D: output.flac

エンコード(開始から3分の音楽ファイル)。
ffmpeg -f libcdio -ss 0 -i D: -t 180 output.wav
ffmpeg -f libcdio -ss 0 -i D: -t 180 output.flac

トラック情報のメタデータを出力する。例えば以下のような ffmetadata.txt が出力されたとすると、カットする時間は START*TIMEBASE がそのトラックの開始時間になり、END*TIMEBASE がそのトラックの終了時間になる。
ffmpeg -f libcdio -i D: -f ffmetadata ffmetadata.txt

チャプター情報を json で出力する。json を見てカットする時間は start_time がそのトラックの開始時間になり、end_time がそのトラックの終了時間になる。
ffprobe -f libcdio -i D: -print_format json -show_chapters -loglevel error > chapters.json

チャプター毎に分割する例に mkvmerge を使う方法がある。分割されたファイル名は chapterd-001.mkv のような連番になる。
ffmpeg -f libcdio -ss 0 -i D: -map_metadata 0 -acodec flac output.mkv
mkvmerge -o chapterd.mkv --split chapters:all output.mkv

MKVToolNix Downloads – Matroska tools for Linux/Unix and Windows
MKVToolNix Download – VideoHelp : Windows はこちらから保存する。

関連記事

libcdioのコンパイル&インストール (libcdio-0.90以降) お気に入りの動画を携帯で見よう
Is there an elegant way to split a file by chapter using ffmpeg? – Stack Overflow

-ss 0 を指定しないと読み込めないバグが昔から報告されているが直る気配がない。
#3815 (libcdio only works with -ss 00) – FFmpeg

公式ドキュメント

FFmpeg Devices Documentation :: libcdio

個別チャンネルの値を映像の場所毎に確認できる datascope

$
0
0

YUV(A) や RGB(A)、GRAY の数値を16進数で映像にオーバーレイして確認できる datascope フィルタの使い方。数値ではなく映像で表示するフィルタに histogram フィルタがあるが datascope フィルタの方が直感的に任意の場所の数値が読み取れる。ただし表示できる範囲は全画面ではなく1px毎に表示されるので全体の変化を大まかに調べるのには向かない。

ffmpeg でヒストグラムを表示する

基本コマンド

ffplay input -vf datascope=s=1280x720:x=0:y=0:mode=0:axis=0

チャンネル数の数だけ 1px に表示される数が変わる。上から順番にチャンネルが割り振られる。チャンネルが増えるだけ表示できる解像度が狭くなる。

(4:6)から調べた datascope の出力サンプル

ffmpeg -f lavfi -i testsrc2=d=1,format=rgb24 -vf datascope=s=340x380:mode=color:x=4:y=6:axis=1 -vframes 1 datascope.png

入力映像が3チャンネル、8ビットの場合以下の解像度になる。

  • 横のpx数*20-2+22
  • 縦のpx数*36-2+22

上と左に表示される座標値を crop フィルタでカットする場合は左上 22x22p をカットする。入力解像度が奇数になる場合は format=rgb24, format=yuv444p で入力フォーマットを変更する。右と下をぎりぎりにカットする場合は、右に3px、下に7pxをカットする。
ffmpeg -f lavfi -i testsrc2=d=1,format=rgb24 -vf datascope=s=340x380:mode=color:x=4:y=6:axis=1,crop=340-22-3:380-22-7:22:22 -vframes 1 datascope-crop.png

縦横の比率を合わせる場合

scale2ref フィルタを使って解像度を揃える。

testsrc2 を crop したもの 16x10p

ffmpeg -f lavfi -i testsrc2=d=1,crop=16:10:4:6 -vframes 1 testsrc2-crop.png

datascope フィルタ後の解像度は 340(16*20-2+22)x380(10*36-2+22) になり、そこから左上の22x22px、右に3px、下に7pxをカットする。

縦そのままに横を伸ばす

ffmpeg -i testsrc2-crop.png -filter_complex split[a],datascope=s=340x380:mode=color:axis=1,crop=340-22-3:380-22-7:22:22[b];[b][a]scale2ref='if(gt(iw,ih),(iw*20-2-3)*dar,iw*20-2-3):if(gt(ih,iw),(ih*36-2-7)*dar,ih*36-2-7)'[b0][a0] -map [b0] datascope-scale0.png -map [a0] -f null -
横をそのままに縦を縮める

ffmpeg -i testsrc2-crop.png -filter_complex split[a],datascope=s=340x380:mode=color:axis=1,crop=340-22-3:380-22-7:22:22[b];[b][a]scale2ref='if(gt(iw,ih),iw*20-5,(iw*20-5)/dar):if(gt(ih,iw),ih*36-9,(ih*36-9)/dar)'[b0][a0] -map [b0] datascope-scale1.png -map [a0] -f null -

公式ドキュメント:FFmpeg Filters Documentation : datascope

オプション

  • size, s[image_size]
    出力解像度。表示する座標に横は20倍以上、縦は1チャンネルあたり12倍以上必要
    既定値。hd720(1280×720)
  • x[int]
    左上を 0 とした表示する横軸の座標指定
    既定値:0
  • y[int]
    左上を 0 とした表示する縦軸の座標指定
    既定値:0
  • mode[int] 表示モードの指定
    • 0, mono:黒背景に白色数字。既定値
    • 1, color:黒背景に元映像の色数字
    • 2, color2:元映像の背景に数字を読みやすい色に変える
  • axis[boolean]
    既定値:0(無効)
    上と左に座標の値を表示する。有効化すると表示範囲が狭まる
  • opacity[float]
    背景の透過指定
    既定値:0.75
    範囲:0 から 1 まで

ffmpeg 4.0 リリース

$
0
0

2018年4月20日に ffmpeg 4.0 Wu(Chien-Shiung Wu, 呉健雄) がリリースされた。今回のリリースはメジャーアップデートとなり、3.4 以降に追加された新機能の中からマスターにしか追加されていなかったフィルタやエンコーダ、デコーダ等の新機能が全て取り込まれた。今回は特にハードウェアアクセレーション関係のコミットが多い印象である。

前回記事
ffmpeg 3.4 リリース

RELEASE NOTES for FFmpeg 4.0 “Wu”

3.4 以降に取り込まれた機能の一覧
Changelog 3.4 to 4.0 < git.videolan.org Git

気になった新機能をいくつか紹介

mp4 の暗号化、復号方法
ffmpeg -f lavfi -i testsrc2=d=10 -c:v libx264 -encryption_scheme cenc-aes-ctr -encryption_key 76a6c65c5ea762046bd749a2e632ccbb -encryption_kid a7e61c373e219033c21091fa607bf3b8 encrypted.mp4
ffmpeg -decryption_key 76a6c65c5ea762046bd749a2e632ccbb -i encrypted.mp4 -c copy decrypted.mp4

追加されたフィルタで記事にしているフィルタ
複数の映像を任意の割合でミックスする mix

ffprobe の使い方

$
0
0

動画や音声、画像ファイルを調べるのに ffmpeg で表示される以上のことを調べるときに使う ffprobe の使い方。grep, awk などから正規表現を使って必要なデータを取る方法もあるが、今回はそうでなくオプションを指定して必要なデータを表示する方法を紹介する。出力フォーマット指定ができるので json, xml からパースすれば正規表現で無理に取る必要はない。

ffprobe では vf, af, filter_complex が使えないので lavfi デバイスで読み込み、そこからフィルタを使う。よって映像は rawvideo、音声は pcm_f32le になるのに注意。

基本コマンド

オプションを何も付けなければ 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

解像度を表示する。
ffprobe -v error -select_streams v:0 -show_entries stream=width,height -i input

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

パケット毎の 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

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

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

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

公式ドキュメント : 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, etc と併用する。map と同じように v, a, 0:v, 0:a などと指定する
  • -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”セクションをプログラム内容を表示
    表示内容は program_id, program_num, nb_streams, pmt_pid, pcr_pid, start_pts, start_time, end_pts, end_time, TAG:service_name, TAG:service_provider
  • -show_streams
    ストリーム内容の表示
  • -show_chapters
    “CHAPTER”セクションにチャプター別のデータを表示
    表示内容は id, time_base, start, start_time, end, end_time, TAG:title
  • -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”セクションに対応したピクセルフォーマットを表示
  • -read_intervals
    調べるデータの範囲指定。パケット単位と秒単位がある。詳しくは後述
  • -i
    入力ファイルの指定。無指定でも入力ファイルとして扱える。ffplay と同じ

print_format, of

default

無指定だとこれになり、対応する FORMAT, STREAM と PROGRAM_STREAM セクションにメタデータタグを表示する。
表示形式
[SECTION]
key1=val1
...
keyN=valN
[/SECTION]

オプション内容

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

1つのセクションを1行でカンマ区切りに表示し、対応する “FORMAT”, “STREAM” セクションのメタデータタグを表示する。メタデータタグキーが表示される場合は接頭辞 “tag:” が付く。
表示形式
section|key1=val1| ... |keyN=valN
オプション内容

  • 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

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

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

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

“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 packet の抜粋

show_entries format の表示例

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秒(絶対位置)までの例。
10%+20,01:30%01:45

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

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

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

可変フレームを検出する vfrdet

$
0
0

可変フレームか固定フレームかを調べることが出来る vfrdet フィルタ。コンソールには総フレーム数と可変フレーム数、 pts 間隔の最大値最小値が表示される。

基本コマンド

ffmpeg -i input -an -vf vfrdet -f null -

表示ログの例

固定フレームなら右に総フレーム数、左に可変フレーム数。

[Parsed_vfrdet_0 @ 000000000295fe80] VFR:0.000000 (0/34046)

可変フレームなら右に総フレーム数とは限らず、左に可変フレーム数かもよく分からない。pts 間隔の最大値最小値。

[Parsed_vfrdet_0 @ 00000000004e7f80] VFR:0.641629 (89787/50149) min: 0 max: 35)

公式ドキュメント:FFmpeg Filters Documentation : vfrdet

pts 間隔を調べるには ffprobe で調べる方法と、mkvtimestamp_v2 で調べる方法があるが、2つの方法が一致するとも限らない。

ffprobe
ffprobe -v error -i input -select_streams v:0 -show_entries packet=pts_time > pts_time.txt

mkvtimestamp_v2
ffmpeg -i input -an -f mkvtimestamp_v2 mkvtimestamp_v2.txt

音声のダイナミックレンジを調べる drmeter

$
0
0

14以上ならレンジがとても広く、8 以上 14 未満 までは普通で、8 未満はレンジが狭いとされている。

基本コマンド

ffmpeg -i input -vn -af drmeter=length=3 -f null -

表示ログの例

[Parsed_drmeter_0 @ 0000000000486580] Channel 1: DR: 12.6
[Parsed_drmeter_0 @ 0000000000486580] Channel 2: DR: 12.9
[Parsed_drmeter_0 @ 0000000000486580] Overall DR: 12.7

公式ドキュメント:FFmpeg Filters Documentation : drmeter

オプション

length[double]
何秒単位で解析するかの設定
既定値:3
範囲:0.01 から 10 まで


簡易的なフレーム補間をする framerate

$
0
0

本格的なフレーム補間は 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

オプション

  • fps[int]
    出力フレームレート数の指定
    既定値:50
  • interp_start[int]
    線形補間される範囲の最初の値
    既定値:15
    範囲:0 から 255 まで
  • interp_end[int]
    線形補間される範囲の最後の値
    既定値:240
    範囲:0 から 255 まで
  • scene[double]
    シーンチェンジが検出されるレベルの指定。低い値だと補完しにくくなり、高い値だと補完しやすくなる
  • flags[flags]
    フラグの指定
    scene_change_detect, scd
    scene を使う。既定値

フィールドタイプのフラグを建てる setfield

$
0
0

インターレースの映像でトップとボトムのどちらが最初なのかを指定する setfield フィルタ。フィールドタイプが間違っているときに修正する。

基本コマンド

ffmpeg -i input -vf setfield=mode=auto output
ffplay -i input -vf setfield

公式ドキュメント:FFmpeg Filters Documentation : setfield

オプション

mode[int]
フィールドモードの指定

  • -1, auto
    入力と同じ。既定値
  • 0, bff
    ボトムフィールドファースト
  • 1, tff
    トップフィールドファースト
  • 2, prog
    プログレッシブ

各フィールドをフレームに変換する separatefields

$
0
0

分離フィールドを交互に挟んだフレームにする separatefields フィルタ。フレーム数とフレームレートを2倍に、出力映像の縦解像度を半分にする。トップ、ボトムどちらのフィールドを先に出力するかは動画情報による。もし間違っているのなら setfield フィルタを先に指定する。

基本コマンド

ffmpeg -i input -vf separatefields output
ffplay -i input -vf separatefields

分離フィールドを元の映像に戻すには weave フィルタを使う。http://nico-lab.net/weave_with_ffmpeg/
ffmpeg -i input -vf separatefields,weave output
ffplay -i input -vf separatefields,weave

公式ドキュメント:FFmpeg Filters Documentation : separatefields

特定の映像フレームや音声サンプルを出力する select, aselect

$
0
0

特定のフレーム間隔での出力なら trim. atrim フィルタでもよいが、select フィルタはピクチャータイプやインターレースタイプの指定でも出力できるがものすごく処理が遅い。

trim フィルタの使い方

基本コマンド

select フィルタを使いながら音声も同期しつつ出力するのは難しいので音声は無効化 -an している。

0(最初)から100フレーム目までの合計101フレームを出力する。
ffmpeg -i input -vf select="between(n\,0\,100)",setpts=PTS-STARTPTS -vsync 0 -an output
同じ出力結果を trim フィルタで行う。こちらの方が処理が速い。
ffmpeg -i input -vf trim=start_frame=0:end_frame=101,setpts=PTS-STARTPTS -vsync 0 -an output

開始45秒から30フレーム分出力する。
ffmpeg -i input -vf select='gt(t,45)*lt(selected_n,30)',setpts=PTS-STARTPTS -vsync 0 -an output
ffmpeg -i input -vf trim=45,setpts=PTS-STARTPTS,trim=end_frame=30 -vsync 0 -an output

Iフレームだけ出力する。
ffmpeg -i input -vf select='eq(pict_type\,I)' -an -vsync 0 output.mp4
ffmpeg -i input -vf select='eq(pict_type\,I)' -an -vsync 0 output-%03d.png

キーフレームだけ出力する。
ffmpeg -i input -vf select='eq(key\,1)' -an -vsync 0 output.mp4
ffmpeg -i input -vf select='eq(key\,1)' -an -vsync 0 output-%03d.png
ffmpeg -skip_frame nokey -i input -an -vsync 0 output.mp4
ffmpeg -skip_frame nokey -i input -an -vsync 0 output-%03d.png

映像の変化が8割以上を出力する
ffmpeg -i input -vf select='gte(scene\,0.8)' -an -vsync 0 output.mp4
ffmpeg -i input -vf select='gte(scene\,0.8)' -an -vsync 0 output-%03d.png

画像を1フレームに複数枚並べるには tile フィルタを使う。
1フレームに複数のフレームを表示する tile

条件の設定には以下の評価式を使う。
ffmpeg で使える計算書式

公式ドキュメント:FFmpeg Filters Documentation : select_002c-aselect

オプション

音声のカットはあまり正確ではないらしいのと、使い方がよく分からない。

  • n
    連続したフレーム。0 から始まる
  • selected_n
    選択された連続フレーム。0 から始まる。条件で範囲を狭めて最初以外からの連続フレームを選択するときに使う
  • prev_selected_n
    選択された連続フレームの最後のフレーム。選択されてなければ NAN
  • TB
    タイムスタンプのタイムベース
  • pts
    映像の PTS
  • t
    映像の PTS 秒。pts*TB = t になる
  • prev_pts
    映像の PTS。pts との違いは1フレーム次の pts までのフレームを対象とする
  • prev_selected_pts
    最後にフィルタが当たった映像フレームの PTS。固定値。不明ならば NAN。使い方が分からない
  • prev_selected_t
    選択された最後の映像フレームの PTS 。固定値。不明ならば NAN。使い方が分からない
  • start_pts
    最初の映像フレームの PTS。一般的には 0 になることが多い。固定値。不明ならば NAN
  • start_t
    最初の映像フレームの PTS 秒。一般的には 0 になることが多い。固定値。不明ならば NAN
  • pict_type (video only)
    ピクチャータイプの指定
    • I
      I フレーム
    • P
      P フレーム
    • B
      B フレーム
    • S
      スイッチフレーム。詳細不明。VC-1で使われているらしい
    • SI
      スイッチングIフレーム
    • SP
      スイッチングPフレーム
    • BI
      スペシャルイントラフレーム
  • interlace_type (video only)
    フィールドタイプの指定
    • PROGRESSIVE
    • TOPFIRST
    • BOTTOMFIRST
  • consumed_sample_n (audio only)
  • samples_n (audio only)
  • sample_rate (audio only)
  • key
    キーフレームなら 1、それ以外なら 0。I フレームより出力が少なくなる。つまりキーフレームはすべてIフレームだが、Iフレームのすべてがキーフレームではない。ffprobe の key はこれのこと
  • pos
    position の値。分からなければ -1 になる。showinfo フィルタで調べられる
  • scene (video only)
    変化率。小さい値ほど変化が小さく、大きい値ほど変化が大きいフレームだけを検出する。一般的には大きな値になるほどIフレームだけになる。0 は完全一致
  • concatdec_select

2つの映像の画質評価をする PSNR

$
0
0

2入力した映像を比較して PNSR(Peak Signal to Noise Ratio) の値を計算する。MSE(mean squared error) は PSNR を計算するのに使われる。

関連フィルタ
2つの映像の画質評価をする SSIM
新しい映像の品質評価 libvmaf

最終結果だけを表示。1入力がオリジナルの動画で、2入力が PSNR を計算する動画
ffmpeg -i input1 -i input2 -filter_complex psnr -an -f null -

ログファイルを出力する。
ffmpeg -i input1 -i input2 -filter_complex psnr=stats.txt -an -f null -

metadata フィルタでフレーム単位でコンソールに表示する方法。ここでは unsharp フィルタの psnr_avg を表示している。
ffplay -i input -vf split[a][b];[b]unsharp[B];[a][B]psnr,metadata=print:key=lavfi.psnr.psnr_avg

映像に焼き付けて再生する。
ffplay -f lavfi -i movie=input1.mp4[a];movie=input2.mp4[b];[a][b]ssim,drawtext=fontfile="c\://Windows/Fonts/arial.ttf":fontsize=20:fontcolor=white:box=1:boxcolor=black@0.4:text='"SSIM="%{metadata\:lavfi.ssim.ALL}'

lavfi.psnr.X 形式で X に代入できるのは、mse_avg, psnr_avg である。

framesync の設定にも対応している
2ファイル入力するフィルタの挙動設定 framesync

オプション

  • stats_file, f[string]
    ログファイルの出力名
  • stats_version[int]
    ログファイルのバージョン指定
    既定値:1、ログファイル1行目の項目を表示しない
    範囲:1, 2
  • stats_add_max[boolean]
    最大値をログファイルに出力するかの指定。出力する場合は stats_version=2 を指定する
    既定値:0

ログファイルの見方

  • psnr_log_version
    stats_version のバージョン
  • n
    フレーム番号
  • mse_avg
    すべてのチャンネルの不偏分散平均
  • mse_y, mse_u, mse_v, mse_r, mse_g, mse_b, mse_a
    個別のチャンネルの不偏分散平均
  • psnr_y, psnr_u, psnr_v, psnr_r, psnr_g, psnr_b, psnr_a
    個別のチャンネルの psnr
  • max_avg, max_y, max_u, max_v
    YUVチャンネルの最大許容値の平均、個別のチャンネルの最大許容値

ブロッキングアーティファクトを除去する deblock

$
0
0

不可逆圧縮したときに生じる圧縮アーティファクトを除去する deblock フィルタの使い方。

圧縮アーティファクト – Wikipedia

基本コマンド

ffmpeg -i input -vf deblock=filter=1:block=8:alpha=0.098:beta=0.05:gamma=0.05:delta=0.05:planes=15 output
ffplay -i input -vf deblock=filter=1:8:0.098:0.05:0.05:0.05:15

ブロックサイズ4ピクセルの弱いフィルタ
ffplay -i input -vf deblock=filter=weak:block=4
ブロックサイズ4ピクセルの強いフィルタにエッジのでブロックを強化
ffplay -i input -vf deblock=filter=strong:block=4:alpha=0.12:beta=0.07:gamma=0.06:delta=0.05
上と似ているが最初のチャンネルしか効果がない
ffplay -i input -vf deblock=filter=strong:block=4:alpha=0.12:beta=0.07:gamma=0.06:delta=0.05:planes=1

公式ドキュメント:FFmpeg Filters Documentation : deblock

画像サンプル

オリジナルを2倍に拡大 PNG 出力(32.3KB)

上から品質26で jpg 出力(3.02KB)

品質26に既定値の strong(5.41KB)

品質26に既定値から weak に指定(5.56KB)

オプション

  • filter[int]
    フィルタータイプの指定
    0, weak
    1, strong:既定値
  • block[int]
    ブロックサイズの指定。小さい値ほどデブロック効果が高い
    既定値:8
    範囲:4 から 512 まで
  • alpha[float]
    ブロック検出の閾値の指定。大きい値ほど強度が増す
    既定値:0.098
    範囲:0 から 1 まで
  • beta[float]
    以下2つはエッジ付近の閾値検出を制御する。それぞれ下/上または左/右。0 を指定すると無効になる
    既定値:0.05
    範囲:0 から 1 まで
  • gamma[float]
    同上
  • delta[float]
    同上
  • planes[int]
    フィルタを当てるチャンネル指定
    詳しくは ffmpeg について | チャンネルの順番と注意点 を参照

3次元周波数領域デノイズフィルタ fftdnoiz

$
0
0

3次元周波数領域デノイズフィルタ fftdnoiz の使い方。ただし既定値では3次元はなく2次元設定になっている。他の3次元デノイズフィルタに hqdn3d がある。

基本コマンド

ffmpeg -i input -vf fftdnoiz=sigma=1:amount=1:block=4:overlap=0.5:prev=0:next=0:planes=7 output
ffplay -i input -vf fftdnoiz=1:1:4:0.5:0:0:7

3次元デノイズにするには prev, next を有効にする
ffplay -i input -vf fftdnoiz=1:1:4:0.5:1:1:7

公式ドキュメント:FFmpeg Filters Documentation : fftdnoiz

オプション

  • sigma[float]
    デノイズ強度の指定。sigma を大きくし、overlap を小さくするとブロッキングアーティファクトが発生しやすくなる
    既定値:1
    範囲:0 から 30 まで
  • amount[float]
    デノイズ量の指定。1 の指定で検出されたすべてをデノイズする
    既定値:1
    範囲:0 から 1 まで
  • block[int]
    ブロックサイズの指定。指定した値の2のべき乗になる
    既定値:4
    範囲:3 から 6 まで
  • overlap[float]
    ブロックのオーバーラップ(重なり)の割合の指定
    既定値:0.5
    範囲:0.2 から 0.8 まで
  • prev[int]
    過去フレームを参照してデノイズをするフレーム数の指定
    既定値:1
    範囲:0 から 1 まで
  • next[int]
    未来フレームを参照してデノイズをするフレーム数の指定
    既定値:1
    範囲:0 から 1 まで
  • planes
    デノイズするチャンネル指定
    詳しくは ffmpeg について | チャンネルの順番と注意点 を参照
    既定値:7
    範囲:0 から 15 まで

vmaf スコアをインターレース解除とデノイズのフィルタを使って調べてみた

$
0
0

vmaf スコアの調べ方。新しい映像の品質評価 libvmaf

インターレース解除フィルタの vmaf スコア

インターレース解除フィルタでの vmaf スコアを調べる。比較したデインターレースフィルタは左から、yadif, bwdif, fieldmatch, pp=linipoldeint, pp=cubicipoldeint, pp=mediandeint, pp=ffmpegdeint の初期設定。エンコーダは QSV で余裕を持って 10000k 固定ビットレート出力している。

結論は fieldmatch フィルタが実写、アニメ映像にかかわらず vmaf スコアが高くなり、映像を補完するフィルタは vmaf スコアが下がる傾向になった。fieldmatch フィルタのスコアが高くなるのは縞が出ないところは何もせずに縞があるところだけフィールドをずらしてプログレッシブにするので元映像と比較すると変化が少ないことが最大の理由と考えられる。

コマンド例
ffmpeg -analyzeduration 300M -probesize 300M -i input -vf fieldmatch -movflags faststart -max_muxing_queue_size 1024 -vcodec h264_qsv -look_ahead 0 -b:v 10000k -maxrate 10000k fieldmatch.mp4
ffmpeg -analyzeduration 300M -probesize 300M -i fieldmatch.mp4 -i input.ts -filter_complex libvmaf=model_path=../share/model/vmaf_v0.6.1.pkl -f null - > fieldmatch.txt 2>&1

A から D までは実写映像に以下のデインターレースフィルタを当ててる。

frames size yadif bwdif field linip cubic media ffmpe
A 8997 1440x1080p 96.785 95.625 99.238 91.749 94.953 98.163 96.167
B 8988 1920x1080p 89.917 87.787 93.729 82.646 84.576 91.282 87.930
C 17986 1920x1080p 88.843 87.803 92.067 86.976 87.754 91.945 90.035
D 22252 1920x1080p 93.855 91.552 96.667 85.598 88.303 94.124 91.684

E から J まではアニメ映像に上と同じようにデインターレースフィルタを当ててる。

frames size yadif bwdif field linip cubic media ffmpe
E 16168 1440x1080p 92.274 91.240 92.985 88.623 90.264 92.621 92.025
F 9592 1440x1080p 93.206 92.458 94.124 89.208 90.707 94.103 92.900
G 8997 1920x1080p 91.867 90.237 92.726 86.584 87.939 92.474 90.728
H 9592 1920x1080p 91.494 89.860 92.433 86.321 87.780 92.314 90.508
I 3780 1920x1080p 92.819 92.864 98.097 87.472 88.016 94.449 91.097
J 7197 1920x1080p 89.458 88.352 92.029 84.990 85.952 91.483 89.291

デノイズフィルタの vmaf スコア

デノイズフィルタでの vmaf スコアを調べる。比較したデノイズフィルタは初期設定である。through はデノイズフィルタを当てていない。エンコーダは QSV での 3000k 固定ビットレート出力している。

結論は sab フィルタが実写、アニメ映像にかかわらず概ね vmaf スコアが高くなる結果になった。fftdnoiz フィルタも高い vmaf スコアになっているが結構負荷が高い。調べ終えて気づいたが input を fieldmatch したほうがよかった気がしないでもない。

コマンド例
ffmpeg -analyzeduration 300M -probesize 300M -i input -vf fieldmatch,sab,fifo -movflags faststart -max_muxing_queue_size 1024 -vcodec h264_qsv -look_ahead 0 -b:v 3000k -maxrate 3000k sab.mp4
ffmpeg -analyzeduration 300M -probesize 300M -i sab.mp4 -i input -filter_complex libvmaf=model_path=../share/model/vmaf_v0.6.1.pkl -f null - > sab.txt 2>&1

A から D までは実写映像

hqdn3d pp=de pp=dr sab nlmeans through deblock fftdnoiz
A 66.425 66.128 66.324 67.175 67.122 67.155 66.840 67.184
B 76.115 75.360 75.404 76.586 76.389 76.424 76.369 76.453
C 69.159 68.347 68.617 70.119 70.064 69.684 69.433 69.854
D 85.630 85.235 85.283 86.355 86.102 86.187 86.106 86.208

E から J まではアニメ映像

hqdn3d pp=de pp=dr sab nlmeans through deblock fftdnoiz
E 88.821 89.699 89.772 91.130 90.887 91.082 90.547 91.095
F 88.464 89.537 89.519 90.799 90.516 90.730 90.287 90.730
G 78.809 79.263 79.221 80.204 80.057 80.193 79.792 80.211
H 86.294 87.396 87.351 88.617 88.475 88.533 88.061 88.597
I 71.020 71.254 71.413 72.185 72.114 72.290 71.907 72.290
J 68.278 68.079 68.354 69.448 69.276 69.302 69.044 69.323

ビットレートを変えたデノイズフィルタの vmaf スコア

3000k でも足りている映像と足りてない映像があったが今度はさらにビットレートを 1500k, 1000k に下げてビットレートが足りていない状態でデノイズフィルタを当てたときの vmaf スコアを調べた。映像はプログレッシブの異なる2つのアニメ映像を使った。スコアの右に順位も記載した。

結論は必要なビットレートが足りなくなると何もデノイズフィルタを当てないよりも sab フィルタの方が vmaf スコアが高くなった。しかし上の例ではスコアが 90 を超えているのに sab フィルタの方が高くなることもあるので一概に低ビットレートでは sab フィルタを使えばスコアが高くなるとも言い切れない。

一つ目は、7194フレーム、1920x1080p の映像。コマンドは上と同じだが、ビットレートが異なる。

3000k 1500k 1000k
hqdn3d 90.998 8 86.779 8 82.592 8
pp=de 93.128 7 88.481 7 84.026 6
pp=dr 93.300 6 88.607 6 84.015 7
sab 94.057 2 89.271 2 84.845 1
nlmeans 93.878 4 89.243 4 84.743 4
through 94.185 1 89.369 1 84.802 2
deblock 93.579 5 88.768 5 84.386 5
fftdnoiz 93.985 3 89.251 3 84.789 3

二つ目は、5399フレーム、1920x1080p の映像。

3000k 1500k 1000k
hqdn3d 80.787 8 75.280 8 69.435 8
pp=de 82.362 7 76.482 7 70.239 7
pp=dr 82.457 6 76.599 6 70.331 6
sab 83.157 2 77.347 1 71.045 1
nlmeans 82.796 4 77.115 4 70.756 4
through 83.204 1 77.298 3 70.984 2
deblock 82.720 5 76.840 5 70.546 5
fftdnoiz 83.102 3 77.330 2 70.913 3

ブログで解説した記事

文字を描写する drawtext

$
0
0

文字を直接コマンドに記述したり、ファイルを読み込んで描写する drawtext フィルタの使い方。現在のところ絵文字には対応していない。文字を動かしたり、表示非表示の切り替えや、内容を変更したり、色を変えたり出来る。ただし映像の途中に拡大縮小は出来ないので ass, subtitles フィルタを使って字幕を動かす方法をとる。

外部ライブラリフィルタなので別途インストールが必要である。基本となる –enable-libfreetype、font 設定に必要な –enable-libfontconfig。アラビア文字で右から左描写には –enable-libfribidi が必要。

ass の字幕ファイルを動画に焼き付ける ass
字幕ファイルを動画に焼き付ける subtitles

テキスト描写にはフォント描写の知識がないとオプションの意味が分かりにくい。

基本コマンド

color ソースに aiueo を左上に描写
ffplay -f lavfi -i color=white -vf "drawtext=fontfile='C\://WINDOWS/Fonts/arial.ttf':text='aiueo'"

msgothic フォントを指定し、あいうえお を左から右へ1フレーム毎に1ピクセル移動させる
"drawtext=fontsize=30:box=1:boxcolor=white@0.5:fontcolor=black:fontfile='C\://WINDOWS/Fonts/msgothic.ttc':text='あいうえお':x=n"

hello world を映像の中心に描写
"drawtext=fontsize=30:box=1:boxcolor=white@0.5:fontcolor=black:fontfile='C\://WINDOWS/Fonts/msgothic.ttc':text='hello world':x=(w-text_w)/2:y=(h-text_h)/2"

5秒毎にランダムな場所に描写
"drawtext=fontsize=30:fontfile='C\://WINDOWS/Fonts/msgothic.ttc':text='hello world':x=if(eq(mod(t\,5)\,0)\,rand(0\,(w-text_w))\,x):y=if(eq(mod(t\,5)\,0)\,rand(0\,(h-text_h))\,y)"

横に中央からフォント半分ほど左に、縦に半分からベースラインから上の部分だけ上げたところに描写
"drawtext="fontsize=60:fontfile='C\://WINDOWS/Fonts/msgothic.ttc':fontcolor=green:text=g:x=(w-max_glyph_w)/2:y=h/2-ascent"

タイムライン編集を使って3秒毎に1秒描写
"drawtext="fontfile='C\://WINDOWS/Fonts/msgothic.ttc'.ttf:fontcolor=white:x=100:y=x/dar:text='blink':enable=lt(mod(t\,3)\,1)"

スタイルにセミボールドを指定する
"drawtext='fontfile=Linux Libertine O-40\:style=Semibold:text=FFmpeg'"

strftime() 書式を使って、英語での曜日、英語での月、日付、年を描写
"drawtext=fontfile='C\://WINDOWS/Fonts/msgothic.ttc':text='%{localtime\:%a %b %d %Y}'"

公式ドキュメント:FFmpeg Filters Documentation : drawtext

描写を読みやすくする

フォントカラーを変える
"drawtext=fontfile='C\://WINDOWS/Fonts/arial.ttf':text='aiueo':fontcolor=yellow:x=40:y=40"

フォントサイズを変える
"drawtext=fontfile='C\://WINDOWS/Fonts/arial.ttf':text='aiueo':fontsize=64:x=40:y=40"

四角いボックスをフォントの背景に配置
"drawtext=fontfile='C\://WINDOWS/Fonts/arial.ttf':text='aiueo':box=1:boxcolor=yellow:boxborderw=10:x=40:y=40"

フォント周りを縁取る
"drawtext=fontfile='C\://WINDOWS/Fonts/arial.ttf':text='aiueo':bordercolor=yellow:borderw=3:x=40:y=40"

フォントからの位置にオフセット指定した影を配置
"drawtext=fontfile='C\://WINDOWS/Fonts/arial.ttf':text='aiueo':shadowcolor=yellow:shadowx=3:shadowy=3:x=40:y=40"

オプション

オプション数が膨大なのでオプション名は省略しないほうがわかりやすい。

  • fontfile[string]
    フォントファイルのパスを指定。日本語の場合は日本語フォントを指定しないと正しく描写されない。Windows だと、C:\Windows\Fonts を開いて、プロパティからファイル名を取得する
  • text[string]
    描写するテキストの指定。文字コードは UTF-8 でなければならない。また以下の書式も使える。スペースで間を開ける場合は “‘ ‘” で挟むかエスケープする。Text expansion の項を参照
  • textfile[string]
    描写するテキストファイルのパスを指定。text と併用できない。文字コードは UTF-8 でなければならない。改行する場合はこちらの方が手軽
  • fontcolor[color]
    描写内容の色指定。詳しくは FFmpeg Utilities Documentation : Color を参照。指定した色の後ろに @0.5 とすることで透過指定も可能
    既定値:black
  • fontcolor_expr[string]
    描写内容の色指定の拡張版。フレーム数や時間で色を変えられる。0xRRGGBB[AA] の順番で指定する。後ろに @0.5 とすることで透過指定も可能
    例:fontcolor_expr=’0x%{eif\:print(mod(n\,256))\:x\:2}%{eif\:print(mod(n\,256))\:x\:2}%{eif\:print(mod(n\,256))\:x\:2}’@0.5
  • boxcolor[color]
    box の背景色を指定。random でランダムになる。詳しくは FFmpeg Utilities Documentation : Color を参照。指定した色の後ろに @0.5 とすることで透過指定も可能
    既定値:white
  • bordercolor[color]
    borderw の色を指定
    既定値:black
  • shadowcolor[color]
    text の影の色指定。詳しくは FFmpeg Utilities Documentation : Color を参照。指定した色の後ろに @0.5 とすることで透過指定も可能
  • box[boolean]
    描写内容の背景をテキスト幅で囲む
    既定値:0
  • boxborderw[int]
    box のサイズ指定。上下左右同じように広がる
    範囲:INT_MIN から INT_MAX まで
    既定値:0
  • line_spacing[int]
    set line spacing in pixels
    範囲:INT_MIN から INT_MAX まで
    既定値:0
  • fontsize[string]
    フォントサイズの指定
  • x[string]
    描写内容の横座標の指定。以下の書式が使える
  • y[string]
    描写内容の縦座標の指定。以下の書式が使える
  • shadowx[int]
    描写内容に影を横軸の方向に表示
  • shadowy[int]
    描写内容に影を縦軸の方向に表示
  • borderw[int]
    描写内容の縁取りのサイズの指定
  • tabsize[int]
    タブ1つがスペースいくつかの指定
    範囲:0 から INT_MAX まで
    既定値:4
  • basetime[int64]
    廃止予定。Set a start time for the count. Value is in microseconds. Only applied in the deprecated strftime expansion mode.
  • font[string]
    描写に使うフォントファミリーの名前
    既定値:Sans
  • timecode[string]
    text, textfile を使わずにタイムコードを描写する。書式は “hh:mm:ss[:;.]ff” 形式。時間指定でオフセットの指定になる
    例:timecode=’00\:00\:00\:00′
  • tc24hmax[boolean]
    24時間経過したら0時に戻る
    既定値:0
  • timecode_rate, r, rate[rational]
    timecode を使うときのフレームレートの指定で必須項目。分数や少数は一番近い整数になる
    既定値:0/1
    範囲:1 から INT_MAX まで
  • reload[boolean]
    textfile をリロードして内容が書き換わったらフレーム毎に書き換える
    既定値:0
  • alpha[string]
    描写内容を透過させる
    既定値:1(透過しない)
    範囲:0.1 から 1 まで
  • fix_bounds[boolean]
    check and fix text coords to avoid clipping
    既定値:0
  • start_number[int]
    The starting frame number for the n/frame_num variable.
    既定値:0
  • expansion[int]
    text拡張指定
    • none:無効
    • normal:有効。既定値
    • strftime:廃止予定
  • ft_load_flags[flags]
    フラグの指定。+ で複数指定できる。詳しくは公式サイトを参照
    • default
    • no_scale
    • no_hinting
    • render
    • no_bitmap
    • vertical_layout
      縦書きだが、文字が重なりうまく描写できない
    • force_autohint
    • crop_bitmap
    • pedantic
    • ignore_global_advance_width
    • no_recurse
    • ignore_transform
    • monochrome
    • linear_design
    • no_autohint

Text expansion

  • expr, e
    x, y で使った書式が使える
  • expr_int_format, eif
    x, y で使った書式が使え、第2引数で表示形式が指定できる
    • x:符号なし整数を16進数表示、アルファベットは小文字
    • X:符号なし整数を16進数表示、アルファベットは大文字
    • d:符号あり整数を10進数表示
    • u:符号なし整数を10進数表示
  • gmtime
    UTC を使って時間を表示する。strftime() 書式が使えるが一部使えない
  • localtime
    ローカルタイムゾーンを使って時間を表示する。strftime() 書式が使えるが一部使えない
  • metadata
    metadata を呼び出して描写する
  • n, frame_num
    0開始のフレーム番号
    例:text=’%{n}’
  • pict_type
    IPBフレームの表示
    例:text=’%{pict_type}’
  • pts
    • flt:マイクロ秒表示。第2引数でオフセットが使える
      例:text=’%{pts\:flt\:100}’
    • hms:時間分秒表示。hh:mm:ss 形式。第2引数でオフセットが使え、第3引数で 24HH を使うと 00-23 の範囲になり日が更新される
      例:text=’%{pts\:hms\:400000\:24HH}’
    • gmtime:UTC 時間で1970-01-01 00:00:00 から始まる。第2引数でオフセットが使える
    • localtime:ローカルタイムゾーンで日本なら 1970-01-01 09:00:00 から始まる。第2引数でオフセットが使える
      例:text=’%{pts\:localtime\:400000\:%Y}’

x, y の評価式

ffmpeg で使える計算書式 を併用することもできる。

  • sar
    サンプルアスペクト比
  • dar
    (w/h)*sar
  • hsub
    横のクロマサブサンプリング数。yuv420p ならば 2、yuv422p ならば 2
  • vsub
    縦のクロマサブサンプリング数。yuv420p ならば 2、yuv422p ならば 1
  • line_h, lh
    描写内容の高さ。fontsize で変化するが同じになるとは限らない
  • main_h, h, H
    入力した映像の縦解像度
  • main_w, w, W
    入力した映像の横解像度
  • max_glyph_a, ascent
    ベースラインからすべての描写内容の上の高さ
  • max_glyph_d, descent
    ベースラインからすべての描写内容の下の高さ。ベースラインから下に描写されなければ 0 になるが、”g” のような文字だとマイナスになる
  • max_glyph_h
    ascent – descent で、lh と同じようになる
  • max_glyph_w
    すべての描写内容からフォント1文字分の最大幅
  • n
    表示している映像のフレーム番号。0 から始まる
  • rand(min, max)
    最小値と最大値の値をランダムで返す
  • t
    表示している映像のタイムスタンプ
  • text_h, th
    描写内容の高さ。fontsize, text, textfile などで動的に変わる
  • text_w, tw
    描写内容の横幅。fontsize, text, textfile などで動的に変わる
  • x
    テキストが描画されるx座標のオフセット。x には自己参照になるので指定できない
  • y
    テキストが描画されるy座標のオフセット。y には自己参照になるので指定できない
  • pict_type
    1:I フレーム
    2:B フレーム
    3:P フレーム

応用例

test.txt を書き換えて描写内容を変更する
"drawtext=fontsize=32:box=1:boxcolor=white@0.5:fontcolor=black:fontfile='C\://WINDOWS/Fonts/msgothic.ttc':textfile='test.txt':reload=1"

映画などの編集作業でよくみる時間経過を表示するタイムコードを描写
"drawtext=fontsize=32:box=1:boxcolor=white@0.5:fontcolor=black:fontfile='C\://WINDOWS/Fonts/arial.ttf':timecode='00\:00\:00\:00':r=24:fontcolor=0xccFFFF"

ffmpegならこちらへ 3 [無断転載禁止]©2ch.net より

639名無しさん@お腹いっぱい。2018/05/27(日) 19:51:33.96ID:zoTvVaWy0
>フレームレートを大きくする前の動画の時間に対してタイムコードが付く
つまり倍速再生にして、時間経過も倍速表示にしたいと

25fps の動画の場合、倍速分の入力フレームレートを指定し、最初に倍速分の pts を掛けて、元に戻す
ffmpeg -r 50 -i input -vf setpts=PTS*2,”drawtext=fontsize=30:box=1:boxcolor=white@0.5:fontcolor=black:fontfile=’C\://WINDOWS/Fonts/arial.ttf’:text=’%{eif\:t\:d}'”,setpts=PTS/2 output.mp4

ffplay -f lavfi -i color=white -vf setpts=PTS*2,"drawtext=fontsize=30:box=1:boxcolor=white@0.5:fontcolor=black:fontfile='C\://WINDOWS/Fonts/arial.ttf':text='%{eif\:t\:d}'",setpts=PTS/2

映像フィルタを当てる前後のデータを見える化する
ffmpeg でテキストを動的に表示する
ニコ生のTSから一定時間毎に画像を出力する

フレームがインターレースかどうかを調べる idet

$
0
0

入力フレームがインターレース、プログレッシブ、トップフィールドファースト(tff)、ボトムフィールドファースト(bff) のどれであるかを調べる idet(interlace detect type) フィルタの使い方。また、隣り合うフレーム間で重複するフィールド(テレシネのサイン)も調べられる。

基本コマンド

ffmpeg -i input.ts -vf idet -an -f null -

出力ログ例
Repeated Fields: Neither: 267 Top: 17 Bottom: 17
Single frame detection: TFF: 135 BFF: 0 Progressive: 44 Undetermined: 122
Multi frame detection: TFF: 279 BFF: 0 Progressive: 0 Undetermined: 22

ffplay で drawtext フィルタを使って描写しながら再生
ffplay -i input.ts -vf idet,drawtext=fontfile='C\://WINDOWS/Fonts/arial.ttf':text='repeated.current_frame" "%{metadata\:lavfi.idet.repeated.current_frame}':fontsize=32:borderw=2:bordercolor=white
ffplay -i input.ts -vf idet,drawtext=fontfile='C\://WINDOWS/Fonts/arial.ttf':textfile=idet.txt:fontsize=32:borderw=2:bordercolor=white:line_spacing=2

ffprobe でログ出力。packet_tags で idet フィルタ内容の順番を入れ換えても順番が入れ替わらない
ffprobe -v error -f lavfi -i movie=input.ts,idet -select_streams 0:v -show_entries packet=pts_time -show_entries packet_tags=lavfi.idet.repeated.current_frame,lavfi.idet.repeated.neither,lavfi.idet.repeated.top,lavfi.idet.repeated.bottom,lavfi.idet.single.current_frame,lavfi.idet.single.tff,lavfi.idet.multiple.tff,lavfi.idet.single.bff,lavfi.idet.multiple.current_frame,lavfi.idet.multiple.bff,lavfi.idet.single.progressive,lavfi.idet.multiple.progressive,lavfi.idet.single.undetermined,lavfi.idet.multiple.undetermined -of csv > output.csv

half_life を 1000 を右にして左右に再生する
ffplay -i input.ts -vf "split[a],idet,drawtext=fontfile='C\://WINDOWS/Fonts/arial.ttf':textfile=idet.txt:fontsize=32:borderw=2:bordercolor=white:line_spacing=2[b];[a]idet=half_life=1000,drawtext=fontfile='C\://WINDOWS/Fonts/arial.ttf':textfile=idet.txt:fontsize=32:borderw=2:bordercolor=white:line_spacing=2,crop=iw/2:ih:0:0,[b]overlay=W/2:0"

公式ドキュメント:FFmpeg Filters Documentation : idet

オプション

  • intl_thres[float]
    インターレース検出の閾値
    既定値:1.04
    範囲:-1 から FLT_MAX まで
  • prog_thres[float]
    プログレッシブ検出の閾値
    既定値:1.5
    範囲:-1 から FLT_MAX まで
  • rep_thres[float]
    重複検出の閾値
    既定値:3
    範囲:-1 から FLT_MAX まで
  • half_life[float]
    統計で累積に対するフレームの寄与設定。既定値の 0 ではすべてのフレームに最後まで 1.0 ずつ加算される。0 に近いほど累積値が小さくなり少数で加算され、大きい値ほど 1.0 に近い値で加算される。-1 は 0 とおそらく同じ
    既定値:0
    範囲:-1 から FLT_MAX まで
  • analyze_interlaced_flag[int]
    インターレースフラグが正確かどうかを判断するために使用するフレームの数を設定する。指定した値を超えたフレーム数は検出を止める
    既定値:0(全フレーム)
    範囲:0 から INT_MAX まで

メタデータ

Single frame detection は隣り合うフレームだけを参照する。Multiple frame detection は複数の過去フレームを参照する。

  • repeated.current_frame
    現在のフレームはどちらのフィールドが1つ前のフレームと比較して重複しているか
    “neither”(どちらでもない), “top”, or “bottom”
  • repeated.neither
    重複していないフィールドの累積フレーム数
  • repeated.top
    1つ前のフレームを比較して重複した tff の累積フレーム数
  • repeated.bottom
    1つ前のフレームを比較して重複した bff の累積フレーム数
  • single.current_frame
    single-frame detection を使って現在のフレームタイプを調べる
    “tff” (top field first), “bff” (bottom field first), “progressive”, or “undetermined”(不明)
  • single.tff
    single-frame detection を使って tff の累積フレーム数
  • single.bff
    single-frame detection を使って bff の累積フレーム数
  • single.progressive
    single-frame detection を使って progressive の累積フレーム数
  • single.undetermined
    single-frame detection を使って undetermined の累積フレーム数
  • multiple.current_frame
    multiple-frame detection を使って現在のフレームタイプを調べる
    “tff” (top field first), “bff” (bottom field first), “progressive”, or “undetermined”(不明)
  • multiple.tff
    multiple-frame detection を使って tff の累積フレーム数
  • multiple.bff
    multiple-frame detection を使って bff の累積フレーム数
  • multiple.progressive
    multiple-frame detection を使って progressive の累積フレーム数
  • multiple.undetermined
    multiple-frame detection を使って undetermined の累積フレーム数

ffmpeg 4.1 リリース

$
0
0

2018年11月6日に ffmpeg 4.1 al-Khwarizmi(フワーリズミー) がリリースされた。今回のリリースはメジャーアップデートとなり、4.0 以降に追加された新機能の中からマスターにしか追加されていなかったフィルタやエンコーダ、デコーダ等の新機能が全て取り込まれた。今回は AV1 パーサlibdav1d による AV1 デコーダ
(4.2 以降)
AV1 のビットストリームフィルタlibaomenc による AV1 エンコーダの tile サポートlibxavs2 による AVS2 エンコーダなど新しいコーデックの新機能が追加されている。

libdav1d による AV1 デコーダは 4.2 以降だったので訂正した。

前回記事
ffmpeg 4.0 リリース

RELEASE NOTES for FFmpeg 4.1 “al-Khwarizmi”

4.0 以降に取り込まれた機能の一覧
Changelog 4.0 to 4.1 < git.videolan.org Git

言及し忘れていたが configure の速度が大幅に向上している。

ffmpeg で動画にロゴ画像を追加し透過させる

$
0
0

具体的には overlay フィルタを使って画像を映像の上に載せるが、そのままだと画像が透過しないので format フィルタでアルファチャンネルを追加し、lutyuv フィルタで透過具合を指定する。画像が動画よりも縦横のどちらかの解像度が超えている場合は予めリサイズするか、フィルタで小さくする。

Windows の ffmpeg で生放送する方法 : lutyuv
Windows の ffmpeg で生放送する方法 : overlay
Windows の ffmpeg で生放送する方法 : scale
Windows の ffmpeg で生放送する方法 : crop

プレビュー例
ffmpeg -re -i movie.mp4 -loop 1 -i input.jpg -filter_complex [1]format=yuva420p,lutyuv=a=64,[0]overlay=x=10:y=20 -an -f sdl -

動画で出力
ffmpeg -i movie.mp4 -loop 1 -i input.jpg -filter_complex [1]format=yuva420p,lutyuv=a=64,[0]overlay=x=10:y=20 -c:a copy output.mp4

画像を半分にリサイズする
ffmpeg -i movie.mp4 -loop 1 -i input.jpg -filter_complex [1]scale=iw/2:ih/2,format=yuva420p,lutyuv=a=64,[0]overlay=x=10:y=20 -c:a copy output.mp4

左上を基準で半分にクロップする
ffmpeg -i movie.mp4 -loop 1 -i input.jpg -filter_complex [1]crop=iw/2:ih/2:0:0,format=yuva420p,lutyuv=a=64,[0]overlay=x=10:y=20 -c:a copy output.mp4

Viewing all 310 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>