AviUtlで複数の動画を結合したexoファイルを自動で作成する

アプリ
スポンサーリンク

こん○○は、よふかしわーくすの、よふかしさんです。

今回は複数の動画を自動で結合したexoファイルを生成する
プログラムを作る過程の解説をしたいと思います

多数の動画を効率的に連結したい、といった方に向けた記事になります

スポンサーリンク

このプログラムを作るに至った背景

以前、ドラレコの動画からGPSデータを抜き出してAviUtlで動画合成するという記事を書きました

第一回目の記事はこちら

第二回目の記事はこちら

ドラレコだと60s毎に区切られたmovファイルに対して
例えば8H分連結したい、といったことがあるんですよね
AviUtlの拡張編集画面に、動画ファイルを1つずつD&Dしていくと…

・1file/min * 60min * 8H = 480files

ということで、480回ものD&Dを実施しなければなりません…
しかも単純にD&Dするだけではなく、
ひとつ前の動画ファイルの直後に結合されるように位置合わせもあるので
それはもはや人間が実施する所業ではないわけです…

ドラレコ以外にも監視カメラや、何回かに分けて撮影した動画の場合も
まずはたたき台としてひとつに連結したexoファイルが欲しい場合があると思います

上記の第二回目の記事で触れたんですが
この作業の結果となる、拡張編集(exedit)のオブジェクトファイル(exo)を
プログラムで自動で作ってみていたので、その記録を残しておきます

exoファイルの中身を覗き見

15fpsでざっくり60s程度毎に撮影された、test1.mp4、test2.mp4、test3.mp4を題材にしてみます
まずは手動で3つのファイルを拡張編集にD&D、exoをエクスポートしてみます

出来上がったexoファイルを眺めてみます

[exedit]
width=1920
height=1080
rate=15
scale=1
length=3000
audio_rate=48000
audio_ch=2
[0]
start=1
end=1000
layer=1
group=1
overlay=1
camera=0
[0.0]
_name=動画ファイル
再生位置=1
再生速度=100.0
ループ再生=0
アルファチャンネルを読み込む=0
file=C:\temp\test_folder\test1.mp4
[0.1]
_name=標準描画
X=0.0
Y=0.0
Z=0.0
拡大率=100.00
透明度=0.0
回転=0.00
blend=0
[1]
start=1001
end=2000
layer=1
group=2
overlay=1
camera=0
[1.0]
_name=動画ファイル
再生位置=1
再生速度=100.0
ループ再生=0
アルファチャンネルを読み込む=0
file=C:\temp\test_folder\test2.mp4
[1.1]
_name=標準描画
X=0.0
Y=0.0
Z=0.0
拡大率=100.00
透明度=0.0
回転=0.00
blend=0
[2]
start=2001
end=3000
layer=1
group=3
overlay=1
camera=0
[2.0]
_name=動画ファイル
再生位置=1
再生速度=100.0
ループ再生=0
アルファチャンネルを読み込む=0
file=C:\temp\test_folder\test3.mp4
[2.1]
_name=標準描画
X=0.0
Y=0.0
Z=0.0
拡大率=100.00
透明度=0.0
回転=0.00
blend=0
[3]
start=1
end=1000
layer=2
group=1
overlay=1
audio=1
[3.0]
_name=音声ファイル
再生位置=0.00
再生速度=100.0
ループ再生=0
動画ファイルと連携=1
file=C:\temp\test_folder\test1.mp4
[3.1]
_name=標準再生
音量=100.0
左右=0.0
[4]
start=1001
end=2000
layer=2
group=2
overlay=1
audio=1
[4.0]
_name=音声ファイル
再生位置=0.00
再生速度=100.0
ループ再生=0
動画ファイルと連携=1
file=
[4.1]
_name=標準再生
音量=100.0
左右=0.0
[5]
start=2001
end=3000
layer=2
group=3
overlay=1
audio=1
[5.0]
_name=音声ファイル
再生位置=0.00
再生速度=100.0
ループ再生=0
動画ファイルと連携=1
file=
[5.1]
_name=標準再生
音量=100.0
左右=0.0

これをベースに解析していきます

exoファイルの構造を理解する

[]で括られた部分がタグ的に機能していることがわかるので、順にみていきます
便宜的に//でのコメントにて解説を入れていきます
まずは、ヘッダ的な役割の[exedit]部です

[exedit]
width=1920			// 動画の幅
height=1080			// 動画の高さ
rate=15				// 動画のfpsの分子
scale=1				// 動画のfpsの分母
length=3000			// 全ての動画のフレーム数の合計
audio_rate=48000	// 音声のサンプリングレート
audio_ch=2			// 2:ステレオ

