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

解像度が一致しなくても映像を並べられる xstack

$
0
0

ffmpeg 4.1 から使えるフィルタ。overlay, stack フィルタを合わせたような xstack フィルタの使い方。解像度が異なっていても使えるのが特徴で、上下左右にも映像の上にも重ねられる。余白部分は YUV なら [0:0:0] の緑、RGB なら [0:0:0] の黒になり、フレームレートが一致しないと小さい方に合わされる。

overlay フィルタのように映像の上に重ねることもできるが、透過情報は引き継げないのできれいに色が抜けない。overlay フィルタよりも処理が早いので透過させないならこちらの方がよいが、overlay_opencl, overlay_qsv が使えるのならその限りではない。

Windows の ffmpeg で生放送する方法 : overlay
Windows の ffmpeg で生放送する方法 : stack
qsv 対応の ffmpeg をつくる : overlay_qsv

基本コマンド

1入力の右に2入力を並べ、音声は1入力をコピーする
ffmpeg -i input1 -i input2 -filter_complex "xstack=inputs=2:layout=0_0|w0_0:shortest=0[v]" -map [v] -map 0:a -c:a copy output
ffmpeg -i input1 -i input2 -filter_complex "xstack[v]" -map [v] -map 0:a -c:a copy output

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

オプション

  • inputs[int]
    入力ファイル数
    範囲:2 から INT_MAX まで
    既定値:2
  • layout[string]
    レイアウトの指定。wは横解像度で隣の数字が入力ファイルの指定で0から。hは縦解像度で数字は横解像度と同じ。座標指定も可能
    既定値:”0_0|w0_0″
  • shortest[boolean]
    一番短い入力ファイルが終わったときに強制的に終了させるか
    既定値:0(終了しない)

応用例

  • 4入力したときに
    13
    24
    の順番に並べる
    "xstack=inputs=4:layout=0_0|0_h0|w0_0|w0_h0"
  • 4入力したときに
    1
    2
    3
    4
    の順番に並べる
    "xstack=inputs=4:layout=0_0|0_h0|0_h0+h1|0_h0+h1+h2"
  • 9入力したときに
    516
    438
    729
    の順番に並べる
    "xstack=inputs=9:layout=w3_0|w3_h0+h2|w3_h0|0_h4|0_0|w3+w1_0|0_h1+h2|w3+w1_h0|w3+w1_h1+h2"

映像、音声情報を映像に表示する graphmonitor, agraphmonitor

$
0
0

ffmpeg 4.1 から使えるフィルタ。フィルタ間のフレーム数、時間、解像度、フォーマット、フレームレートを映像に表示する graphmonitor, agraphmonitor フィルタの使い方。文字の描写に drawtext フィルタを使わないので、fontconfig 関係のライブラリが不要。出力フォーマットは rgba になるので overlay フィルタを使うと透過して下の映像が映る。

基本コマンド

ffplay -i input -vf graphmonitor=s=hd720:o=0.9:m=full:f=queue
ffplay -i input -vf graphmonitor

公式ドキュメント:FFmpeg Filters Documentation : graphmonitor, agraphmonitor

オプション

  • size, s[image_size]
    映像での出力解像度
    既定値:hd720(1280×720)
  • opacity, o[float]
    透過指定。1 が透過しない。0 が完全透過
    既定値:0.9
  • mode, m[int]
    ログの表示指定
    0, full:全部(既定値)
    1, compact:一部
  • flags, f[flags]
    表示内容の指定。+ でつなげると複数指定が可能
    • queue:フィルタ間の入力番号
    • frame_count_in:入力時のフレーム数
    • frame_count_out:出力時のフレーム数
    • pts:pts 時間
    • time:秒時間
    • timebase:タイムベース
    • format:フォーマット
    • size:解像度
    • rate:フレームレート
  • rate, r[video_rate]
    描写のフレームレート指定
    既定値:25

応用例

rgba で出力されるので元映像に乗せた方が見やすい。
ffplay -i input -vf split[v],graphmonitor=1280x720:o=.6:f=frame_count_in+time:r=24000/1001:m=1,[v]overlay

agraphmonitor フィルタを使う場合。
ffplay -f lavfi -i movie=input.mp4[v];amovie=input.mp4,asplit[out1],agraphmonitor=1280x720:o=.6:f=time:r=24000/1001,[v]overlay[out0]

文字の色は白のままなので colorkey フィルタでバックの黒だけ透過させ、lutrgb フィルタで別の色に変える。
ffplay -i input.mp4 -vf split[v],graphmonitor=1280x720:o=1:f=rate+size:r=24000/1001:m=1,colorkey=black,lutrgb=255:255:0,[v]overlay

ffmpeg でクロマキー合成 : colorkey
Windows の ffmpeg で生放送する方法 : lutrgb

ffplay の基本起動オプション

$
0
0

ffplay で起動時にオプションを指定することで解像度や表示位置、音量などを調整できる。

ffplay のショートカットキー

ffplay Documentation : Main options

オプション

[] で囲まれてなければ引数不要で有効化する。

  • x[width]
    起動時の横解像度の指定。y も同時に指定する
  • y[height]
    起動時の縦解像度の指定。x も同時に指定する
  • fs
    フルスクリーンで起動
  • an
    音声無効
  • vn
    映像無効
  • sn
    字幕無効
  • ss[pos]
    再生開始時間の指定
  • t[duration]
    再生時間の指定
  • seek_interval[seconds]
    キーボード「←/→」キーでシークする秒時間の指定
  • noborder
    プレイヤーの縁を非表示
  • volume[volume]
    起動時の音量指定。0 が無音、100 が最大音量(既定値)
  • f[fmt]
    フォーマットの強制
  • window_title[window]
    縁左上に表示されるタイトルの指定
  • af[filter_graph]
    オーディオフィルタの指定
  • vf[filter_graph]
    ビデオフィルタの指定
  • showmode[mode]
    表示モードの指定。キーボード「w」と同じ
    • 0:video
    • 1:waves
    • 2:RDFT
  • i
    入力ファイルの指定。使わなくても入力ファイルから類推する
  • codec[decoder_name]
    デコーダの強制。主にハードウェアデコーダや、外部ライブラリのデコーダで使う
  • autorotate
    メタデータから映像を回転させる
  • autoexit
    最後まで再生が終われば終了
  • exitonkeydown
    キーボードでキー入力すれば終了
  • exitonmousedown
    マウスでボタン入力すれば終了

