[8日目] LiveWedgeの録画で分割されたmp4ファイルをつなぎ合わせる方法

koba koba

こんにちは、小林です。組込みソフトウェアを担当しています。
昨日は金星探査機「あかつき」の周回軌道投入と、その記者会見のライブ中継をかじりついて見ていました。私も技術者のはしくれなので、設計したものが設計の通りに動くことですら簡単ではないことは日々痛感しています。ましてや、一度失敗してしまって修理もできないものをリカバリーするのは気の遠くなるほど難しいことはよくわかります。メインエンジンは壊れてしまったし、残りの部分も設計寿命をこえて劣化しています。しかもやり直しが効かない一発勝負です。正直絶対無理だと思っていました。この記事を書いている時点では、まだ成否は確定していませんが、この段階まで持って行くことができただけでもすごいとしかいいようがありません。携わっている方々の執念を感じました。
(12/9 追記) 周回軌道投入は成功だそうです。おめでとうございます! (追記 ここまで。)

さて、アドベントカレンダー8日目はLiveWedgeに関係するTipsです。

LiveWedgeではSDカードに録画をすることができます。録画を開始すると、SDカードの残り容量が100MBを切るまでは録画を継続するので大きなサイズのSDカード(SDXCカードの128GBまで試しています)を使うとかなりの長時間の録画ができます。
ただし、LiveWedgeの搭載メモリに限りがあるため、以下の条件で録画ファイルを分割するようになっています。
(1) ファイルのサイズが4000 * 1024 * 1024 バイトを超えた
(2) 150分以上経過した

もしかしたら、いいところで録画ファイルが分割されてしまうことがあるかもしれません。しかし、分割したときでも可能な限りデータの欠落がないようにしているので、後からつなぎ合わせることができます。

この記事のタイトルの通り、LiveWedgeの録画で分割されたmp4ファイルをつなぎ合わせる方法として私のおすすめの方法を紹介します。
ffmpegというコマンドを使用します。

この方法の利点は
(1) 無料のツールだけでできる
(2) 再エンコードしないので画質の劣化がない
(3) 同じく再エンコードしないので処理時間が短い

ffmpegを使用して、まずmp4ファイルを一度mpegtsのフォーマットに変換し、mpegtsファイルどうしを連結してから再度mp4に戻します。これをコマンド一発で行うスクリプトを用意しました。
大量のデータ転送が発生するので、mp4ファイルはあらかじめ高速なSSDにコピーしておき、カレントディレクトリもSSDにするのがおすすめです。私のMacBookProでは2つに分割された合計5時間の録画ファイルをひとつにつなぐのに約1分で完了しました。

ffmpegの入手

ffmpegは以下のところからダウンロードすることができます。
https://www.ffmpeg.org/download.html
ソースコードからビルドしてもいいですが、ビルド済みのバイナリを取ってくるのが手軽です。
環境変数PATHをセットして、以下のようにコマンドラインから実行できれば、準備OKです。

$ ffmpeg -version
ffmpeg version 2.7.2-tessus Copyright (c) 2000-2015 the FFmpeg developers
built with Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn)
configuration: --cc=/usr/bin/clang --prefix=/opt/ffmpeg --as=yasm --extra-version=tessus --enable-avisynth --enable-fontconfig --enable-gpl --enable-libass --enable-libbluray --enable-libfreetype --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopus --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libvidstab --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzmq --enable-version3 --disable-ffplay --disable-indev=qtkit --disable-indev=x11grab_xcb
libavutil      54. 27.100 / 54. 27.100
libavcodec     56. 41.100 / 56. 41.100
libavformat    56. 36.100 / 56. 36.100
libavdevice    56.  4.100 / 56.  4.100
libavfilter     5. 16.101 /  5. 16.101
libswscale      3.  1.101 /  3.  1.101
libswresample   1.  2.100 /  1.  2.100
libpostproc    53.  3.100 / 53.  3.100

Mac, Linuxの場合

以下をコピペしてconcat_mp4.sh という名前で保存します。

#!/bin/sh -x
if [ $# -ne 3 ]; then
  echo "Usage: " $0 " input1.mp4 input2.mp4 output.mp4" 1>&2
  exit 1
fi
FFMPEG=ffmpeg
TEMP1="$1.$$.ts"
TEMP2="$2.$$.ts"
$FFMPEG -f mp4 -i $1 -c copy -bsf:v h264_mp4toannexb -f mpegts $TEMP1
$FFMPEG -f mp4 -i $2 -c copy -bsf:v h264_mp4toannexb -f mpegts $TEMP2
$FFMPEG -y -i "concat:$TEMP1|$TEMP2" -c copy -bsf:a aac_adtstoasc -f mp4 $3
rm -f $TEMP1 $TEMP2

実行権を付与します

$ chmod +x ./concat_mp4.sh

20151021T175814_000.mp4と20151021T175814_001.mp4を連結してout.mp4として保存するならば、以下のようにコマンドを実行します。

$ ./concat_mp4.sh 20151021T175814_000.mp4 20151021T175814_001.mp4 out.mp4

Windowsの場合

以下をコピペしてconcat_mp4.bat という名前で保存します。

if "%~3"=="" (
  echo Usage: %~0 input1.mp4 input2.mp4 output.mp4
  exit /b 1
)
setlocal
set FFMPEG=ffmpeg
set TEMP1="%1.%RANDOM%.ts"
set TEMP2="%2.%RANDOM%.ts"
%FFMPEG% -f mp4 -i %1 -c copy -bsf:v h264_mp4toannexb -f mpegts %TEMP1%
%FFMPEG% -f mp4 -i %2 -c copy -bsf:v h264_mp4toannexb -f mpegts %TEMP2%
%FFMPEG% -y -i "concat:%TEMP1%|%TEMP2%" -c copy -bsf:a aac_adtstoasc -f mp4 %3
del %TEMP1% %TEMP2%

20151021T175814_000.mp4と20151021T175814_001.mp4を連結してout.mp4として保存するならば、以下のようにコマンドを実行します。

> concat_mp4.bat 20151021T175814_000.mp4 20151021T175814_001.mp4 out.mp4

最後に

今回はコマンドラインで使えるMP4動画を連結する方法を紹介しました。
なお、連結してサイズが4GBを超えたファイルはFATでフォーマットされているSDカードには書き戻すことはできませんので、念のため。