2010年10月16日土曜日

SCx264 to Bookmarks for AvsP

またまたAvsPマクロネタ。

さて、AviSynthのプラグインにはいろいろと毛色の変わったものがありますが、そんな中にSClavcSCXvidというものがあります。
オリジナルのSClavcはx264のペンギン様ことLoren Merritt氏作、SCXvidの作者は#darkholdのいかつい人、MyrsloikことFredrik Mellbin氏であります。(以前一度、JEEB氏に写真を見せてもらったことがあるのですが、Myrsloik氏はやたら人相の怖い太っちょでした。一方、一緒に写ってたTheFluff氏は小柄で柔和そうな感じで、普段の言動から受ける印象とあまりにも違いすぎるので、思わず大笑いしたものです)

で、これらが何のためにあるかというと、要するにffmpegやXvidの2pass用のログを利用して、クリップ内のシーンチェンジの場所とかを割り出して色々利用しようというものらしい。
なんで「らしい」かといえば、使い方がよくわからないから。
とりあえずavs書いてVirtualDubに食わせて"Run Video Analysis pass"を走らせるなりすれば、2pass用のlogファイルが作られるわけですが、そこから先がどうしたものやら…。
AviSynth.infoによれば、「元々は、Yattaにおいて、libavcodecのシーンチェンジ・メトリクスの利用を可能するために書かれた。」とありますが、Yattaってねぇ…あれの使い方がわかる日本人なんているのかしら?
7月ごろにJEEB氏に「#yattaでmenter氏が初心者講習会を開くので来ないか?」と誘われたのでROMってみましたが、何をしゃべってるのかさっぱりわかりませんでした。(そもそも知りたかったのは理論やテクニックではなく、操作方法そのものなのですが、そこらへんはやってくれなかったし…orz)

まあ、Yattaの使い方は今もさっぱりわかりませんが、2pass用logからシーンチェンジ検出というのは理解できます。
そこでふと思ったことが「それならx264のlogファイル使ったほうがよくね? lavcのmpeg4やXvidよりもlog出力速いじゃん」。
で、こんなのを書いてみた。
#SCx264 to bookmarks.py
frames = avsp.GetVideoFramecount()
logfilename = avsp.GetFilename(title='Select x264_logfile')

if logfilename:
    logfile = open(logfilename)
    logs = logfile.readlines()
    logfile.close()
    if len(logs) == frames + 1:
        bookmarks = []
        for logline in logs:
            log = logline.split(' ')
            if log[2] == 'type:I':
                bmpoint = int(log[0].lstrip('in:'))
                bookmarks.append(bmpoint)
        avsp.SetBookmark(bookmarks)
    else:
        avsp.MsgBox('This log is not corresponding to the number of frames of current clip.',title='Warning')

あらかじめx264.exeで --pass 1 をつけてエンコしたlogから、IDRフレームと判定されたフレームにブックマークを自動で打つマクロである。(またブックマークか…)
とりあえずシーンチェンジを検出して、ちゃんとIDRと判定されるようなオプションにしていれば、ほぼ100%検出できるはずである。

さて、ただlog読んでブックマーク打つだけでは面白くないので、さらに発展させてみる。
#SCx264 to bookmarks AUTO.py
import os
avsname = avsp.SaveScript()
#使用するx264.exeを毎回指定したい場合はこちら
#exe = avsp.GetFilename(title = 'Specify x264.exe used.')
#x264.exeのパスを固定したい場合は、こちらにフルパスで書いておく
exe = r'G:\Enctools\x264_x86.exe'

if avsname and exe:
    x264opt = '--preset ultrafast --crf 30 -p 1 -I infinite -i 1'
    thresh = '--scenecut 50'
    logfilename = avsname + '.sc_log'
    os.system('%s %s %s %s --stats %s -o nul' % (exe, avsname, x264opt, thresh, logfilename))

    logfile = open(logfilename)
    logs = logfile.readlines()
    logfile.close()
    bookmarks = []
    for logline in logs:
        log = logline.split(' ')
        if log[2] == 'type:I':
            bmpoint = int(log[0].lstrip('in:'))
            bookmarks.append(bmpoint)
    avsp.SetBookmark(bookmarks)

log出力も一緒にやるようにしてみた。

ううむ、これをどう使えばいいのだろうか?

例えばMPEG2Source("hogehoge.d2v")だけのavsの状態でこれを実行するとCMカットは楽になる。
なぜって、ただブックマーク移動していくだけで本編とCMの切れ目を確実にシークできるから。
AvsP初期装備のTrimEditorと併用すれば、ほとんどストレスなくCMカットできるはず(ただし、TrimEditorでTrimを実行する際は、ブックマークをすべてクリアしてからにすること。これを忘れるとプレビューの更新で随分時間を食うことになります)。
x264は--preset ultrafastならものすごく高速です。自分のそろそろ時代遅れなQ9450でも、1440x1080
のMPEG2-TSを90fps~100fpsで処理します。つーかMPEG2Sourceがボトルネックになっているので、本当はもっと速いです。2本同時にlog出力したりするといいかもしれません。

なお、「30分のTSだとlog出力だけで10分かかるじゃねえか、それだけあればCMカットなんか終わってるよ」とかいう意見は無視します…orz

0 件のコメント:

コメントを投稿