透過部分だけに色を付ける

$
0
0

Replace transparent pixels (alpha) with black in ffmpeg? – Stack Overflow より、透過情報のある画像、または映像に透過部分を別の色に変えて透過情報を消すコマンド。

透過部分に映る色を color=black で指定するか、FFFFFF形式の RGB で指定する。
ffmpeg -i in.png -filter_complex "color=black,format=rgb24;[0]scale2ref[i];[i]overlay=format=auto:shortest=1,setsar=1" out.png
ffmpeg -i in.png -filter_complex "color=000000,format=rgb24;[0]scale2ref[i];[i]overlay=format=auto:shortest=1,setsar=1" out.png

映像と音声の pts を扱う setpts, asetpts

$
0
0

pts を処理することで再生速度を上げたり下げたり、複数のファイルを合わせたりするときに pts を揃えたりするのに使う setpts, asetpts フィルタの使い方。

基本コマンド

再生速度を2倍にする。
ffmpeg -i input -filter_complex setpts=(PTS-STARTPTS)/2;atempo=2 output

再生速度を半分にする。
ffmpeg -i input -filter_complex setpts=2*(PTS-STARTPTS);atempo=0.5 output

【ffmpeg】倍速再生できる動画にエンコードする

2つの映像の pts を 0 開始に揃えて縦に並べる。
ffmpeg -i input1 -i input2 -filter_complex [0:v]setpts=PTS-STARTPTS[v0];[1:v]setpts=PTS-STARTPTS[v1];[v0][v1]vstack output

公式ドキュメント:FFmpeg Filters Documentation : setpts, asetpts

オプション

評価式のオプション

  • FRAME_RATE
    フレームレート。固定フレームレートだけを定義する
  • PTS
    PTS(presentation timestamp)
  • N
    0 から始まる映像フレーム数、または音声サンプル数
  • NB_CONSUMED_SAMPLES
    累積の音声サンプル数
  • NB_SAMPLES, S
    現在の音声サンプル数
  • SAMPLE_RATE, SR
    音声サンプルレート
  • STARTPTS
    入力した映像の pts
  • STARTT
    最初のフレームの動画時間
  • INTERLACED
    現在のフレームがインターレースかどうか。インターレースなら 1。そうでなければ 0
  • T
    現在のフレームの動画時間(秒)
  • POS
    現在のフレーム数。分からなければ未定義になる
  • PREV_INPTS
    1つ前フレームの PTS
  • PREV_INT
    1つ前フレームの T
  • PREV_OUTPTS
  • PREV_OUTT
  • RTCTIME
    RTC のマイクロ秒。現在は非推奨。代わりに time(0) を使う
  • RTCSTART
    RTC のマイクロ秒。マイクロ秒で動く
  • TB
    タイムスタンプのタイムベース

応用例

pts を 25fps に修正する。映像がそれよりも高fpsなら再生速度が遅くなり、低fpsなら再生速度が速くなる。
ffplay -f lavfi -i testsrc2=r=60,setpts=N/(25*TB)
ffplay -f lavfi -i testsrc2=r=10,setpts=N/(25*TB)

開始 pts を10秒進める。
setpts=PTS+10/TB

フレーム数から現在のタイムスタンプ秒に変換しタイムスタンプを振り直す。
setpts=N/FRAME_RATE/TB

音声サンプル数から現在のタイムスタンプ秒に変換しタイムスタンプを振り直す。
asetpts=N/SR/TB

タイムスタンプを振り直すのは trim, select フィルタなどで複数に分割、特定フレームだけ出力する場合に使う。振り直さなければ元映像の pts で分割されるので、出力されなかった映像は動かなくなる。
ffmpeg -i input -an -vf select=eq(pict_type\,I) -vsync 0 -t 5 output.mp4
ffmpeg -i input -an -vf select=eq(pict_type\,I),setpts=N/FRAME_RATE/TB -vsync 0 -t 5 output.mp4

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

再エンコードせずに fps を変更する

$
0
0

Using ffmpeg to change framerate – Stack Overflow より、H.264, H.265 の映像を再エンコードせずにフレームレート(fps)を変更する方法。映像のフレームレートだけなので音声は再エンコードしないと速度を変えられない。音声の速度変更は atempo, rubberband フィルタのどちらかを使う。

【ffmpeg】倍速再生できる動画にエンコードする
サンプリング周波数を変えずにテンポとピッチを変える rubberband

元映像のフレームレートよりも入力フレームレートを大きくすれば再生速度は速く、動画時間は短くなる。反対に入力フレームレートを小さくすれば再生速度は遅く、動画時間は長くなる。

H.264 の場合。
ffmpeg -i input.mp4 -c copy output.h264
ffmpeg -r 12 -i output.h264 -c copy output.mp4
ffmpeg -r 36 -i output.h264 -c copy output.mp4

音声も合わせるなら映像の速度に合わせて atempo も揃える。
ffmpeg -r 36 -i output.h264 -i input.mp4 -filter_complex [1:a]atempo=1.5[a] -map 0 -c:v copy -map [a] -c:a aac output.mp4

H.265 の場合。
ffmpeg -i input.mp4 -c copy output.h265
ffmpeg -r 12 -i output.h265 -c copy output.mp4
ffmpeg -r 36 -i output.h265 -c copy output.mp4

フィールドタイプや色域を記述する setparams

$
0
0

ffmpeg 4.1 から使えるフィルタ。出力映像のフィールドタイプや色域などの色情報を記述する setparams フィルタの使い方。 入力映像は変更しないがフィルタやエンコーダの処理方法に影響を与える。

基本コマンド

SD 解像度の設定で記述する。
ffmpeg -i input -vf setparams=field_mode=prog:range=tv:color_primaries=smpte170m:color_trc=smpte170m:colorspace=smpte170m output

HD 解像度の設定で記述する。
ffmpeg -i input -vf setparams=field_mode=prog:range=tv:color_primaries=bt709:color_trc=bt709:colorspace=bt709 output

