代理ちゃん日誌

キホン自分用

フレーム補間おぼえがき

テレビアニメのOP映像(TS)を音声無劣化でフレーム補間し、H.264のmp4にするという方針を例にあげてやってみます。
自分用のメモですがお役に立てれば幸いです。
注:この記事はすこし重たいです。

全体的な流れ

切り出し → 音声分離 → 音声読込・位置調整 → インタレ解除 → ノイズ・ロゴ除去 → 中間ファイル → フレーム補間 → エンコード → 動画ファイル完成!

前提として、TS抜き録画が出来る環境があることを想定して書いております。
蛇足になりますが、自分の環境はWin7+TVTest+TvRockで、PX-W3U3(v2じゃないほう)で復調しています。
PCでテレビを視聴したり録画したりすることに詳しくない方は以下のブログ様などを参照されると良いかもしれません。
せっかくの自作PCなのでPT3とか差そうかなと思った矢先に生産終了で悲しい。

また、AviUtlのインストールと、TSやaacが読み込める入力プラグインの導入や、x264GUIEx(1.46以降)の導入も済ませてあることを前提としております。

切り出し

アニメ1話分はTSの容量にして地上波だと3GB~4GB、BSだとさらに+1GBくらいです。このままですと死ぬほど扱いづらいのでOP(またはED)だけ切り出します(放送波にもよりますが200MBくらいになる)。
切り出しにはMurdocCutterというソフトがいい感じです。
使い方も直感的ですので書く程でもないですが、こちらのサイトとかに詳しく載っています。
だいたいOPの頭とケツに少し余裕を持たせて切り出すと良いと思います。最終的なエンコードのときに、AviUtlでこのマージン分を除いた部分をフレーム選択してエンコードしてあげればOKです。

音声分離

BonTsDemux(リンク先up1091)」というソフトがいい感じです。
こちらも使い方は直感的ですので書く程でもないです。が、下記のサイトに詳しく載っています。
TSを読み込んだら、エンコード方式は「Demux(aac)」にして、音声だけ分離しましょう(wavでは音声無劣化でエンコまで行けません)。
このソフトで変換したらTSファイルの音声部がなくなるとかそういうことはありません。抽出という表現の方が適当かもしれません。
「音声遅延補正」はややこしいので自分は「0」で変換しています。けっきょくAviUtlで調整します。

音声読込・位置調整

そもそも「FakeAacWav(FAW)」というツールがあり、これはaac音声を「擬似的なWAV」に変換するツールで、変換後は耳がおかしくなるような音声ファイルが出来ます。
これを、wav形式を扱える編集ソフトで編集するなどして、FAWで再びaac音声に戻したのちそのまま映像とmuxすれば、音声部分が無劣化になるといった具合です。
このFAWについて、AviUtl向けにプラグインに「AACをFAWとして読み込むプラグイン」というものがあり、今回はこれを用いて、先ほど変換したaacをAviUtl側でFAWとして読み込み、x264guiExのエンコード時に音声を「FAW2aac」というプラグインを用い、aacとしてmuxします。
その前に、先ほど変換したaacをふつうに読み込み、音声の位置を調整してディレイ秒数をメモでもしておくという作業を行う必要があります。
まず上記プラグイン(aacfaw.aui、FAW2aac.auo)を導入後、AviUtlを起動し「ファイル」→「環境設定」→「入力プラグインの優先度」を開きます。ここでaac入力に使う入力プラグインが「AACをFAWとして読み込むプラグイン」より上の優先度になっていることを確認します。なっていなければ優先度を設定して閉じます。

f:id:heikin2525:20160512205754p:plain

その後、TSを開き、「ファイル」→「音声読み込み」で先ほど変換したaacを開きます。
何もしていない状態だと再生ウィンドウで確認しても音ズレしていると思われますので、「設定」→「音声の位置調整の設定」を開き、調整します。
このとき、読み込んだaacのファイル名に注目します。BonTsDemuxから出力されたaacには、ファイル名の末尾に「DELAY -299ms」などの文字列が付加されています。この値を正負逆にした値を参考にAviUtl側で調整するとだいたいうまいこといきます。
f:id:heikin2525:20160512211913p:plain
ファイル名を参考に合わせていく

