ffmpegでドラレコの映像を連結する方法

PC/デジモノ

今回は小ネタですが、ドライブレコーダーで撮影した映像をlinux上のffmpegで連結する方法を紹介します。

ファイル分割の問題

ドライブレコーダーはファイルの損失の危険を小さくするために、ファイルを1分ごとなどに分割して記録している場合が多いです。

事故の記録など、本来の用途で使用する場合には(見直すこともないので)これで問題ありません。しかし、旅の記録としてドライブ映像を保存しておきたい場合など、連結にひと手間かかってしまいます。1ファイル1分とすると1時間で60ファイル生成されるわけですから、Davinciなどでこのまま編集しようとするとハンドリングが悪いわけですね。

連結時の問題

もう一つの問題として、単純に連結してしまうとうまくフレームが合わないという点が挙げられます。私が使用しているユピテルのドラレコの場合、1ファイルが1分1秒の長さで、1秒分は2つのファイルに重複して記録されるようになっています。このため、何も考えずに一般的なツールなどを使用して連結してしまうと1分ごとに映像が1秒巻き戻るという不自然な映像になってしまいます。

ユピテルのドラレコでは映像を1秒だけ重複させることでファイル間の映像隙間を絶対に作らないという設計思想でこのような仕様になっていると思われます。他社のドラレコやアクションカムなどではこれとは異なる仕様になっているものもあると思います。本記事ではユピテルのドラレコの場合ならこれでいけるよ、という程度でお考え下さい。最新のモデルや他社モデルではそんな仕様じゃない!などありましたらコメントいただけると嬉しいです。

解決方法

解決策として、ffmpegを使用して各ファイルの後端1秒をカットし、そのあとで全ファイルを連結するという方法をとります。

スクリプト(cbdr.sh)

#!/bin/bash
cd `dirname $0`

#入出力DIRFILEの設定
input_dir=$1
crop_dir=`dirname $0`"/crop"
output=$2
duration="60" #切り出す時間(秒)

#作業用CROPディレクトリを削除する
if [ -d "$crop_dir" ]; then
 rm -rf $crop_dir
fi
mkdir -p $crop_dir

#指定時間で切り出し
for file in "$input_dir"/*;do
 if [[ -f $file ]]; then
  filename=$(basename -- "$file")
  extension="${filename##*.}"
  name="${filename%.*}"
  output_file="$crop_dir/${name}_cut.${extension}"
  ffmpeg -i "$file" -ss 00:00:00 -t "$duration" -c copy "$output_file"
  echo "Processed $file -> $output_file"
 fi
done

#連結ファイルの一覧作成
src_dir=$crop_dir"/*"
file_list="flist.txt"

#一覧ファイルが既にある場合は削除する
if [ -f "$file_list"];then
 rm $file_list
fi

for filepath in $src_dir; do
 echo "file "$filepath >> $file_list
done

#動画連結
ffmpeg -safe 0 -f concat -i $file_list -c copy $output

使用方法

$./cbdr.sh {元ファイル格納ディレクトリ} {出力ファイル名}

例)

$./cbdr.sh input combined.mov

まとめ

いかがだったでしょうか。ユピテルのドラレコ2製品(DRY-ST7000,5000)で確認しましたが、上記の方法を使えば再生中の音楽などの途切れも気にならないレベルで撮影映像の連結が可能でした。

アクションカムなどでも同様の問題がある(ファイル分割の都合で映像が途切れる)のでそちらも良い方法がないか調査中です。

コメント