ちなみに、showinfo フィルタで色域などの色情報を調べることができる。ただし古いバージョンだと表示しない
ffplay -i input -vf showinfo

n:   0 pts:      0 pts_time:0       pos:  615334 fmt:yuv420p sar:1/1 s:640x360 i:P iskey:1 type:I checksum:34D2040D 
plane_checksum:[4CFF3752 C34B881E EC87448E] mean:[126 117 133] stdev:[52.7 7.8 6.1]
color_range:tv color_space:smpte170m color_primaries:smpte170m color_trc:smpte170m

しかし、setparams フィルタで書き換えても idet フィルタで調べたフィールドタイプは変えられない。

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

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

オプション

オプションの既定値はすべて auto になっている。int 型指定だが、対応する数字とオプション数が一致していない場合があるので文字指定する。

  • field_mode[int]
    • auto
    • bff
    • tff
    • prog
  • range[int]
    • auto
    • unspecified, unknown
    • limited, tv, mpeg
    • full, pc, jpeg
  • color_primaries[int]
    • auto
    • bt709
    • unknown
    • bt470m
    • bt470bg
    • smpte170m
    • smpte240m
    • film
    • bt2020
    • smpte428
    • smpte431
    • smpte432
    • jedec-p22
  • color_trc[int]
    • auto
    • bt709
    • unknown
    • bt470m
    • bt470bg
    • smpte170m
    • smpte240m
    • linear
    • log100
    • log316
    • iec61966-2-4
    • bt1361e
    • iec61966-2-1
    • bt2020-10
    • bt2020-12
    • smpte2084
    • smpte428
    • arib-std-b67
  • colorspace[int]
    • auto
    • gbr
    • bt709
    • unknown
    • fcc
    • bt470bg
    • smpte170m
    • smpte240m
    • ycgco
    • bt2020nc
    • bt2020c
    • smpte2085
    • chroma-derived-nc
    • chroma-derived-c
    • ictcp

レンズ補正フィルタ lenscorrection

$
0
0

レンズ補正フィルタは他に frei0rlensfun などの外部フィルタがある。手動補正なのであらかじめレンズの視野(Field of View)を調べておくと設定が楽になる。

基本コマンド

既定値での設定。k1, k2 が0なので変化しない。
ffmpeg -i input -vf lenscorrection=cx=0.5:cy=0.5:k1=0:k2=0 output

video – Is there a way to remove GoPro fisheye using ffmpeg – Stack Overflow より k1 の計算方法。

GoPro 3 setting: 16 x 9 Widescreen :: H fov = 69.5 || V fov = 118.2 || Diag = 133.6
118.2 / 69.5 * 133.6 = 227.216, k1=227

GoPro のここでは HERO5 の FOV のデータが公開されている。
jp.gopro.com/help/articles/Question_Answer/HERO5-Black-Field-of-View-FOV-Information より

垂直画角(V. FOV) 水平画角(H. FOV) 対角画角(Diag)
4 x 3 W 94.4 122.6 149.2
4 x 3 M 72.2 94.4 115.7
4 x 3 N 49.1 64.6 79.7
16 x 9 W 69.5 118.2 133.6
16 x 9 M 55 94.4 107.1
16 x 9 N 37.2 64.4 73.6

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

オプション

  • cx[double]
    ゆがみ補正する中心を横方向の相対位置で指定
    既定値:0.5
    範囲:0 から 1 まで
  • cy[double]
    ゆがみ補正する中心を縦方向の相対位置で指定
    既定値:0.5
    範囲:0 から 1 まで
  • k1[double]
    補正係数
    既定値:0
    範囲:-1 から 1 まで
  • k2[double]
    補正係数の2乗
    既定値:0
    範囲:-1 から 1 まで

変換例

サンプル画像は縦横平行な格子状の画像
ffmpeg -f lavfi -i color=white:s=502x402 -vf drawgrid=width=20:height=20:thickness=1:color=black -frames 1 output.png
k1, k2 の指定値

-1, 0

-0.5, 0

-0.1, 0

0.1, 0

0.5, 0

1, 0

0, -1

0, -0.5

0, -0.1

0, 0.1

0, 0.5

0, 1

-1, -1

-0.5, -0.5

-0.1, -0.1

0.1, 0.1

0.5, 0.5

1, 1


ニコ生を外部ツールで見ながら録画する

$
0
0

配信形式が RTMP から HLS に変わり同じアカウントで録画しながら配信を見ると片方が止まることがあるのでそれを回避する方法。今回はTSではなくライブ配信を対象とする。使用するツールは ffmpeg と ffplay で録画しながら tee プロトコルで UDP に配信している。別の配信を同時に配信する場合はポート番号の 8080 を変更する。

FFmpeg Formats Documentation : tee

ユーザー生放送のライブの RTMP はうまく受信できない。さらに HLS は直ぐにプレイリストにアクセスできなくなるのでコメントビューワを同時に起動して配信コメントを受信する。それでもアクセスできなくなり録画が中断することもあるし、セグメント欠けを起こすこともある。

HLS
ffmpeg -i "https://pb0528a2b77.dmc.nico/hlslive/ht2_nicolive/nicolive-hamster-lvXXXXXX_main_badfa6014ab3f4035be820bca7b38f89fbd4f3fde9125e29f761be998c0dc306/1/ts/playlist.m3u8?ht2_nicolive=123456.0k3c77_pkhzkh_29bc3k7rwlg4n" -vsync passthrough -frame_drop_threshold 4 -copytb 1 -map 0:0 -map 0:1 -flags +global_header -reset_timestamps 1 -c copy -f tee "[f=mpegts:onfail=ignore]udp://localhost:8080|output1.ts"

RTMP
ffmpeg -i "rtmp://nlakmjpk.live.nicovideo.jp:1935/live/aqkv_yuwb_2@s191116?auth=dbEcbdkbCc3dnctd_azbnasawazcYaUcnaW-bCj2O9-frG-vga-xxyBFq_zACEmx&aifp=0191210" -vsync passthrough -frame_drop_threshold 4 -copytb 1 -map 0:0 -map 0:1 -flags +global_header -reset_timestamps 1 -c copy -f tee "[f=mpegts:onfail=ignore]udp://localhost:8081|output2.ts"