24fps->60fpsで補完する時はこの値(もしくはこれを2.5倍した値)で合わせるとうまいこといくので、この時点でメモしておきます。
ここでもしファイル名にあるミリ秒で調整しても音がずれている場合は、手動で確認して音ズレをなくしておきます。
ファイル名にあるミリ秒表記があてになる時と、全くあてにならない時があるので、不安な方は拡張編集で音声ファイルを左右chに振ってチェックしてみたり、一度数秒分をaviなどで書き出してみて拡張編集でディレイ秒数を調べてみるのも良いかもしれません。
f:id:heikin2525:20160514012100p:plain
tsとaacの音声を左右に振って確かめるなど

インタレ解除

アニメのエンコードといえばインターレースの解除が重要です。
とはいえ、AviUtlにそもそも入っているインタレ解除機能で充分キレイになるので、そこまで難しくないと思います。素材や好みによって外部のプラグインを入れるのも良しです。
AviUtl本体で解除する場合は、まず「設定」→「インターレースの解除」から、「自動24fps」を選択します。このとき、「自動24fpsの設定」も確認し、「横縞部分を二重化」のチェックは外しておきます。加えて、「設定」→「フレームレートの変更」から、「24fps <- 30fps (4/5)」を選択します。このとき、「24fps <- 30fpsの間引きには自動24fpsの処理を使う」のチェックを入れておきます。
外部のプラグインで解除する場合は、「自動フィールドシフト」とかが良いと思います。使い方は頑張ってください。

ノイズ・ロゴ除去

インタレ解除をしたら、おこのみでノイズ除去やロゴ(ウォーターマーク)の除去を行います。
ノイズの除去においても、AviUtlにそもそも入っている「ノイズ除去フィルタ」で充分だと思いますが、キツくノイズの除去を行いたい場合は「NL-Means」系などが良いと思います。また、ノイズが除去できたのか確認するのに「ノイズ表示フィルタ」なども有効だと思います。
また、ロゴの除去においては「透過性ロゴプラグイン」が良いと思います。(こういうのもあるそうです)

f:id:heikin2525:20160513232244p:plain
けっこうキレイに消える

中間ファイル生成

以上まで終われば、一度aviなどの無劣化な中間ファイルに落とし込みましょう。
蛇足かもしれませんが、aviのコーデックは「未圧縮」でやるとファイルサイズがものすごいことになりますので、UtVideohuffyuvが良いと思います。
すべて閉じる前に、「ファイル」→「環境設定」→「入力プラグインの優先度」で、「AACをFAWとして読み込むプラグイン」が、aacを読み込める他の入力プラグインより上の優先度になっていることを確認します。なってなければ優先度を設定してから閉じます。

f:id:heikin2525:20160513222159p:plain

フレーム補間

AviSynthの導入

AviSynthとは?については長くなるのでこちらとかがわかりやすいです。
この記事においては、素材を読み込んでフレーム補間したデータをAviUtlに渡すまでがAviSynthとそのプラグインの役割といったところです。
ひとくちにAviSynthといっても色んなビルドやらバージョンやら種類がありますが、AviSynth+をインストールしておけばいいんじゃないかと思います。
AviSynth単体でもいろいろフィルタを掛けることはできますが、フレーム補間については外部プラグインを用いたやり方が一般的です。
その前に、動画をAviSynthに読み込ませるためのプラグインを入れておかないといけません。だいたいの動画はAviSynth側の「DirectShowSource」を使えば開けますが、TSなどはうまくいかなかったりするので、「L-SMASH Works」に同梱されているAviSynth向けのプラグイン「LSMASHSource」を導入しておきます。ダウンロードした上で「LSMASHSource.dll」をAviSynthをインストールしたフォルダの「plugins」フォルダにほりこみます。
中間ファイルにaviを使用した場合AVIsourceでも良さそうに思えます。それで大丈夫なら良いですが、私の環境ではファイルサイズがデカくなるとエラーを吐いてくるので、いつもL-SMASHでやっています。

SVPを使う

