ffmpeg はとても便利なものですが、コマンドが難しく覚えられません。 使うものをいくつか記録しておきます。
再生 15 秒後から 10 秒間を切り取ります。
ffmpeg -ss 00:00:15 -i input.mp4 -t 10 output.mp4
でも、長い動画だととても時間がかかります。 そういう場合は、開始と終了を指定してやれば一瞬で終了します。
ffmpeg -i input.mp4 -ss 00:00:34 -to 00:00:47 -c copy output.mp4
でも、このコードでも思い通りにカットできないことがあります。
chatGPT に質問すると、
-c copy は再エンコードせずにフレームをそのままコピーします。 動画は**キーフレーム(Iフレーム)**を基準に再生されます。 キーフレーム以外のフレーム(Pフレーム、Bフレーム)は前後のフレームに依存するため、 キーフレームのない場所から切ると、ffmpegはその前のキーフレームから出力を始めてしまいます。 そのため「17秒から始めたい」としても、実際は 直前のキーフレーム時刻から切れてしまい、ずれが発生します。
いや、そんな少しのズレではないんですけどね。
そして、以下のようなコードを提示してきました。
ffmpeg -ss 00:00:17 -to 00:00:25 -i input.mp4 -c copy output.mp4
以前のコードと似ていますが、-ss の位置などが違います。
以前のコードだと、場合によっては 1 秒にも満たないことがあり間違いだったことがわかりました。
ざっくり処理するならこれが最速だと思います。
基本構文は、
ffmpeg -i input.mp4 -af "volume=1.5" output.mp4
dB(デシベル)で調整するのは、
ffmpeg -i input.mp4 -af "volume=5dB" output.mp4
再生 5 秒後から 0.1 秒間の静止画を作成。
#!/bin/sh
mkdir -p after
for ext in mkv mp4 webm; do for file in before/*."$ext"; do [ -f "$file" ] || continue basename=$(basename "$file") name="${basename%.*}" # 拡張子除去 ffmpeg -y -ss 2 -i "$file" -frames:v 1 "after/${name}.jpg" donedone
動画のある部分を切り取ります。
ffmpeg -i aaa.MP4 -vf crop=w=294:h=471:x=885:y=585 output.mp4
大きなサイズの動画を小さくしたいことがあります。
まずは、動画の解像度などを取得します。
ffprobe -v error -show_entries stream=width,height,duration -of default=noprint_wrappers=1 input.mp4
input.mp4 の解像度を 1280✕720 に変更します。
ffmpeg -i input.mp4 -vf scale=1280:720 output.mp4
アスペクト比をそのままにして変更する場合には、
ffmpeg -i input.mp4 -vf scale=640:-1 output.mp4
品質を保つためのオプション。
ffmpeg -i input.mp4 -vf scale=640:-1 -c:v libx264 -crf 23 -preset fast output.mp4
(-crf は画質(0〜51、小さいほど高画質、23がデフォルト)-preset はエンコード速度(ultrafast, fast, slow, veryslowなど))
#!/bin/sh
for file in `find ./before -name "*.mp4"`; dofaname_ext="${file##*/}"fname="${faname_ext%.*}"echo $fnameffmpeg -i $file -pix_fmt yuv420p -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" ./after/$fname.mp4ffmpeg -i $file -ss 1 -t 1 -r 1 -f image2 ./after/$fname.pngdone