チャンネルの RTMP はパッチを当てないと配信が読み込めない
ffmpeg -f live_flv -i "rtmp://nlech01.live.nicovideo.jp:1935/onairliveedge/live_181229_20_5/lvXXXXXX live=1 nofcsub=1 conn=S:123456:lvXXXXXX:16:1546082569:150:20a71271e9a52178 cmdinv=nlPlayNotice cmdinvamf=S:rtmp://chnl03.ep.live.nicovideo.jp:1935/publicorigin/181229_18_1/ cmdinvamf=S:lvXXXXXX?:30:ee10e37a7d32862b cmdinvamf=S:lvXXXXXX cmdinvamf=N:-2" -vsync passthrough -frame_drop_threshold 4 -copytb 1 -map 0:0 -map 0:1 -flags +global_header -reset_timestamps 1 -c copy -f tee "[f=mpegts:onfail=ignore]udp://localhost:8082|output3.ts"

パッチを当てた ffmpeg とコマンド例は以下を参照。
N を使わない新しいニコ生用の rtmpdump と ffmpeg(librtmp)

受信方法は ffplay で UDP を開く。VLC ではうまく開けない。
set SDL_AUDIODRIVER=directsound
ffplay -f mpegts udp://localhost:8080

指定フレーム毎に順番を入れ換える shuffleframes

$
0
0

映像のフレーム順を入れ換える shuffleframes フィルタの使い方。AviSynth の SelectEvery のように使える。逆再生にする場合は reverse フィルタを使う。

応用例
1フレームに複数のフレームを表示する tile

基本コマンド

引数はスペース区切りの 0 フレーム目から指定する。-1 を指定するとフレームがドロップする。

3フレーム毎に、2フレーム目と3フレーム目を入れ換える。
ffmpeg -i input -vf "shuffleframes=0 2 1" output

4フレーム毎に 4, 8, 12 … のように4番目のフレームがドロップする。
ffmpeg -i input -vf "shuffleframes=0 1 2 -1" output

4フレーム毎に、2, 3, 4番目のフレームがドロップする。
ffmpeg -i input -vf "shuffleframes=0 -1 -1 -1" output

30000/1001 の映像を5フレーム毎に5番目のフレームがドロップし、pts, fps を修正する。
ffmpeg -i input -vf "shuffleframes=0 1 2 3 -1,setpts=N/((24000*TB)/1001)" -r 24000/1001 output

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

映像と音声の pts を扱う setpts, asetpts
ffmpeg でのフレームレート設定の違い
映像と音声を逆再生にエンコードする

上下左右を入れ換える vflip, hflip

$
0
0

解像度はそのままに上下左右を入れ換える vflip, hflip フィルタの使い方。似たフィルタに rotate, transpose フィルタがある。

映像を任意の角度に回転させる rotate
ピクセル数はそのままに映像を回転させる transpose

基本コマンド

vflip, hflip フィルタともに引数を取らない。
ffmpeg - i input -vf vflip output
ffplay - i input -vf vflip

オリジナル

vflip(上下反転)

hflip(左右反転)

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

ピクセル数はそのままに映像を回転させる transpose

$
0
0

ピクセル数はそのままなので、1280X720 だと、90度回転すると 720X1280 になる。似たフィルタに rotate, hflip, vflip フィルタがある。

映像を任意の角度に回転させる rotate
上下左右を入れ換える vflip, hflip

基本コマンド

ffmpeg - i input -vf transpose=cclock_flip output
ffplay - i input -vf transpose=0

オリジナル

cclock_flip(反時計回りに90度回転し上下反転)

clock(時計回りに90度回転)

cclock(反時計回りに90度回転)

clock_flip(時計回りに90度回転し上下反転)

ffplay - i input -vf transpose=1,transpose=1

clock を2回(時計回りに180度回転)

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

オプション

  • dir[int]
    回転方向の設定
    • 0, cclock_flip
      反時計回りに90度回転し上下反転。既定値
    • 1, clock
      時計回りに90度回転
    • 2, cclock
      反時計回りに90度回転
    • 3, clock_flip
      時計回りに90度回転し上下反転
  • passthrough[int]
    フィルタを当てた後の縦と横の解像度を比較して回転をそのままにするかやめるかの設定
    • none
      なにもしない。既定値
    • portrait
      縦解像度が横解像度以上になるとフィルタの結果そのまま返す
    • landscape
      横解像度が縦解像度以上になるとフィルタの効果を打ち消す

映像を任意の角度に回転させる rotate

$
0
0

任意の角度に回転でき、時間経過で回転させたり止めたりできる rotate フィルタの使い方。似たフィルタに transpose, hflip, vflip フィルタがある。

上下左右を入れ換える vflip, hflip
ピクセル数はそのままに映像を回転させる transpose

基本コマンド

角度はラジアン指定なので慣れてないと混乱しやすい。1ラジアンは時計回りに約57.3度回転。PI, hypot, min などの書き方。
ffmpeg -i input -vf rotate=a=1 output
ffplay -i input -vf rotate=1

オリジナル

rotate=1

時計回りに45度回転させる。
ffplay -i input -vf rotate=45*PI/180

rotate=45*PI/180

回転しても見切れないように出力解像度を大きくする。
ffplay -i input -vf rotate=45*PI/180:ow='hypot(iw,ih)':oh=ow

rotate=45*PI/180:ow=’hypot(iw,ih)’:oh=ow

回転しても映像が常に映る(余白が表示されない)ように出力解像度を小さくする。
ffplay -i input -vf rotate=t*60*PI/180:ow='min(iw,ih)/sqrt(2)':oh=ow

rotate=t*60*PI/180:ow=’min(iw,ih)/sqrt(2)’:oh=ow

1ラジアン回転させて映像が丁度見切れない解像度に縦横を調節する。
ffplay -i input -vf rotate=1:ow=rotw(1):oh=roth(1)

rotate=1:ow=rotw(1):oh=roth(1)

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

オプション