SVPとは「SmoothVideo Project」の略で、なんかMPCとかを使って再生しながらフレーム補間して視聴できるソフトだそうです。
ローカルで再生するだけならそれでも十分ですが、死ぬほど重いのでそれ相応のスペックが要求されますし、PCでしかぬるぬるできなかったりするので個人的には微妙ですが、実力は十分とのことです。
そのSVPの核となるフレーム補間部については、AviSynth向けに「https://www.svp-team.com/wiki/Download#libs」というプラグインが用意されており、今回はそれを利用します。
まずSVPのメインHPからSVP本体をDL・インストールします。
(デフォルトのインストール設定の場合、一緒にMPC-HCとかffdshowもインストールされそうになるので、必要ない場合はチェックを外しておきましょう。)
ダウンロードしたファイルのうち、「svpflow1.dll」「svpflow2.dll」をAviSynthの「plugins」にほりこみます。
その後、AviSynthスクリプトを書きます。以下をメモ帳などにコピペして、環境に合わせて適当にいじって、拡張子を「.avs」とし保存します。#はコメント行です。

SetMemoryMax(1024) #環境に合わせてよき数字に
LoadPlugin("C:\Program Files (x86)\AviSynth+\plugins+\svpflow1.dll")
LoadPlugin("C:\Program Files (x86)\AviSynth+\plugins+\svpflow2.dll")
threads=12  #Corei7とかの場合。環境に合わせてよき数字に
LWLibavVideoSource("TEST.avi", audio=false).converttoYV12
#フレーム補完したい中間ファイルのパスを記入。フルパスのほうが良いと思います。
super=SVSuper("{gpu:1}")
vectors=SVAnalyse(super, "{ block:{w:32}, main:{satd:true, coarse:{width:1920, trymany:true}}, refine:[{thsad:1000}] }")
SVSmoothFps(super, vectors, "{ rate:{num:5,den:2}, algo:23, cubic:1 }", url="www.svp-team.com", mt=threads)
#目標フレームレートはSVSmoothFps内の「rate:{num:x,den:y}」の箇所で決まる。
#目標フレームレート = ソースのフレームレート * num / den

このavsを「プログラムから開く」でAviUtlを指定して開き、黒地に赤文字のエラーが出なければ成功。もし出た場合、最下行のavsフルパスの後の「line *」がエラー箇所の行数となるので、そこを修正します。
パラメータなどをこだわりたい人はSVPのwikiに詳しく書いてあるので(英語)、こちらが参考になると思います。

もしも、「オレは中間ファイルなんて面倒なことはしたくない!!直接TSをフレーム補間してやる!!」という破天荒な方は、以下のように、AviSynth側でインターレース解除を行ってからフレーム補間の関数に渡す必要があります。また、ノイズ除去やロゴ消しのフィルタも、フレーム補間の後になります。

...
LWLibavVideoSource("TEST.ts", audio=false).converttoYV12
Auto24FPS()
...

MVTools2を使う

何らかの事情で上記のSVPでどーにもこーにもうまくいかない場合は、MVTools2というプラグインもあります。
こちらはSVPが出てくる前によく使われていたフレーム補間のプラグインで、SVPflowの元となったプラグインでもあるそうです。
こちらも上記にリンクしてあるページの下部からダウンロードし、次にwarpsharpパッケージをこちらからOSのビット数に合わせてダウンロードし、同様にAviSynthをインストールしたフォルダの「plugins」フォルダにほりこみます。
その後、AviSynthスクリプトを書きます。以下をメモ帳などにコピペして、環境に合わせて適当にいじって、拡張子を「.avs」とし保存します。#はコメント行です。

