LoginSignup
4
1

More than 3 years have passed since last update.

FFmpeg 画面を分割して複数動画を合成する

Last updated at Posted at 2020-10-04

実行環境

Node.jsでの実行を想定しているためJavaScriptコードになります。
コマンドラインで同様のコマンドを打てばNode.js以外でも実行可能です。

画面の分割と複数動画の合成

画面を4分割して、左上、右上、左下に動画を合成した場合の例です。

const { execSync } = require('child_process');

function overlay(input1, input2, input3, output)
{
    const stdout = execSync(`ffprobe -i ${input1} -show_streams -print_format json`);
    let streamInfo = JSON.parse(stdout);
    // 幅、高さを取得
    let width = streamInfo.streams[0].coded_width;
    let height = streamInfo.streams[0].coded_height;
    // 4分割後の幅、高さを計算
    let cutWidth = width/2;
    let cutHeight = height/2;
    // コマンド生成
    command = `ffmpeg -i ${input1} -i ${input2} -i ${input3} -filter_complex "\
        amix=inputs=3:duration=longest;\
        [0:v] setpts=PTS-STARTPTS, scale=${cutWidth}x${cutHeight} [upperleft];\
        [1:v] setpts=PTS-STARTPTS, scale=${cutWidth}x${cutHeight} [upperright];\
        [2:v] setpts=PTS-STARTPTS, scale=${cutWidth}x${cutHeight} [lowerleft];\
        [upperleft]pad=2*iw:2*ih[a];\
        [a][upperright]overlay=w:0[b];\
        [b][lowerleft]overlay=0:h\
        " \
        ${output}`;
    // コマンド実行
    execSync(command);
}

コマンド内容

関数前半は、input1のストリーム情報から幅、高さを取得し、4分割後の各動画の幅、高さを計算しています。

Audio

amix=inputs=3:duration=longest;はaudioの合成になります。
amix=inputs=3:duration=longest;を省いた場合は、左上の動画音声のみになります。

Video

[0:v] setpts=PTS-STARTPTS, scale=${cutWidth}x${cutHeight} [upperleft];部分は、
[0:v]:input1のVideoを表しています。
scale=${cutWidth}x${cutHeight}:スケール変更しています。
[upperleft]:upperleftという名前で定義しています。名前なので任意に変更可能。

[1:v] setpts=PTS-STARTPTS, scale=${cutWidth}x${cutHeight} [upperright];
[2:v] setpts=PTS-STARTPTS, scale=${cutWidth}x${cutHeight} [lowerleft];
はinput2、input3に同様の処理を行っています。

[upperleft]pad=2*iw:2*ih[a];
は[upperleft]映像に余白を追加しています。
iwはinput Widthを、ihはinput heightを意味しており、幅、高さ2倍の余白を追加しています。
またそれを[a]という名前で定義しています。

[a][upperright]overlay=w:0[b];
[a][upperright]を横方向座標w([upperright]の幅)、縦方向座標0の位置に合成しています。
またそれを[b]という名前で定義しています。

[b][lowerleft]overlay=0:h
[b][lowerleft]を横方向座標0、縦方向座標h([lowerleft]の高さ)の位置に合成しています。

注意事項

最後のオプション[b][lowerleft]overlay=0:hには;を付けるとエラー(No such filter: '')になります。

実行結果

※動画のスクリーンショットです。
image.png

4
1
0

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
4
1