特定の時間だけフィルタを当てるならタイムライン編集、特定の時間に角度を変化させるなら評価式を使う。1ラジアンは約57.3度でπが180度。

  • angle, a[string]
    時計回りに回転させる角度のラジアン指定。マイナスで反時計回り。評価式が使える
  • out_w, ow[string]
    出力解像度の横幅。回転したときの余白を調整する。フレーム間でのサイズ変更はできない。評価式が使える
  • out_h, oh[string]
    出力解像度の縦幅。回転したときの余白を調整する。フレーム間でのサイズ変更はできない。評価式が使える
  • fillcolor, c[string]
    余白の色指定。色名指定とRRGGBB形式が使える https://ffmpeg.org/ffmpeg-utils.html#color-syntax
    既定値:black
  • bilinear[boolean]
    回転したときに bilinear で映像補間する
    既定値:1(有効)

評価式

  • n
    映像のフレーム数。0開始
  • t
    映像のタイムスタンプ秒。0開始
  • hsub
    横方向のクロマサブサンプル値。yuv422p なら 2
  • vsub
    縦方向のクロマサブサンプル値。yuv422p なら 1
  • in_w, iw
    入力映像の横幅
  • in_h, ih
    入力映像の縦幅
  • out_w, ow
    出力映像の横幅。out_w, ow で変更できる
  • out_h, oh
    出力映像の縦幅。out_h, oh で変更できる
  • rotw(a)
    out_w, ow で aラジアン回転させた分だけの横幅
  • roth(a)
    out_h, oh で aラジアン回転させた分だけの縦幅

ffmpeg でダウンロード速度を制限する

$
0
0

よく使われるのがリアルタイムの re であるが、それだと1倍速にしかならないので音声の PTS を加工して速度を調整する。

本来のダウンロード速度は制限前より高速であることが前提である。倍速の逆数を asetpts フィルタで変更し arealtime フィルタでリアルタイム処理にする。

1.1倍速の例
ffmpeg -i "https://example.com/hls/playlist.m3u8" -c copy output.ts -af asetpts=10*PTS/11,arealtime -vn -f null -

1.5倍速の例
ffmpeg -i "https://example.com/hls/playlist.m3u8" -c copy output.ts -af asetpts=2*PTS/3,arealtime -vn -f null -

2倍速の例
ffmpeg -i "https://example.com/hls/playlist.m3u8" -c copy output.ts -af asetpts=PTS/2,arealtime -vn -f null -

異なる fps を連結して VFR の動画にする

$
0
0

今まで ffmpeg は異なるフレームレートの動画を1つに出力するのはできないと思っていたが、あらかじめ異なるフレームレートにエンコードしておいて、その後に連結すれば VFR の動画になる。

方法は以前書いた demuxer の concat を使えば楽に VFR の動画になる。注意点は映像音声ともに同じコーデックで同じエンコード設定、音声は同じサンプリング数であること。ただし動画によっては「Non-monotonous DTS in output stream 0:0」のエラーが出るが再生して問題なかったら気にしない。

concat を使い分ける
【ffmpeg】動画・音声を連結する concat の使い方 其の3
再エンコードせずに fps を変更する
ffmpeg で使える映像のテストソース

ffmpeg -f concat -safe 0 -i 24-30.txt -c copy vfr.mp4

24-30.txt

file 24p.mp4
file 30p.mp4
file 24p.mp4


動画へのファイルパスはシングルクオート(’)で挟む。

file 'E:/video/24p.mp4'
file 'E:/video/30p.mp4'
file 'E:/video/24p.mp4'

再生してファイルがおかしい場合は H.264, H.265 の raw コンテナに入れてみる。
ffmpeg -i 24p.mp4 -c copy -an 24p.264
ffmpeg -i 30p.mp4 -c copy -an 30p.264

映像と音声を合わせる
ffmpeg -f concat -safe 0 -i raw.txt -f concat -safe 0 -i 24-30.txt -map 0:v -map 1:a -c copy vfr.mp4

raw.txt

file 24p.264
file 30p.264
file 24p.264

動画サンプル作成コマンド
ffmpeg -f lavfi -i testsrc2=r=24000/1001:d=10 24p.mp4
ffmpeg -f lavfi -i testsrc2=r=30000/1001:d=10 30p.mp4


RGB の色味を手軽に調整できる vibrance

$
0
0

RGB それぞれの色を強く、弱く、反転できる vibrance フィルタの使い方。他にも似たフィルタがあるが、輝度係数の指定があるのが特徴。

基本コマンド

intensity を上げて RGB を同じようにコントラストを上げる
ffmpeg -i input -vf vibrance=intensity=0.5:rbal=1:gbal=1:bbal=1 output
ffplay -i input -vf vibrance=0.5:1:1:1

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

オプション

  • intensity[float]
    強度指定。プラスでコントラストを強く、マイナスでモノクロからネガポジのようになる
    既定値:0(変化なし)
    範囲:-2 から 2 まで
  • rbal[float]
    Red(赤)のバランス指定
    既定値:1
    範囲:-10 から 10 まで
  • gbal[float]
    Green(緑)のバランス指定
    既定値:1
    範囲:-10 から 10 まで
  • bbal[float]
    Blue(青)のバランス指定
    既定値:1
    範囲:-10 から 10 まで
  • rlum[float]
    明るさをRGBのRからどの割合にするかの指定
    既定値:0.072186
    範囲:0 から 1 まで
  • glum[float]
    明るさをRGBのGからどの割合にするかの指定
    既定値:0.715158
    範囲:0 から 1 まで
  • blum[float]
    明るさをRGBのGからどの割合にするかの指定
    既定値:0.715158
    範囲:0 から 1 まで

映像の上に映像をのせる overlay

$
0
0

映像を重ねてワイプを作ったり、重ねた映像を動かしたりできる overlay フィルタの使い方。重ねる映像は動画と画像どちらもできる。重ねる映像の解像度が背景となる映像よりも小さくなければならない。

基本コマンド

input1 の中央に input2 の中央を配置。
ffmpeg -i input1 -i input2 -filter_complex overlay="x=(W-w)/2:y=(H-h)/2" output

右下隅から左上10ピクセルに配置。
"overlay=x=main_w-overlay_w-10:y=main_h-overlay_h-10"

右上から左上に向かって1フレーム1ピクセル移動する。
"overlay=x=W-n:y=0"

1枚の画像をオーバーレイするにはループ入力する。
ffmpeg -i video.mp4 -loop 1 -i img.jpg -filter_complex overlay="x=(W-w)/2:y=(H-h)/2" output

