日々精進

新しく学んだことを書き留めていきます

AviSynth - バッチ処理でサムネイル作成

AviSynthで動画のサムネイルを一括作成するスクリプトを作ってみた。


mp4ファイルをAviSynthで処理しようとすると↓のエラーが出て処理できない。

Could not open as video or audio.Video returned: "DirectShowSource: couldn't open file

mp4 with avisynth using directshow [Archive] - Doom9's Forumに、Haali Media Splitterをインストールするとエラーが直ると書いてあったので早速インストール。無事エラーがでなくなりました。Media Splitterというソフトがどんなソフトかよくわかってないんだけど、映像と音声のデータを分離するソフトかな?


最初に書いたスクリプトは↓だったが、これではImageWriterは動画プレイヤーで表示されたフレームしか書き出してくれないのでjpgファイルは全く書き出されない。

DirectShowSource("C:\mp000468.mp4") #ファイル読み込み
Trim(900,900)  #Trimフィルタで900フレーム目のみ取り出す
Crop(40, 0, 640, 480) #両端を切り落として720×480を640×480にする
BilinearResize(160, 120) #160×120にリサイズ
ConvertToRGB() #色をRGBに変更。これをしないとImageWriterで書き出せないため
#再生されたフレームをjpgファイルに書き出す
ImageWriter(file = "C:\Documents and Settings\toru\My Documents\Aptana Studio\MagicCast\public\videos\", type = "jpg") 

DirectShowSource("C:\mp000469.mp4")
Trim(900,900)
Crop(40, 0, 640, 480) #両端を切り落として720×480を640×480にする
BilinearResize(160, 120) #160×120にリサイズ
ConvertToRGB() #色をRGBに変更。これをしないとImageWriterで書き出せないため
#再生されたフレームをjpgファイルに書き出す
ImageWriter(file = "C:\Documents and Settings\toru\My Documents\Aptana Studio\MagicCast\public\videos\", type = "jpg") 
(...以下ファイル数だけ続く)



スクリプトの方は試行錯誤の末、↓のようになった。

#Trimフィルタで900フレーム目のみ取り出し、連結する。 ...以降は動画ファイルの数だけ続ける
Trim(DirectShowSource("C:\mp000468.mp4"),900,900) + Trim(DirectShowSource("C:\mp000469.mp4"),900,900) + ... 

Crop(40, 0, 640, 480) #両端を切り落として720×480を640×480にする
BilinearResize(160, 120) #160×120にリサイズ
ConvertToRGB() #色をRGBに変更。これをしないとImageWriterで書き出せないため
#再生されたフレームをjpgファイルに書き出す
ImageWriter(file = "C:\Documents and Settings\toru\My Documents\Aptana Studio\MagicCast\public\videos\", type = "jpg") 

このスクリプトも問題があって、開いた動画ファイルをすべてメモリ上に展開するのでメモリをものすごく食う。今回処理する動画のサイズや自分の環境では一度に20の動画を処理するのがやっとだったので↓のフローで作業を行った。


1.上記スクリプトで1〜20番目の動画を処理
2.動画プレイヤーで再生(静止画が出力される)
3.ファイル名一括リネームソフトで静止画ファイルをリネーム
4.1番の作業に戻って21番目以降の動画を処理


これを483ファイルにやったのでしんどかった。。
一気にサムネイル作る方法あるのかな。詳しい人いたら是非コメントお願いします。


ついでに再生時間の一覧を出力するスクリプトも作ってみた。

DirectShowSource(" & """" & "C:\videos\mp000001.mp4" & """" & ") #ファイル読み込み
#再生時間を計算して少数以下切り捨ててlog.logに出力
WriteFileStart(" & """" & "C:\videos\log.log" & """" & ", append = true, String(int(FrameCount() / FrameRate())))

DirectShowSource(" & """" & "C:\videos\mp000002.mp4" & """" & ") #ファイル読み込み
#再生時間を計算して少数以下切り捨ててlog.logに出力
WriteFileStart(" & """" & "C:\videos\log.log" & """" & ", append = true, String(int(FrameCount() / FrameRate())))
...(以下ファイルの数だけ続ける)

こちらはWriteFileStartが動画ファイルを読み込んだ時に文字列を書き出してくれるので
動画を一つずつ処理できる。そのため何個でも一気に動画ファイルを処理できる。