okayurisotto.net

私が好きでやったことが他の人のためにもなったらお得かも!

複数の動画ファイルを一気にAviUtlのタイムラインに並べたかった

公開日:
最終更新日:

私は趣味として音声合成ソフトを使ったゲーム実況動画を制作し、ニコニコ動画やYouTubeに投稿するということをしています。動画編集ソフトとして使っているのは、AviUtlです。AviUtlは長い歴史を持つフリーの動画編集ソフトであり、どうしても前時代的で使いづらいところはあります。しかしPSDToolKitなどの外部ツールが動画編集作業を強力に補助してくれるため、他の動画編集ソフトに移行しようにもできないという悩ましい状況にあります。

個人的にAviUtlを使っている中で最も困らせられることは、動画の読み込みに関する不安定な挙動です。ゲーム実況動画を制作する上で、ゲームを録画した動画ファイルをAviUtlに読み込ませる場面は頻出します。しかしその際、長めの動画ファイルを読み込ませようとするとフリーズしてしまうのです。そのため、動画ファイルをあらかじめ細かく切り分けておくということをせざるを得ないのが現状です。

動画ファイルを細かく切り分けること自体は簡単です。FFmpegのSegment Muxerを使ってもいいですし、録画ソフト(私はOBS Studioを使っています)で一定の長さもしくはファイルサイズになったら保存する動画ファイルを分割するように設定してもよいでしょう。

問題は、その分割して得られた動画ファイル群をAviUtlのタイムライン上に並べていくのがとても面倒であるということです。ファイルエクスプローラーからひとつひとつドラッグアンドドロップし、隙間が空かないように並べていくというのは、動画ファイルが長尺になればなるほど苦痛となります。

そこで私は、それぞれの動画ファイルの長さを読み取り、それに応じたexoファイルを生成するツールを作ることにしました。exoとは、タイムラインに並んだオブジェクト(動画データや音声データなど)をエクスポート・インポートする機能で使われるプレーンテキストベースのファイルフォーマットです。これをプログラムから作ることができれば、動画ひとつひとつをドラッグアンドドロップするのではなく、たった1つのexoファイルをドラッグアンドドロップするだけで一気に、タイムラインに動画を読み込めるようになるはずです。

プログラミング言語としてはRustを選びました。Rustは強力な型システムや所有権の仕組みによる安全なメモリ管理を提供する、システムプログラミングに向いたプログラミング言語として知られるものです。しかし今回の場合は、そういった特徴以上に、単純に「ライブラリ(クレート)が豊富で、なおかつ簡単にインストールできる」というところが魅力的でした。

動画ファイルを読み込み、その長さを取得するために、mp4を使いました。また、exoファイルはSHIFT_JISでエンコードされている必要がありますが、SHIFT_JISとして書き出すために、encoding_rsを使いました。またCLIツールとして使いやすいものにするために、コマンドライン引数パーサーのclapも使いました。

というわけで完成したのが、videos2exoです。Rustは完全に初心者なので、あまりきれいなソースコードにはなっていないと考えられますが、恥ずかしいのを堪えてGitHubにて公開しています。

奇妙なことに、AviUtl上で認識される動画ファイルの長さと、mp4クレートが取得する動画ファイルの長さには数フレームの違いがあることがあるようでしたが、原因は不明です。AviUtl側の実装がどうなっているのかわからない以上、どうしようもないように思えたため、完全に一致させることは諦めました。

とはいえ、実用上は特に問題ありません。動画ファイルを読み込む手間は、期待通り、これまでのO(n)からO(1)になり(?)、とても楽になりました。作ってよかったです。

しかしそれはそれとして、AviUtlには扱いにくいところがあるため、脱AviUtlについては検討を重ねる必要がありそうです。「動画編集 as Code」がしたいです……!