動画をループ入力する。
ffmpeg -stream_loop -1 -i video.mp4 -loop 1 -i img.jpg -filter_complex overlay="x=(W-w)/2:y=(H-h)/2" -fflags +genpts output

ffmpeg で無限入力が可能に
ループ回数を指定できる loop, aloop

1枚画像どうしを入力して1枚画像にする場合にはループ入力しなくてよい。
ffmpeg -i img1.jpg -i img2.jpg -filter_complex overlay="x=(W-w)/2:y=(H-h)/2" output.jpg

アニメGIF, APNG は ignore_loop 0 を付けると無限ループする。アニメWebp は現在のところデコードできない。
ffmpeg -i video.mp4 -ignore_loop 0 -i img.gif -filter_complex overlay="x=(W-w)/2:y=(H-h)/2" output

透過部分だけに色を付ける
ffmpeg で動画にロゴ画像を追加し透過させる

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

オプション

  • x[string]
    オーバーレイする映像の左上の横座標。評価式が使える
  • y[string]
    オーバーレイする映像の左上の縦座標。評価式が使える
  • eof_action[int]
    2入力した映像が終了したときの1入力した映像の挙動指定。framesync を参照
  • eval[int]
    x, y で指定した値どのように更新するか
    • 0, init:最初に決めたら更新しない
    • 1, frame:フレーム毎に更新。既定値
  • shortest[boolean]
    時間の短いファイルが最後まで処理したら終了する
    既定値:0(終了しない)
  • format[int]
    出力フォーマットの指定
    • yuv420:既定値
    • yuv422
    • yuv444
    • rgb
    • gbrp
    • auto
  • repeatlast[boolean]
    時間の短いファイルが最後まで処理し、時間の長いファイルが最後まで処理し終わるまで、時間の短いファイルの最終フレームを繰り返す
    既定値:1(終了する)
  • alpha[int]
    合成モードの指定。詳しくは後述
    • 0, straight:unpremultiplied, non-premultiplied とも言う。既定値
    • 1, premultiplied

評価式

ffmpeg で使える計算書式 を使って複雑な計算ができる。

  • main_w, W:1入力目の横の解像度
  • main_h, H:1入力目の縦の解像度
  • overlay_w, w:1入力目の横の解像度
  • overlay_h, h:2入力目の縦の解像度
  • x:x で指定した値
  • y:y で指定した値
  • hsu:横方向のクロマサブサンプル値。yuv422p なら 2
  • vsub:縦方向のクロマサブサンプル値。yuv422p なら 1
  • n:映像のフレーム数。0開始
  • pos:映像のバイトサイズの位置。不明なら NAN
  • t:映像のタイムスタンプ秒。不明なら NAN

応用例

タイムスタンプのエラーが出るときには2入力ともに setpts=PTS-STARTPTS フィルタを当てて開始時間を0秒からにする。
ffmpeg -i input1 -i input2 -filter_complex [0:v]setpts=PTS-STARTPTS[0v];[1:v]setpts=PTS-STARTPTS[1v];[0v][1v]overlay="x=(W-w)/2:y=(H-h)/2" output

x y
左上隅 0 0
右上隅 W-w 0
左下隅 0 H-h
右下隅 W-w H-h

ループ

表示方法は2通りあり、端に見切れ初めてすべて見切れたときに再び表示される場合と、見切れたら同時に再び表示する場合がある。後者は同時に2つの映像がオーバーレイされているので2度 overlay フィルタを当てる。

右上から左上にループ。
ffmpeg -i input1 -i input2 -filter_complex overlay=x=W-mod(n\,W+w):y=0" output

1表示ループ x y
左から右 mod(n\,W+w)-w
右から左 W-mod(n\,W+w)
下から上 H-mod(n\,H+h)
上から下 mod(n\,H+h)-h

右上から見切れずに左上にループ。
ffmpeg -i input1 -i input2 -filter_complex "overlay=x=W-mod(n\,2*W):y=0[o];[o][1:v]overlay=x=W-mod('if(between(n,0,W),0,n-W)'\,2*W):y=0" output

2表示ループ x x
左から右 -w+MOD(n\,2*w) -w+mod(‘if(between(n,0,W),0,n-W)’\,2*W)
右から左 W-mod(n\,2*W) W-mod(‘if(between(n,0,W),0,n-W)’\,2*W)
2表示ループ y y
下から上 H-mod(n\,2*H) H-mod(‘if(between(n,0,H),0,n-H)’\,2*H)
上から下 -h+mod(n\,2*H) -h+mod(‘if(between(n,0,H),0,n-H)’\,2*H)

時計回り、反時計回り

適宜+-60の部分とsin(), cos() を入れ換えれば開始位置と回転方法を変えられる。回転速度は *n を変更する。

中央右60ピクセルから時計回りに回る
ffmpeg -i input1 -i input2 -filter_complex "overlay=x=(W-w)/2+60*cos((PI*n)/180):y=(H-h)/2+60*sin((PI*n)/180)" output

中央右60ピクセルから反時計回りに回る
ffmpeg -i input1 -i input2 -filter_complex "overlay=x=(W-w)/2+60*cos((PI*n)/180):y=(H-h)/2-60*sin((PI*n)/180)" output

中央上60ピクセルから時計回りに回る
ffmpeg -i input1 -i input2 -filter_complex "overlay=x=(W-w)/2+60*sin((PI*n)/180):y=(H-h)/2-60*cos((PI*n)/180)" output

中央上60ピクセルから反時計回りに回る
ffmpeg -i input1 -i input2 -filter_complex "overlay=x=(W-w)/2-60*sin((PI*n)/180):y=(H-h)/2-60*cos((PI*n)/180)" output

x y
中央 (W-w)/2 (H-h)/2
時計回り、右 (W-w)/2+60*cos((PI*n)/180) (H-h)/2+60*sin((PI*n)/180)
反時計回り、右 (W-w)/2+60*cos((PI*n)/180) (H-h)/2-60*sin((PI*n)/180)
反時計回り、左 (W-w)/2-60*cos((PI*n)/180) (H-h)/2+60*sin((PI*n)/180)
時計回り、左 (W-w)/2-60*cos((PI*n)/180) (H-h)/2-60*sin((PI*n)/180)
時計回り、上 (W-w)/2+60*sin((PI*n)/180) (H-h)/2-60*cos((PI*n)/180)
反時計回り、上 (W-w)/2-60*sin((PI*n)/180) (H-h)/2-60*cos((PI*n)/180)
時計回り、下 (W-w)/2-60*sin((PI*n)/180) (H-h)/2+60*cos((PI*n)/180)
反時計回り、下 (W-w)/2+60*sin((PI*n)/180) (H-h)/2+60*cos((PI*n)/180)