LWLibavVideoSource("TEST.avi", audio=false).converttoYV12
#フレーム補間したい中間ファイルのパスを記入。フルパスのほうが良いと思います。
super=MSuper(pel=4, hpad=0, vpad=0, rfilter=4)
backward_vectors = MAnalyse(super, isb = true,search=3,delta=1)
forward_vectors = MAnalyse(super, isb = false,search=3,delta=1)
super=MSuper()
backward_1 = MAnalyse(super, chroma=false, isb=true, blksize=32, blksizev=16, searchparam=4, plevel=1, search=3, overlap=8, badrange=(-24))
forward_1 = MAnalyse(super, chroma=false, isb=false, blksize=32, blksizev=16, searchparam=4, plevel=1, search=3, overlap=8, badrange=(-24))
backward_2 = MRecalculate(super, chroma=false, backward_1, blksize=32, blksizev=16, searchparam=4, search=3, overlap=8)
forward_2 = MRecalculate(super, chroma=false, forward_1, blksize=32, blksizev=16, searchparam=4, search=3, overlap=8)
backward_3 = MRecalculate(super, chroma=false, backward_2, blksize=16, blksizev=16, searchparam=4, search=3, overlap=8)
forward_3 = MRecalculate(super, chroma=false, forward_2, blksize=16, blksizev=16, searchparam=4, search=3, overlap=8)
backward_4 = MRecalculate(super, chroma=false, backward_3, blksize=16, blksizev=16, searchparam=3, search=3, overlap=8)
forward_4 = MRecalculate(super, chroma=false, forward_3, blksize=16, blksizev=16, searchparam=3, search=3, overlap=8)
backward_5 = MRecalculate(super, chroma=false, backward_4, blksize=16, blksizev=8, searchparam=3, search=3, overlap=2)
forward_5 = MRecalculate(super, chroma=false, forward_4, blksize=16, blksizev=8, searchparam=3, search=3, overlap=2)
backward_6 = MRecalculate(super, chroma=false, backward_5, blksize=8, blksizev=8, searchparam=3, search=3, overlap=2)
forward_6 = MRecalculate(super, chroma=false, forward_5, blksize=8, blksizev=8, searchparam=3, search=3, overlap=2)
backward_7 = MRecalculate(super, chroma=false, backward_6, blksize=8, blksizev=4, searchparam=2, search=3, overlap=int(2/4)*2)
forward_7 = MRecalculate(super, chroma=false, forward_6, blksize=8, blksizev=4, searchparam=2, search=3, overlap=int(2/4)*2)
backward_8 = MRecalculate(super, chroma=false, backward_7, blksize=4, blksizev=4, searchparam=2, search=3, overlap=int(2/4)*2)
forward_8 = MRecalculate(super, chroma=false, forward_7, blksize=4, blksizev=4, searchparam=2, search=3, overlap=int(2/4)*2)
MFlowFps(super, backward_8, forward_8, num=60, den=1, blend=true)
#目標フレームレートはMFlowFps内の「num=x, den=y」の箇所で決まる。
#目標フレームレート = num / den

このavsを「プログラムから開く」でAviUtlを指定して開き、黒地に赤文字のエラーが出なければ成功。もし出た場合、最下行のavsフルパスの後の「line *」がエラー箇所の行数となるので、そこをデバッグします。
MVTools2では、SVPに比べ日本語で解説されているサイトが多くあります。上記のパラメータをいじる際はこちら(英語)こちら(日本語)などが参考になると思います。

音声mux

無事にAviUtlにフレーム補間された映像が読み込めたら、音声とmuxします。
「ファイル」→「音声読み込み」より、BonTsDemuxで変換したaacを読み込ませます。そして、「設定」→「音声の位置調整の設定」を開き、「音声読込・位置調整」でメモした分だけ音声を調整します。
ここでプレビューしようとしても、aacはFAWとなって読み込まれているはずなので、耳がおかしくなるような音声しか聞こえてきません。

エンコ

最後にOPの最初のフレーム~おわりのフレームまでを選択すれば、あとはエンコードするのみです。
FAWで音声をaacにする関係で、x264GUIEx(1.46以降)を使用する必要がありますので、導入されていない方は、現在のAviUtlの状態を「ファイル」→「編集プロジェクトの保存」などして保留しておき、頑張って導入してください。
エンコードの設定は、60fpsの動画であるという前提でてきとうに設定していただければいいと思いますが、右側「音声」タブの「FAWCheck」にチェックが入っていること、また「FAW2aacプラグインが導入済であるかに注意が必要です。

f:id:heikin2525:20160514002805p:plain

おまけ(サンプル)

上3つはロゴ消ししてNL-Meansかけてます。音声無劣化です。
最後のは、公式Youtubeをフレーム補間して、AviUtl付属のノイズ除去フィルタかけた以外は特に何もしてません。音声もソースをそのままqaacです。
ブラウザじゃムリおもたいって人は直リンクからローカルに保存してどうぞ。


激しい動きが多いのでちょっとキツイかな…。
途中のPAN3連発のカットでわかるくらいかなといったかんじ。


こっちもキツイ。
でもまだちょっとマシかも。


EDは大抵の作品で止メ画PANとかが多いので、わかりやすいけど面白くはない。
この作品はだいぶ気合入ってる方でサビからよく動いてますね。


えろげOPのようなモーショングラフィックス映像は補完するとほんとにすごいです。



以上です。では、良きぬるぬるライフを!