画像ファイルサイズを原則3MBにしました。
最大3000KBまで投稿できるようになりました。感謝っ・・・・!圧倒的感謝っ・・・・!
- 投稿可能上限:3000KB=1024bytes×3000=3072000bytes
- 拡張子:.mp4 .webm
- コンテナ:MKV MP4 WEBM
- コーデック:VP9 H.264 AAC HE-AACv2 Opusが実用的
- 高圧縮形式:MKV & VP9 & HE-AACv2(40kbps未満) またはOpus framesize60
(おそらく)日本一の画像掲示板ふたばちゃんねるが動画も投稿できることをご存知ですか。
仕様
- 投稿可能上限:2000KB=1024bytes×2000=2048000bytes WEBM板は3000KB
- 拡張子:.mp4 .webm
- コンテナ:MKV MP4 WEBM
- コーデック:VP9 VP8 H.264 AAC HE-AACv2 Opusが実用的
- 高圧縮形式:MKV & VP9 & HE-AACv2(40kbps未満) ∨ Opus framesize60
動画共有サービスとしてみると貧弱な仕様、1フレーム目がサムネイルになる。以下メモ。
あればエンコードに便利なツール
- Aviutl
- 拡張編集プラグイン
- リサイズフィルタ by Nilposoft
- エッジレベル調整 MT
- バンディング低減 MT SIMD
- ぼかしフィルタ
- NL-Means Light for GPU 強い味方
- FFmpeg
- FFprobe
- audacity
- opusenc
- neroAacEnc
- vpxenc libvpx_v1.8.2_win64ビルド ※要Microsoft Visual C++ 2019 Runtime
- 高画質、高音質なソースを用意する
- ノイズが乗った動画はノイズを除去する
- 高周波成分の多い動画はあえてデノイズフィルタをかけてぼかすとエンコ結果がよくなる
- 基本yuv420、赤と青の彩度の高い色が多い動画でビットレートに余裕有りならyuv444
- 解像度をさげても画質向上はそれほどない、VP9は低解像度で圧縮効率悪化する
- アニメは逆テレシネする、動きの多いシーンはフレームを間引く
- 被写体を切り抜いて背景をぼかす
- ビットレートに余裕あればバンディングノイズ除去してエッジ補正する、サイズは増える
- 古い動画はTVレンジPCレンジがおかしい、ヒストグラムを見て拡張色調補正で直せる
- bt709とbt601の扱いを間違えると色が変わる
- 色深度,色域,ガンマ,YUV⇔RGB変換式、NTSC規格、ブラウン管を調べたら楽しかった
- としあきならCMYKとかAdobeRGBとか色の大切さはわかるはず
- なぜAviUtlはRGBもYUVも10bitも正しく扱えるの?→YC48という内部形式を使ってる
- bt709とbt601の色域はどうやって変換してるの→xyz色空間を介してる
- https://trev16.hatenablog.com/entry/2019/03/31/220300
- 色とはいったい…なんだ?→https://qiita.com/Ushio/items/203f16ad1e23fd42231c
- デインターレースは映画&アニメ24fps→自動フィールドシフト、TV&実写→Yadif60fps
- 可変フレームレートを使うconcatとか、いわゆるVFR動画、最終手段
- 動画を分割し別々のビットレートでエンコードしてconcatで連結、最終手段
- HE-AACv2で音声ビットレートを32kbps以下にする、MKVである必要あり、最終手段
- neroAacEncのHE-AACv2は音質が良いが位相がズレる→あらかじめ音声を編集しておく
- 音声ビットレート40kbpsまではOpusのframesize 60がいい感じそれ未満はHE-AACv2
- H.264で言うところのプロファイルVP9のLevelは4がベストこれより上だと低負荷最適化
- 急ぎの編集はYoutubeのVP9をキーフレーム編集で切って時短、再エンコが不要で早い
- ドット絵やゲームを拡大縮小するならリサイズアルゴリズムnearest neighborボケない
- 拡張編集のリサイズフィルタなら補間なしをチェックでnearest neighborになる
- VP9におけるI、P、BフレームはI、P、golden frames、alt ref frames
- YUVで色差成分が間引かれてる様子はGIMPの色分解で調べられるNL-Means適用の参考
- yuv444の0-255フルレンジもといPCレンジはRGB888と等価...でない、計算誤差あり
- 色ズレ、階調抜け、階調飛びによるバンディングノイズを防ぐため中間ファイルは10bit
- 計算誤差やクロマサブサンプリングのズレ、補完繰り返しが怖いのでYUVのまま扱いたい
- 人間の目は横の解像度が低い、横解像度を削りアス比指定でエンコ、大した効果はない
- 2Pass可変ビットレート、タイル列は2、タイル行は1、行は分けた境界が圧縮されない
- タイル列を増やせばマルチコアでデコード、増やすほど圧縮効率が少し落ちる
- 高圧縮で高負荷にしない妥協ポイント、タイル列は2、タイル行は1
- --tile-columns=2 --tile-rows=1のこと
- opusenc、neroAacEncともに-helpをつけて実行するとヘルプ、オプション一覧が出る
- AviUtlのシャープフィルタは範囲を1下限値を0上限値を1024で強さを調整して効果確認
- 古いテレビ動画や高圧縮で彩度の失われたものはAviUtl色調補正フィルタ色の濃さで調整
- カラーバーさえわかればhttp://gnb.on.coocan.jp/tutorial/s_scope/s_scope.htm
- AviUtlもfpsを分数で正確に指定できる59.940059...=60000/1001ほかに24000/1001
- concatじゃなくてフレームを間引いてPTS、DTS調整して可変フレームレートにもできる
- concatとどちらがより手間なのか
動画を連結
ffmpeg.exe -f concat -i files.txt -c copy out.webm
file "PATH"←のように列挙したテキストファイル、例では"files.txt"を作る
HE-AACV2エンコード
neroAacEnc.exe -hev2 -q 0.02 -if -of
OPUSエンコード(--framesizeは大きいとストリーミングで不都合だけど高圧縮、ふたば用)
opusenc.exe --framesize 60 --bitrate 75 "InputFile" "OutputFile"
画像ファイルから静止画動画(フレームレート長く、この方法ならスライドショーもいける)
ffmpeg -framerate 100/20562 -i LM.bmp -i LM.opus -c:v libvpx-vp9 -pix_fmt yuv420p -b:v 500K -c:a copy -r 100/20562 temp1.webm
(簡単25 fpsのフレームが1つできる)
ffmpeg -i 動画.AVI -i 画像.bmp -c:v libvpx-vp9 -pix_fmt yuv420p -b:v 5000K -c:a copy temp1.webm
2パスでいつもの
(1pass)
ffmpeg -i src.mp4 -c:v libvpx-vp9 -pix_fmt yuv420p -b:v 160K -keyint_min 24 -threads 2 --tile-columns=0 --tile-rows=1 -quality best -level 4.0 -auto-alt-ref 1 -lag-in-frames 25 -arnr-maxframes 15 -arnr-strength 6 -aq-mode 1 -pass 1 -f webm -an -f null -
(ffmpeg2pass-0.logってのがカレントに出力されてるはず、続けて2pass)
ffmpeg -i src.mp4 -c:v libvpx-vp9 -pix_fmt yuv420p -b:v 160K -keyint_min 24 -threads 2 --tile-columns=0 --tile-rows=1 -quality best -level 4.0 -auto-alt-ref 1 -lag-in-frames 25 -arnr-maxframes 15 -arnr-strength 6 -aq-mode 1 -pass 2 -c:a libopus -b:a 96k -frame_duration 60 out.webm
-keyint_minは最小キーフレーム間隔。エンコーダーはシーンチェンジ検出によって自動的にキーフレームの挿入をするが、それを無理やり減らす。この値を大きくすればP、golden frames、alt ref framesを使うしかないので圧縮率は上げられるがシーンチェンジ後の画面の変化が大きいと破綻する副作用がある。苦手なシーンとして例えばエヴァンゲリオンのオープニング後半のフラッシュカット。
追記:明らかにキーフレーム間隔が狭そうな箇所を見つけて検証したけど-keyint_min効かない、FFmpegにリンクされているlibvpx-vp9じゃなくてlibvpx付属のvpxencだと使える...終わりの方にさらに追記
-b:v 160K -b:a 96k 目標ビットレート、読み替えて
-bsf:v vp9_metadata=color_space=bt709 か
-bsf:v vp9_metadata=color_space=bt601つけとこ-c:v libvpx-vp9より前に記述する
FFprobeで素材がbt709かbt601か調べとく、複数の素材があって編集するならbt709にAviUtlでもFFmpegのビデオフィルタでもいいけど変換して統一しとく。HDRとかはまだそんなに無いでしょ
-aq-mode は1にしたけど2でも。3、4はだめ。心理視覚的に最適化する、自然の風景のようなのっぺらとごちゃごちゃが混ざったような画の心理的画質を大幅に上げる。特撮とかよいのでは。PSNRやSSIM、VMAF等画質評価アルゴリズム的には悪し。ベンチマークするでないし、ふたばに貼る分には設定
-auto-alt-ref 1 -lag-in-frames 25 -arnr-maxframes 15 -arnr-strength 6
代替参照フレームalt ref framesを最大限使う設定。圧縮率は上げられるアーティファクトのリスクもあがる。-lag-in-framesって -rc_lookaheadじゃないの?→要はaliasてこと-arnr_max_framesと-arnr-maxframesも同じ。
https://people.xiph.org/~j/ivfenc_ffmpeg.html
--tile-columns=0 --tile-rows=1
分割の最小設定、エンコードもデコードもCPUのスレッドを2つしか使わない。代わりに予測も画面分割されないので圧縮率があがる。だが重くなる。この設定で解像度大きめの動画をエンコして貼ったらまあ迷惑かも。
-frame_duration 60
Opusのフレームサイズ、デフォルトの20だと低ビットレートで段々ときつくなってくる
ffmpeg -h encoder=libopus見ると-frame_duration 120もあるけど通るのか…?
追記:通った
-lag-in-frames 25 -arnr-maxframes 15 と -frame_duration 60
動画をきれいにループさせたいなら値を小さくする
-lag-in-frames 2 -arnr-maxframes 2 と -frame_duration 10
とか
全フレームキーフレームで-lag-in-frames 1、-frame_duration 2.5とかにすればさらに上手く繋がるはず。ビットレートは下げられないけどGIFより圧縮してくれる、音付きの死にたいGIFが作れる。
vpxencを使え おそらくこれがベスト
元動画をy4m化
ffmpeg -i src.mp4 -pix_fmt yuv420p -f yuv4mpegpipe temp.y4m
Opus化
ffmpeg -i src.mp4 -c:a libopus -frame_duration 120 -b:a ビットレート[kbps] audio.opus
(1pass)
vpxenc --threads=2 --end-usage=vbr --passes=2 --pass=1 --fpf=FirstPassStatisticsFile.fpf --best --target-level=40 --tile-columns=0 --tile-rows=1 --color-space=bt709 --output=FirstPassStatisticsFile.fpf temp.y4m
(2pass)
vpxenc --threads=2 --end-usage=vbr --passes=2 --pass=2 --target-bitrate=ビットレート[kbps] --fpf=FirstPassStatisticsFile.fpf --best --target-level=40 --tile-columns=0 --tile-rows=1 --color-space=bt709 --aq-mode=2 --kf-min-dist=4 --lag-in-frames=25 --auto-alt-ref=0 --arnr-maxframes=15 --arnr-strength=6 --output=video.webm temp.y4m
(2pass、こっちはGFとAltRefの間隔を大きく空けてキーフレーム挿入はエンコーダに任せる)
vpxenc --threads=2 --end-usage=vbr --passes=2 --pass=2 --target-bitrate=ビットレート[kbps] --fpf=FirstPassStatisticsFile.fpf --best --target-level=40 --tile-columns=0 --tile-rows=1 --color-space=bt709 --aq-mode=2 --min-gf-interval=4 --lag-in-frames=25 --auto-alt-ref=1 --arnr-maxframes=15 --arnr-strength=6 --output=video.webm temp.y4m
音声とMUX
ffmpeg -i audio.opus -i video.webm -c:v copy -c:a copy out.webm
太字のところは適当に読み替え--color-space=bt601が適切かもしれないし--kf-min-dist=はもっと小さい値にしたほうが破綻を防げるかもしれないということ。ただし--kf-max-dist=の既定値120(たぶん)を超えるとエラーになる。短いシーンチェンジがなくてかつ1シーンの動きが連続しているようなら--kf-max-dist=、--kf-min-dist=両方に大きい値を指定してキーフレーム間隔を広くしてもいいかもしれない。副作用としてシークが遅くなる。
--auto-alt-ref=を無効にすることになるので基本的には--min-gf-interval=でAltRefを増やしてキーフレームの挿入はエンコーダに任せるのがおすすめ。amiroquaiのVirtual Insanityみたいな動画はこのオプションがかなり効く。
実際見てわかる程度には画質が上がる
vpxencのオプション一覧、--disable-kfとかとんでもないのあるな。timebaseはFFmpegでなんとかして。ちなみにHE-AACv2を使うならFFmpegでMKVにコンテナを入れ替えないといけない。品質指定を使えば画質を詰められるけど流石にだるい。どのフレームがキーフレームかはAviUtlでも調べられるググって。
vpxenc.exe -help
Usage: vpxenc <options> -o dst_filename src_filename
Options:
-D, --debug Debug mode (makes output deterministic)
-o <arg>, --output=<arg> Output filename
--codec=<arg> Codec to use
-p <arg>, --passes=<arg> Number of passes (1/2)
--pass=<arg> Pass to execute (1/2)
--fpf=<arg> First pass statistics file name
--limit=<arg> Stop encoding after n input frames
--skip=<arg> Skip the first n input frames
-d <arg>, --deadline=<arg> Deadline per frame (usec)
--best Use Best Quality Deadline
--good Use Good Quality Deadline
--rt Use Realtime Quality Deadline
-q, --quiet Do not print encode progress
-v, --verbose Show encoder parameters
--psnr Show PSNR in status line
--webm Output WebM (default when WebM IO is enabled)
--ivf Output IVF
-P, --output-partitions Makes encoder output partitions. Requires IVF output!
--q-hist=<arg> Show quantizer histogram (n-buckets)
--rate-hist=<arg> Show rate histogram (n-buckets)
--disable-warnings Disable warnings about potentially incorrect encode settings.
-y, --disable-warning-prompt Display warnings, but do not prompt user to continue.
--test-decode=<arg> Test encode/decode mismatch
off, fatal, warnEncoder Global Options:
--yv12 Input file is YV12
--i420 Input file is I420 (default)
--i422 Input file is I422
--i444 Input file is I444
--i440 Input file is I440
-u <arg>, --usage=<arg> Usage profile number to use
-t <arg>, --threads=<arg> Max number of threads to use
--profile=<arg> Bitstream profile number to use
-w <arg>, --width=<arg> Frame width
-h <arg>, --height=<arg> Frame height
--stereo-mode=<arg> Stereo 3D video format
mono, left-right, bottom-top, top-bottom, right-left
--timebase=<arg> Output timestamp precision (fractional seconds)
--fps=<arg> Stream frame rate (rate/scale)
--error-resilient=<arg> Enable error resiliency features
--lag-in-frames=<arg> Max number of frames to lagRate Control Options:
--drop-frame=<arg> Temporal resampling threshold (buf %)
--resize-allowed=<arg> Spatial resampling enabled (bool)
--resize-width=<arg> Width of encoded frame
--resize-height=<arg> Height of encoded frame
--resize-up=<arg> Upscale threshold (buf %)
--resize-down=<arg> Downscale threshold (buf %)
--end-usage=<arg> Rate control mode
vbr, cbr, cq, q
--target-bitrate=<arg> Bitrate (kbps)
--min-q=<arg> Minimum (best) quantizer
--max-q=<arg> Maximum (worst) quantizer
--undershoot-pct=<arg> Datarate undershoot (min) target (%)
--overshoot-pct=<arg> Datarate overshoot (max) target (%)
--buf-sz=<arg> Client buffer size (ms)
--buf-initial-sz=<arg> Client initial buffer size (ms)
--buf-optimal-sz=<arg> Client optimal buffer size (ms)Twopass Rate Control Options:
--bias-pct=<arg> CBR/VBR bias (0=CBR, 100=VBR)
--minsection-pct=<arg> GOP min bitrate (% of target)
--maxsection-pct=<arg> GOP max bitrate (% of target)Keyframe Placement Options:
--kf-min-dist=<arg> Minimum keyframe interval (frames)
--kf-max-dist=<arg> Maximum keyframe interval (frames)
--disable-kf Disable keyframe placementVP8 Specific Options:
--cpu-used=<arg> CPU Used (-16..16)
--auto-alt-ref=<arg> Enable automatic alt reference frames
--noise-sensitivity=<arg> Noise sensitivity (frames to blur)
--sharpness=<arg> Loop filter sharpness (0..7)
--static-thresh=<arg> Motion detection threshold
--token-parts=<arg> Number of token partitions to use, log2
--arnr-maxframes=<arg> AltRef max frames (0..15)
--arnr-strength=<arg> AltRef filter strength (0..6)
--arnr-type=<arg> AltRef type
--tune=<arg> Material to favor
psnr, ssim
--cq-level=<arg> Constant/Constrained Quality level
--max-intra-rate=<arg> Max I-frame bitrate (pct)
--gf-cbr-boost=<arg> Boost for Golden Frame in CBR mode (pct)
--screen-content-mode=<arg Screen content modeVP9 Specific Options:
--cpu-used=<arg> CPU Used (-8..8)
--auto-alt-ref=<arg> Enable automatic alt reference frames
--sharpness=<arg> Loop filter sharpness (0..7)
--static-thresh=<arg> Motion detection threshold
--tile-columns=<arg> Number of tile columns to use, log2
--tile-rows=<arg> Number of tile rows to use, log2 (set to 0 while threads > 1)
--arnr-maxframes=<arg> AltRef max frames (0..15)
--arnr-strength=<arg> AltRef filter strength (0..6)
--arnr-type=<arg> AltRef type
--tune=<arg> Material to favor
psnr, ssim
--cq-level=<arg> Constant/Constrained Quality level
--max-intra-rate=<arg> Max I-frame bitrate (pct)
--max-inter-rate=<arg> Max P-frame bitrate (pct)
--gf-cbr-boost=<arg> Boost for Golden Frame in CBR mode (pct)
--lossless=<arg> Lossless mode (0: false (default), 1: true)
--frame-parallel=<arg> Enable frame parallel decodability features
--aq-mode=<arg> Adaptive quantization mode (0: off (default), 1: variance 2: complexity, 3: cyclic refresh, 4: equator360)
--alt-ref-aq=<arg> Special adaptive quantization for the alternate reference frames.
--frame-boost=<arg> Enable frame periodic boost (0: off (default), 1: on)
--noise-sensitivity=<arg> Noise sensitivity (frames to blur)
--tune-content=<arg> Tune content type
default, screen
--color-space=<arg> The color space of input content:
unknown, bt601, bt709, smpte170, smpte240, bt2020, reserved, sRGB
--min-gf-interval=<arg> min gf/arf frame interval (default 0, indicating in-built behavior)
--max-gf-interval=<arg> max gf/arf frame interval (default 0, indicating in-built behavior)
--target-level=<arg> Target level (255: off (default); 0: only keep level stats; 10: level 1.0; 11: level 1.1; ... 62: level 6.2)
--row-mt=<arg> Enable row based non-deterministic multi-threading in VP9Stream timebase (--timebase):
The desired precision of timestamps in the output, expressed
in fractional seconds. Default is 1/1000.
VP9(LIBVPX-VP9) のエンコード設定について - ニコラボ
vpxenc --profile=3 --threads=2 --end-usage=vbr --passes=2 --pass=1 --fpf=FirstPassStatisticsFile.fpf --best --target-level=40 --tile-columns=0 --tile-rows=1 --color-space=bt709 --bit-depth=10 --output=FirstPassStatisticsFile.fpf temp.y4m
vpxenc --profile=3 --threads=2 --end-usage=vbr --passes=2 --pass=2 --target-bitrate=ビットレート[kbps] --fpf=FirstPassStatisticsFile.fpf --best --target-level=40 --tile-columns=0 --tile-rows=1 --color-space=bt709 --bit-depth=10 --min-gf-interval=2 --lag-in-frames=25 --auto-alt-ref=1 --arnr-maxframes=15 --arnr-strength=6 --output=video.webm temp.y4m
重複フレーム削除
http://ja.voidcc.com/question/p-bzjsckrs-km.html
x265のキーフレームタイミングでVP9
https://stackoverflow.com/questions/39656715/how-to-force-ffmpeg-not-to-change-keyframe-sequence