対角線

左上から右下
ffmpeg -i input1 -i input2 -filter_complex "overlay=x=-w+((W+w)/(H+h))*n:y=-h+n" output

左下から右上
ffmpeg -i input1 -i input2 -filter_complex "overlay=x=-w+((W+w)/(H+h))*n:y=H-n" output

対角線 x y
左上から右下 -w+((W+w)/(H+h))*n -h+n
右上から左下 W-((W+w)/(H+h))*n -h+n
左下から右上 -w+((W+w)/(H+h))*n H-n
右下から左上 W-((W+w)/(H+h))*n H-n

alpha モード

オーバーレイする動画に予め透過具合に応じて色を変更するのが premultiplied

詳しい話は外部記事で。
コンポジターに必要なアルファチャンネルの知識(前編) – コンポジゴク
コンポジターに必要なアルファチャンネルの知識(後編) – コンポジゴク

ffmpeg -f lavfi -i color=red,format=rgba,geq='p(X,Y):p(X,Y):p(X,Y):clip(255-sqrt(pow(X,2)+pow(Y,2)),0,255)',lutrgb=255:val:val:val -vframes 1 red.png
ffmpeg -f lavfi -i color=gray,format=rgba -vframes 1 gray.png
ffmpeg -i gray.png -i red.png -filter_complex overlay=alpha=0:format=rgb overlay-alpha0.png
ffmpeg -i gray.png -i red.png -filter_complex overlay=alpha=1:format=rgb overlay-alpha1.png
赤背景に左上から円周上に透過

グレー一色

overlay=alpha=0、Rが透過具合によって減少

overlay=alpha=1、Rだけに少しづつGBが加算

overlay_opencl

opencl を使って overlay_opencl フィルタを使う。

opencl が使えれば以下のコマンドを実行すると対応 CPU、または GPU が表示される。
ffmpeg -hide_banner -v verbose -init_hw_device opencl

出力コマンド例。

ポイントは opencl を使うデバイスを上の例では 0.0 から 1.1 から指定する。能力によって処理速度が大きく異なる。オプション指定は通常と同じ。

コマンド例。ポイントは2入力とも hwupload フィルタを使う。
ffmpeg -init_hw_device opencl=ocl:1.0 -filter_hw_device ocl -i video.mp4 -loop 1 -i img.png -filter_complex "[0:v]hwupload[0v];[1:v]format=yuva420p,hwupload[1v];[0v][1v]overlay_opencl" output

通常のフィルタに切り替えるには hwdownload,format=yuv420p フィルタを挟む。
ffmpeg -init_hw_device opencl=ocl:1.0 -filter_hw_device ocl -i video.mp4 -loop 1 -i img.png -filter_complex "[0:v]hwupload[0v];[1:v]format=yuva420p,hwupload[1v];[0v][1v]overlay_opencl,hwdownload,format=yuv420p,lutyuv=val:128:128 output

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

リサイズする scale

$
0
0

標準で使える scale フィルタの使い方。外部ライブラリに zscale フィルタがありこちらは HDR、高品質リサイズ向けで処理速度は scale フィルタより速くない。

Zライブラリを使ったリサイズフィルタ zscale

基本コマンド

アスペクト比を維持しながら横幅1280ピクセルにリサイズする。
ffmpeg -i input -vf scale=1280:-1 output

さらに縦幅が奇数になる場合には繰り上げて偶数にする。
ffmpeg -i input -vf scale=1280:-2 output

アスペクト比を維持しながら長辺1280ピクセルより大きいとき長辺1280ピクセルにリサイズする。小さければそのまま。
ffmpeg -i input -vf "scale=if(gte(iw\,ih)\,min(1280\,iw)\,-2):if(lt(iw\,ih)\,min(1280\,ih)\,-2)" output

リサイズ方法を lanczos に変える。
ffmpeg -i input -vf scale=1280:-2:flags=lanczos output
ffmpeg -i input -vf scale=1280:-2 -sws_flags lanczos output

accurate_rnd を併用する。
ffmpeg -i input -vf scale=1280:-2 -sws_flags accurate_rnd+lanczos output

ガンマ補正を行う。既定値では行わない。
ffmpeg -i input -vf scale=1280:-2 -gamma 1 output

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

オプション

  • width, w[string]
    出力解像度の横幅
    0 は入力と同じ。-1 はアスペクト比を揃えて縦解像度に合わせる。-n でnの倍数で割りきれるように繰り上げて調整する
  • height, h[string]
    出力解像度の縦幅
    0 は入力と同じ。-1 はアスペクト比を揃えて横解像度に合わせる。-n でnの倍数で割りきれるように繰り上げて調整する
  • size, s[string]
    横幅x縦幅。使える書式
  • flags[string]
    リサイズアルゴリズムの指定。設定値は後述
  • interl[boolean]
    インターレース保持のリサイズ指定
    • 0:保持しない。既定値
    • 1:保持する
  • in_color_matrix[string]
    入力カラーマトリクス
    • auto:既定値
    • bt709
    • fcc
    • bt601
    • smpte240m
  • out_color_matrix[string]
    出力カラーマトリクス
    設定値は in_color_matrix と同じ
  • in_range[int]
    入力カラーレンジ
    • auto, unknown
    • jpeg, full, pc
    • mpeg, limited, tv
  • out_range[int]
    出力カラーレンジ
    設定値は in_range と同じ
  • force_original_aspect_ratio[int]
    縦横どちらに合わせアスペクト比維持してリサイズするか
    • 0, disable:無効。既定値
    • 1, decrease:短い方に合わせる
    • 2, increase:長い方に合わせる
  • param0, param1
    不明
  • eval[int]
    リサイズの評価方法。動的にリサイズできるオプションがないので用途不明
    • init:1フレーム目で固定
    • frame:フレーム毎に変動

