Skip to content

Instantly share code, notes, and snippets.

@showa-yojyo
Last active April 22, 2023 05:42
Show Gist options
  • Save showa-yojyo/95d908717b20dc33039a8912a0f208a6 to your computer and use it in GitHub Desktop.
Save showa-yojyo/95d908717b20dc33039a8912a0f208a6 to your computer and use it in GitHub Desktop.
I want to automate this process
title first edition last edition
FFmpeg コマンドライン帳
2023-03-12
2023-04-22

図書館逃避行用

携帯電話でビデオ (MP4) を撮影し、順次 PC にインポートする。

ffprobe で各 MP4 ファイルの尺を得る:

5.995500
5.323800
5.764000
5.211100

次のように ffprobe コマンドを関数なり別名なりでラップしておくと便利だ:

video-duration ()
{
    local input="${1:?Usage: $FUNCNAME INPUT_VIDEO_PATH}";
    local ffprobe_options="
        -hide_banner -v error
        -show_entries format=duration
        -of default=noprint_wrappers=1:nokey=1
        ";
    ffprobe $ffprobe_options "$input"
}

ビデオ間に一秒間クロスフェイドをかけたいので、次の計算をする:

echo 5.995500 - 1 | bc
echo 5.995500 + 5.323800 - 2 | bc
echo 5.995500 + 5.323800 + 5.764000 - 3 | bc
echo 5.995500 + 5.323800 + 5.764000 + 5.211100 - 4 | bc

出力を控える:

4.995500
9.319300
14.083300
18.294400

ここまでをまとめる:

declare -a durations
for i in *.mp4 ; do
    durations+=($(video-duration $i))
done

sum=$(echo ${durations[0]} - 1 | bc)
echo $sum
for ((i=1; i<${#durations[@]}; i++)); do
    sum=$(echo $sum + ${durations[i]} - 1 | bc)
    echo $sum
done

映像と音声とに分けてクロスフェイド処理を施す。映像の方はさらに末尾にフェイドアウトを加え、 全編を通じてテキストをオーバーレイする:

ffmpeg -i 0.mp4 -i 1.mp4 -i 2.mp4 -i 3.mp4 -filter_complex "
    [0:v]setpts=PTS,settb=AVTB,fps=30[v0];
    [1:v]setpts=PTS,settb=AVTB,fps=30[v1];
    [2:v]setpts=PTS,settb=AVTB,fps=30[v2];
    [3:v]setpts=PTS,settb=AVTB,fps=30[v3];
    [v0][v1]xfade=transition=fade:duration=1:offset=4.99550[x1];
    [x1][v2]xfade=transition=fade:duration=1:offset=9.31930[x2];
    [x2][v3]xfade=transition=fade:duration=1:offset=14.0833,
    fade=t=out:st=18.2944:d=1,drawtext=text='図書館逃避行第123回
東京都世田谷区粕谷図書館':fontfile=/mnt/c/Windows/Fonts/UDDigiKyokashoN-R.ttc:
box=0:boxcolor=white@0.5:
x=20:y=20:
shadowx=1:shadowy=1:shadowcolor=deeppink@0.9:
fontcolor=deeppink:fontsize=48:line_spacing=8" -an video.mp4

音声は単純にクロスフェイドのみ施す:

ffmpeg -i 0.mp4 -i 1.mp4 -i 2.mp4 -i 3.mp4 -filter_complex "
    [0:a]asetpts=PTS,asettb=AVTB[a0];
    [1:a]asetpts=PTS,asettb=AVTB[a1];
    [2:a]asetpts=PTS,asettb=AVTB[a2];
    [3:a]asetpts=PTS,asettb=AVTB[a3];
    [a0][a1]acrossfade=d=1:c1=tri:c2=tri[x1];
    [x1][a2]acrossfade=d=1:c1=tri:c2=tri[x2];
    [x2][a3]acrossfade=d=1:c1=tri:c2=tri,
    afade=t=out:st=18.2944:d=1" -vn audio.mp4

最後に、Twitter に投稿するためにデータ量を抑えてエンコードする:

ffmpeg -i video.mp4 -i audio.mp4 -map 0:v -map 1:a \
    -c:v libx264 -pix_fmt yuv420p -strict -2 \
    -c:a aac -vb 1024k -minrate 1024k -maxrate 1024k -bufsize 1024k -ar 44100 -ac 2 -r 30 \
    final.mp4

PC の性能が十分ならば上記の ffmpeg コマンドを一体化してよい。

その他コマンド

音声断片を後付け:

ffmpeg -i audio.mp4 \
  -itsoffset 00:00:01.000000 -i 0.wav \
  -itsoffset 00:00:10.000000 -i 1.wav \
  -itsoffset 00:00:30.000000 -i 2.wav \
  -filter_complex amix="inputs=4:duration=longest" \
  -async 1 audio.mp3

PNG をオーバーレイ:

ffmpeg -i video.mp4 -i title.png -filter_complex "
    [0:v][1:v]overlay" \
    -pix_fmt yuv420p -c:a copy video+title.mp4

以上

@showa-yojyo
Copy link
Author

そろそろ関数に書き換えられそうだ。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment