/var/www/yatta47.log

/var/www/yatta47.log

やったのログ置場です。スクラップみたいな短編が多いかと。

ffmpegでファイルをリストにして、動画を連結させる方法

ffmpegで動画を連結する方法を調べています。具体的にはflvファイルね。

探せばいっぱい出てくるんだけど、どうもやりづらいというか、自分に合わないというか・・・・入力がめんどくさいと思ったので、他の方法がないかどうかいろいろと探してみました。

自分である程度納得できる形のものがあったのでそれをご紹介。

 

やりたいこと(おさらい)

複数の動画があって、それを1つの動画ファイルにまとめたい。そんな時にffmpegを使って出来ないかなーと思って調べています。なので前提条件として、同じアスペクト比、同じ画像サイズってことになります。

ffmpegのバージョンは以下。

$ ffmpeg -v
ffmpeg version 2.5.4 Copyright (c) 2000-2015 the FFmpeg developers
  built on Feb 15 2015 21:43:03 with gcc 4.8 (Ubuntu 4.8.2-19ubuntu1)
  configuration: --extra-libs=-ldl --prefix=/opt/ffmpeg --enable-avresample --disable-debug --enable-nonfree --enable-gpl --enable-version3 --enable-libpulse --enable-libopencore-amrnb --enable-libopencore-amrwb --disable-decoder=amrnb --disable-decoder=amrwb --enable-libx264 --enable-libx265 --enable-libfdk-aac --enable-libvorbis --enable-libmp3lame --enable-libopus --enable-libvpx --enable-libspeex --enable-libass --enable-avisynth --enable-libsoxr --enable-libxvid --enable-libvo-aacenc --enable-libvidstab

 

よく見かけた方式はconcat

一番見かけるのは出ているconcatを使う方式

FFmpegで動画作成する方法 - Qiita

【ffmpeg】動画・音声を連結する concat の使い方 - ニコニコ動画研究所

書式としてはこんな感じ。

ffmpeg -i input1.mp4 -i input2.mp4 -filter_complex "concat=n=2:v=1:a=1" output.mp4

「input1.mp4」とか「input2.mp4」が入力の動画ファイル。重要なのはそれ以降のパラメータですね。

-filter_complex "concat=n=2:v=1:a=1" 

n=の後ろに連結したい動画の数を指定、v=がビデオ、a=がオーディオで、1が結合する、0が結合しないのフラグになるようです。で、最後のoutput.mp4ってのが結合後の出力ファイル名になっています。

これで動画結合することが出来ます。

ただ・・・・・ただですよ・・・・・

めんどくさい!!

 

入力ファイル指定するのがめんどくさい

動画ファイルが10個とかあったら、-iで指定するのが凄くめんどくさい。なので、他の方法がないかどうか調べてみたら・・・・・ありました!!

方法としては、Concat demuxerを使う方式があるようです。

ここに詳しいやり方が書いてあります。

Concatenate – FFmpeg

簡単に説明すると書式としては以下。

$ffmpeg -f concat -i mylist.txt -c copy output

 

入力ファイルとして、-iで動画ファイルのリスト化したテキストファイルを指定します。outputが出力名です。

mylist.txtの書式は以下。これで連結する動画ファイルを指定します。

# this is a comment
file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'

このファイル自体はワンライナーで簡単に作ることが出来ます。

# with a bash for loop
for f in *.flv; do echo "file '$f'" >> mylist.txt; done
# or with printf
printf "file '%s'\n" ./*.wav > mylist.txt

Linuxの場合は相対パスで書いても大丈夫でした。

個人的に好みなのはfor文で回すほうですね。

これでリストを作って、それを指定してやれば簡単!注意点としては、連結したい順番になるように並び替える必要がある時がありますね。

 

これでだいぶ楽になった

ファイルに連結したいファイルを書いてそれを基準にして連結することも出来たのは新しい発見でした。ffmpeg、まだまだ奥が深いなー。

でも動画が再エンコードしたせいなのか、劣化しているように見える。本当に劣化しているかどうかってのは自分の目だからあてにならんよなぁ。無劣化でできるかどうかもそのうち調べよう。

 

追記(2017/1/21)

どうやら、ファイル名に日本語(2バイト文字)が入っていると以下のエラーが出るようです。

[concat @ 0x4c40860] Unsafe file name 'あいうえお_part1.flv'
mylist.txt: Operation not permitted 

その場合はファイル名を半角英数に変えてあげるとちゃんと使えました。

ファイル数が少ない場合は手動でやってもいいと思いますがたくさんあるとめんどくさいですよね・・・・その辺もどうにかしたいないあ。