縦横幅に使える書式

これも使える。ffmpeg で使える計算書式

  • in_w, iw
    入力横幅
  • in_h, ih
    入力縦幅
  • out_w, ow
    横幅(width, w)で指定した値。縦幅の指定に横幅でリサイズした後の値を使うときに使う
  • out_h, oh
    縦幅(height, h)で指定した値。横幅の指定に縦幅でリサイズした後の値を使うときに使う
  • a
    iw / ih
  • sar
    サンプルアスペクト比
  • dar
    (iw / ih) * sar
  • hsub, vsub
    入力クロマサブサンプル値。yuv422p だと hsub は 2、vsub は 1
  • ohsub, ovsub
    出力クロマサブサンプル値。yuv422p だと hsub は 2、vsub は 1

リサイズアルゴリズム

  • fast_bilinear
  • bilinear
  • bicubic
  • experimental
  • neighbor
  • area
  • bicublin
  • gauss
  • sinc
  • lanczos
  • spline
  • print_info
  • accurate_rnd
  • full_chroma_int
  • full_chroma_inp
  • bitexact

mp4, mp3 にカバーアートを付ける

$
0
0

カバーアートを付けるとエクスプローラにサムネイルが表示、変更できる。

H.264 だとサムネイルが表示されるが、H.265 だと表示されないのがこれで表示できる。サムネイルは PNG でも可能。
ffmpeg -i movie.mp4 -i thumb.jpg -disposition:v:1 attached_pic -map 0 -map 1 -c copy movie-with-cover.mp4

MP3 の場合。
ffmpeg -i audio.mp3 -i thumb.jpg -disposition:v:1 attached_pic -map 0 -map 1 -c copy -id3v2_version 3 -metadata:s:v title="Album cover" -metadata:s:v comment="Cover (front)" audio-with-cover.mp3

ffmpeg でメタデータを加える | ニコラボ
albumart – How to add album art with ffmpeg? – Stack Overflow

disposition の設定
音声が2つ以上あるときに再生したとき最初に流れる音声を代えられる。ただし MKV コンテナに限る。

2番目の音声を最初に再生するコマンド例。
ffmpeg -i movie.mp4 -map 0:v -map 0:a -c copy -disposition:a:0 0 -disposition:a:1 default output.mkv

ffmpeg Documentation
-disposition[:stream_specifier] value (output,per-stream)
具体的にそれぞれにどのような効果があるのか分からない。

  • default
  • dub
  • original
  • comment
  • lyrics
  • karaoke
  • forced
  • hearing_impaired
  • visual_impaired
  • clean_effects
  • attached_pic
  • captions
  • descriptions
  • dependent
  • metadata

映像に余白を追加する pad

$
0
0

余白を追加することで、別のアスペクト比の映像に手軽に変換できる。ただし出力解像度が奇数になるとピクセルフォーマット次第で余白がずれたり、エンコードエラーになる。

基本コマンド

下のコマンドでエラーが出るときは setsar=1 フィルタを最初に当てる。

オリジナルの解像度に横に60ピクセル、縦に20ピクセル追加し、映像を横に30ピクセル、縦に10ピクセルずらし、余白の色を白にする。
ffmpeg -i input -vf pad=w=iw+60:h=ih+20:x=30:y=10:color=white output
ffplay -i input -vf pad=iw+60:ih+20:30:10:ffffff
ffplay -i input -vf setsar=1,pad=iw+60:ih+20:30:10:ffffff

16:9の映像を横幅固定で4:3の映像にして中央に配置。
ffmpeg -i input -vf pad=y=(ih-oh)/2:aspect=4/3 output
ffplay -i input -vf pad=y=(ih-oh)/2:aspect=4/3
ffplay -i input -vf setsar=1,pad=y=(ih-oh)/2:aspect=4/3

4:3の映像を縦幅固定で16:9の映像にして中央に配置。
ffmpeg -i input -vf pad=x=(iw-ow)/2:aspect=16/9 output
ffplay -i input -vf pad=x=(iw-ow)/2:aspect=16/9
ffplay -i input -vf setsar=1,pad=x=(iw-ow)/2:aspect=16/9

次の方法でも行える:4:3を16:9に、16:9を4:3に余白をつける

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

オプション

  • width, w[string]
    出力解像度の横幅
    0 は入力と同じ。-1 はアスペクト比を揃えて縦解像度に合わせる。-n でnの倍数で割りきれるように繰り上げて調整する
    既定値:iw
  • height, h[string]
    出力解像度の縦幅
    0 は入力と同じ。-1 はアスペクト比を揃えて横解像度に合わせる。-n でnの倍数で割りきれるように繰り上げて調整する
    既定値:ih
  • x[string]
    入力した映像の横座標のオフセット値
    既定値:0(左)
  • y[string]
    入力した映像の縦座標のオフセット値
    既定値:0(上)
  • color[color]
    追加した余白の色の指定。rrggbb 形式も可能
    既定値:black
  • eval[int]
    リサイズの評価方法。動的にリサイズできるオプションがないので用途不明
    • init:1フレーム目で固定
    • frame:フレーム毎に変動
  • aspect[rational]
    出力解像度のアスペクト比の指定。縦または横の長さに合わせて出力解像度を変更する。1にすると縦横が同じサイズになり、16:9の映像に対して、16/9にすると変化がない
    既定値:0/1(オリジナルのまま)

縦横幅に使える書式

これも使える。ffmpeg で使える計算書式

  • in_w, iw
    入力横幅
  • in_h, ih
    入力縦幅
  • out_w, ow
    横幅(width, w)で指定した値。縦幅の指定に横幅でリサイズした後の値を使うときに使う
  • out_h, oh
    縦幅(height, h)で指定した値。横幅の指定に縦幅でリサイズした後の値を使うときに使う
  • x
    x で指定した値。不明なら NAN
  • y
    y で指定した値。不明なら NAN
  • a
    iw / ih
  • sar
    サンプルアスペクト比
  • dar
    (iw / ih) * sar
  • hsub, vsub
    入力クロマサブサンプル値。yuv422p だと hsub は 2、vsub は 1
Viewing all 310 articles
Browse latest View live


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