LoginSignup
0
2

More than 3 years have passed since last update.

ffmpeg で動画を 100 分割して 1 画面 100 分割表示する

Posted at

対象読者

以下のように、動画を 100 分割して 1 画面 100 分割表示させたい方を対象としています。
output-palette.gif

やり方

10x10.sh
## USAGE: sh 10x10.sh input.mp4
ffmpeg -i "$1" -filter_complex '[0:a]asplit=100'`seq -s '' -f '[a%02g]' 0 99`';[0:v]scale=192:-1,split=100'`seq -s '' -f '[v%02g]' 0 99`';'`ffprobe "$1" -hide_banner -show_entries format=duration | perl -ne 'next if not m{^duration=(.*)$}; printf q([v%1$02d]trim=%2$f:%3$f,setpts=PTS-STARTPTS[v%1$02d];[a%1$02d]atrim=%2$f:%3$f,asetpts=PTS-STARTPTS[a%1$02d];), $_, $1*$_/100, $1*($_+1)/100 for (00 .. 99);'``seq -s '' -f '[v%02g]' 0 99`'xstack=inputs=100:layout='"`perl -e 'for $y (0 .. $ARGV[1] - 1) { $h = ($y ? qq($h+h0) : 0); for $x (0 .. $ARGV[0] - 1) { $w = ($x ? qq($w+w0) : 0); push @o, qq(${w}_$h) } } END { print join q(|), @o }' 10 10`"':shortest=1[v];'`seq -s '' -f '[a%02g]' 0 99`'amix=inputs=100:duration=shortest,loudnorm[a]' -map '[v]' -map '[a]' -shortest output.mp4 -y

上記を保存して、sh 10x10.sh input.mp4 と実行すると、input.mp4 から output.mp4 ができます。バージョン 4.3.1 の ffmpeg ffprobeperl seq を使っています。perlseq は filter 文を生成しているだけです。

処理の流れ

ffmpeg
    -i 'input.mp4'
    -filter_complex '
        [0:a]asplit=100[a00](中略)[a99];
        [0:v]scale=192:-1,split=100[v00](中略)[v99];
        [v00]trim=0.000000:18.099510,setpts=PTS-STARTPTS[v00];[a00]atrim=0.000000:18.099510,asetpts=PTS-STARTPTS[a00];
        (中略)
        [v99]trim=1791.851490:1809.951000,setpts=PTS-STARTPTS[v99];[a99]atrim=1791.851490:1809.951000,asetpts=PTS-STARTPTS[a99];
        [v00](中略)[v99]xstack=inputs=100:layout=0_0|0+w0_0|(中略)|0+w0+w0+w0+w0+w0+w0+w0+w0+w0_0+h0+h0+h0+h0+h0+h0+h0+h0+h0:shortest=1[v];
        [a00](中略)[a99]amix=inputs=100:duration=shortest,loudnorm[a]
    '
    -map '[v]'
    -map '[a]'
    -shortest
    output.mp4
    -y

video [v] の処理

  • scale: 出力は横 1920px 想定なので、ここで 192px にしています。
  • split: ここで 100 個になります。
  • 各入力毎の処理: ffprobe から取得した duration で、それぞれの video input をオリジナルの 1/100 の長さにしています。
  • xstack: 100 個を左上から順に並べます。全入力同じ大きさなので、位置計算には w0 と h0 しか使ってません。

audio [a] の処理

  • asplit: ここで 100 個になります。
  • 各入力毎の処理: ffprobe から取得した duration で、それぞれの audio input をオリジナルの 1/100 の長さにしています。
  • amix: 100 個の音声をミックスします。
  • loudnorm: そのままだと音声が大分小さくなるので、ノーマライズします。

参考文献

0
2
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2