最初にD&Dした動画/音声の情報が主です
lengthだけは、3つの動画の合計値になってます

次に動画部の[0]、[0.0]、[0.1]を見ていきます

[0]
start=1				// 1つ目の動画の開始フレーム
end=1000			// 1つ目の動画の終了フレーム
layer=1				// 一旦無視
group=1				// 一旦無視
overlay=1			// 一旦無視
camera=0			// 一旦無視
[0.0]
_name=動画ファイル	// 一旦無視
再生位置=1			// 一旦無視
再生速度=100.0		// 一旦無視
ループ再生=0			// 一旦無視
アルファチャンネルを読み込む=0		// 一旦無視
file=C:\temp\test_folder\test1.mp4	// 動画の絶対パス
[0.1]
_name=標準描画		// 一旦無視
X=0.0				// 一旦無視
Y=0.0				// 一旦無視
Z=0.0				// 一旦無視
拡大率=100.00		// 一旦無視
透明度=0.0			// 一旦無視
回転=0.00			// 一旦無視
blend=0				// 一旦無視

startとendは動画ファイルのフレーム数に応じて適切に可変する必要があります
ちょっと省略しますが、2つ目の動画の[1]部を見ると下記になってます

[1]
start=1001
end=2000

なので、次の動画のstartには、ひとつ前のend+1を入れてあげて
endにはstart+frame数、を入れてあげればよいことがわかります
あと、fileには動画の絶対パスを入れてあげます
それ以外については、大体名称で何を示すかはわかると思いますが
動画結合の目的からすると、D&Dのデフォルトを固定値として無視することにします

次は音声部です

[3]
start=1				// 1つ目の音声の開始フレーム
end=1000			// 1つ目の音声の終了フレーム
layer=2				// 一旦無視
group=1				// 一旦無視
overlay=1			// 一旦無視
audio=1				// 一旦無視
[3.0]
_name=音声ファイル	// 一旦無視
再生位置=0.00		// 一旦無視
再生速度=100.0		// 一旦無視
ループ再生=0			// 一旦無視
動画ファイルと連携=1	// 一旦無視
file=C:\temp\test_folder\test1.mp4	// 動画の絶対パス
[3.1]
_name=標準再生		// 一旦無視
音量=100.0			// 一旦無視
左右=0.0			// 一旦無視

0~2が3つの動画情報だったので
動画ファイルの終点からインクリメントされる3~5が音声情報になっています
動画と同様に、start、end、fileだけ可変してあげれば問題なさそうです

ということで、exoファイルを自作するための情報は揃いました

動画/音声の固有情報の取得方法

まとめると、動画ファイルから下記の情報を取得する必要があります

・動画の幅
・動画の高さ
・動画のfpsの分子
・動画のfpsの分母
・動画のフレーム数
・音声のサンプリングレート
・動画の絶対パス

今回はPythonで自動生成スクリプトを組んでいきたいので

動画情報はopencv-python
音声情報はpydub

を使用して取得していきます
コードについては触りの部分だけ解説します

pip install opencv-python
pip install pydub

importして…

import cv2
from pydub.utils import mediainfo

こんな感じで動画、音声情報がゲットできます

video = cv2.VideoCapture(video_file)
audio = mediainfo(video_file)

Pythonコードではこんな感じで取得できます

# 動画の幅
int(video.get(cv2.CAP_PROP_FRAME_WIDTH))

# 動画の高さ
int(video.get(cv2.CAP_PROP_FRAME_WIDTH))

# 動画のfps
float(video.get(cv2.CAP_PROP_FPS))

# 動画のフレーム数
int(video.get(cv2.CAP_PROP_FRAME_COUNT))

# 音声のサンプリングレート
int(audio.get('sample_rate'))

ここで、問題はfpsです
よふかしさんが使用しているドラレコはLED信号機対策で公称では29.1fpsになってます
これを手動でexoファイルを作成すると…

rate=90000
scale=3103

こうなるんですね…
計算すると公称とも異なる、29.00418949…fps…、あれ??
そしてこの分母と分子の値になる様に計算する実施する部分だけ、ちょっと工夫が必要な点です…

あともうちょっとだけ注意点があります

・ファイルエンコーディングはShift-JISで保存すること
・改行コードはCRLFとすること

うん、流石国産ツールなのでそうですよね

動画を結合してexoにするツールを作ってみた

いくつかのカメラで撮影した、フレーム調やfps違いで自身の環境ではうまく動作しているので
exeとして公開します

Downloadは下記からお願いします

不具合報告、要望は下記からお願いします。。。

公開日時:2025/02/24 17:54:04

コメント

タイトルとURLをコピーしました