いつまで経ってもffmpegのコマンドが覚えられないヤガーです。
というわけで、今回もよく使うコマンドをご紹介、というか自分用メモ。
このごろイベントの撮影やライブ配信をしていて、固定カメラで動画を長回しすることが結構あるんですが、連続撮影していてもMP4ファイルは4GB制限のために複数ファイルに分かれてしまうんですね。編集ソフトにとりこんでしまえば一緒なので分かれていても良いのですが、特に編集せずにざっくりパートを分けたい時にはffmpegで無劣化で処理できると非常に高速でよいです。
というわけでやってみました。
Contents
環境情報
・macOS Sierra (10.12.6)
$ ffmpeg
ffmpeg version 3.4.2 Copyright (c) 2000-2018 the FFmpeg developers
ffmpegはHomebrewでインストールしたものです。
複数ファイルを無劣化で結合する
以前の記事では再エンコードをかけながら結合する方法を紹介しました。
Ffmpegで複数動画を結合して一つの動画に出力 | Creazy!
この時点では無劣化で再エンコードなしの結合方法がうまくいかなかったんですが、その後うまくいくコマンドが分かりました。
結果からいうと、複数ファイル名をインデックスファイルに記載しておいて、ffmpegコマンドからそのインデックスファイルを指定して結合するコマンドです。
インデックスファイルを作成する
インデックスファイルには、下記のフォーマットで記入します。ファイル件数分改行して記載します。
file 'ファイル名1'
file 'ファイル名2'
例えば、movie1.mp4、movie2.mp4、movie3.mp4の3ファイルあった場合に、インデックスファイル files.txt には下記のように書きます。
file 'movie1.mp4'
file 'movie2.mp4'
file 'movie3.mp4'
インデックスファイルを指定して無劣化コピーする
さて、いよいよ結合です。動画ファイルとインデックスファイルは同階層においてある想定です(パスが異なる場合は指定を変更しましょう)
files.txt
movie1.mp4
movie2.mp4
movie3.mp4
以下の用に実行します。
ffmpeg -safe 0 -f concat -i files.txt -c:v copy -c:a copy -map 0:v -map 0:a output.mp4
【オプション解説】
-safe 0
セーフモード解除(インデックスファイルのパスを絶対パスで指定しない場合は不要らしい)
-f concat
結合する指示を出します
-i files.txt
インデックスファイルを指定
-c:v copy
ビデオコーデックをコピーする(無劣化)
-c:a copy
オーディオコーデックをコピーする(無劣化)
-map 0:v
ビデオファイルが複数存在する場合は全てのものを同梱する
-map 0:a
オーディオファイルが複数存在する場合は、全てのものを同梱する
これで、直列結合の無劣化コピーができました。
無劣化で動画の一部分を切り出す
さて、長い動画ファイルができたのですが、パートで区切って動画を分けたくなることもよくあります。
(この区切りが動画ファイルの区切りと合っていないことも多いので、一旦結合した)
切り出す部分のタイムスタンプを記録しておく
ffmpegで特定部分の切り出しは可能ですが、該当する部分のタイムスタンプを取得する必要があります。
色々方法はあると思うのですが、ボクは簡単にいつも使っている動画プレイヤー「VLC」で再生して該当部分のタイムスタンプをメモしておきました。
切り出す範囲の始めと終わりを「時:分:秒」のフォーマットで記録しておきます。
ffmpegで時間指定で切り出す
このようなオプションで実行します。
ffmpeg -ss {開始時間} -i input.mp4 -ss 0 -t {切り出す秒数} -c:v copy -c:a copy -async 1 -strict -2 output.mp4;
【オプション解説】
-ss {開始時間}
切り出しの開始時間を指定。-iより前に置くのがポイントらしいです
-i input.mp4
元ファイル
-ss 0
おまじないみたいな指定方法
-t {切り出す秒数}
ここは切り出しの終了時間ではなく、-ssで指定した開始時間からの経過時間です
-c:v copy
ビデオコーデックをコピーする(無劣化)
-c:a copy
オーディオコーデックをコピーする(無劣化)
-async 1
音声の同期方法。最初だけ同期して後続のサンプルはそのままといういみ
-strict -2
バージョンによってexperimental(実験的実装)を許可する必要があるので一応付けとく
実際に、4時間半くらいの動画ファイルを4パートに切り出した時に下記のようなコマンドを実行しました。
ffmpeg -ss 1:04:20 -i input.mp4 -ss 0 -t 0:33:25 -c:v copy -c:a copy -async 1 -strict -2 part1.mp4;
ffmpeg -ss 1:46:14 -i input.mp4 -ss 0 -t 0:35:08 -c:v copy -c:a copy -async 1 -strict -2 part2.mp4;
ffmpeg -ss 2:39:17 -i input.mp4 -ss 0 -t 0:33:02 -c:v copy -c:a copy -async 1 -strict -2 part3.mp4;
ffmpeg -ss 3:20:02 -i input.mp4 -ss 0 -t 0:51:18 -c:v copy -c:a copy -async 1 -strict -2 part4.mp4;
それぞれ、3分くらいで出力してくれたので、12分くらいで終了です。動画編集ソフトなどでエンコードもかけつつやるとこの時間ではできないでしょう・・・。うまくいきました。
§
データ量が増えてきたり、同じような作業が連続する場合はffmpegのようなコマンドで作業できると非常に効率的で良いですね。まあ、説明難しいんですけどー。