実行環境
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: ''
)になります。