NSV Split付属の Read Meテキストファイル
NSV Split Ver2.1 (2006/05/08)         mikeo_410@hotmail.com

■作成の動機
ストリーム配信されているNSVファイルを保存しておいて、後で見ようと
思いました。
しかし、「番組ごとに分割されていない」「シークして見られない」
「途中までしか再生できない」といった状態に多々遭遇しました。
だんだん分かって来たのは、NSVファイルにはエラー箇所があって、「プ
レイヤーやエンコーダが異常終了する。」「プレイヤーはビデオ属性
(コーデック、サイズ、fps)が変わると止まってしまう。」と言うこと
です。
そこで、エラー箇所をスキップするプログラムを作ってみました。

■機能の概要
1.NSVファイルを分割します。
 1)任意の箇所を切り出すことができます。
 2)NSVファイル形式のエラー箇所をスキップして出力します。
 3)ビデオの属性(コーデック、サイズ、fps)が変わる場所で
   ファイルを分割します。

2.AVIで出力できます。
  AVI形式で出力することで、Windows Media Player等で再生できます。

3.処理結果の概要やNSVパケットの状態を表示する「DIAG」を付けました。

■対象となるNSVファイル
1.NSVファイルの分割
 1)コマンドライン版のstreamripperが出力するファイルです。
   ファイルの内容は送信元で決まるのか、streamripperが作成する
   のかは知りません。
 2)このプログラムは、NSVファイル形式で決められている「パケット」を
   処理します。パケットに含まれる音声、ビデオのストリームは処理せず
   そのまま出力されます。
 3)分割に際して画像を表示できるのはVP3とVP6のみです。

2.AVIで出力
 1)音声がMP3かAACに限ります。
 2)映像はVP3とVP6が対象になります。

■注意
 1)アニメしか試していません。
 2)AACの音声はPCMに変換して出力します。ファイルサイズが大きくなります。
 3)AAC音声のAVI出力には、AACのデコーダ(libfaad.dll)が必要です。
   libfaad.dllは、FAAD 2.0 projectの一部で、ソースコードで入手できます。
   libfaad.dllをこのプログラムと同じディレクトリに置いてください。
 4)VP6の画像の表示にはVP6のデコーダ(vp6vfw.dll)が必要です。
   「AVIの再生について」を参照ください。vp6_vfw_codec.exeをインストール
   するか、このプログラムと同じディレクトリにvp6vfw.dllを置いてください。
 5)AVIを再生する場合にはコーデックのインストールが必要です。
 6)AVIファイルは、2GB以下のサイズのみに対応します。
 7)VP3の画像表示は自前です。何か足りないようでゴミが表示されますが、出力
   ファイルには無関係なのでご容赦を。
 8)すべて、C#で書きました。.NET Framework Version 2.0のランタイムが必須
   です。

■AVIの再生について
このプログラムの動作には必要ありませんが、作成したAVIをWindows Media
Player等で再生する場合にはDirectShowやVFWに対応したデコーダのインス
トールが必要です。ほとんどのプレーヤーは、VP6、VP3を標準で再生できま
せん。
VP6のデコーダーは、vp6_vfw_codec.exe、vp6_decoder.exeの2種類あり
http://www.on2.com/からダウンロードできます。
VP3は、オープンソースで公式のサイトはないようです。VP3を再生できる
プレイヤーもあります。Matroska pack(ffdshow)でも再生できます。

VFWのデコーダDLLは、MPlayerのコーデック・パッケージの中にもあります。
レジストリに追加をして、vp31vfw.dll、vp6vfw.dllをc:\windows\system32に
コピーすれば使えるらしい。
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Drivers32
[名前] [種類] [データ]
VIDC.VP31 REG_SZ vp31vfw.dll
vidc.VP60 REG_SZ vp6vfw.dll
vidc.VP61 REG_SZ vp6vfw.dll
vidc.VP62 REG_SZ vp6vfw.dll

■処理の詳細
NSVファイルには、音声、ビデオのストリームを含む2種類のパケットが
含まれます。このプログラムは、この2誌種類のパケットのみ取り出し、他
のデータはすべて削除します。
2種類のパケットは、「synchronization frame」、および「nonsync
frame」と呼ばれているようです。「synchronization frame」は文字列"NSVs"で
始まり、コーデックやサイズなどの情報を持っています。
このプログラムは、NSVファイルから長さ情報に従ってパケットを読み込
みます。あるパケットの長さ情報が示す次のパケットの先頭にあたる位置
が、パケットのヘッダでないとき、エラーと見なします。その位置から
「synchronization frame」を検索し、見つかるまでのデータをスキップし
ます。ファイルの終端では、長さに満たないパケットを捨てます。
長さがゼロのパケットも破棄します。
出力ファイルの先頭は、必ず「synchronization frame」でキーフレームに
なるように調整します。
出来上がるファイルは、2種類のパケットのみからなり、複数のファイルを
単純に結合しても有効なはずです。
(streamripperのデフォルトでは、NSVファイルの先頭に比較的大きなサイズの
ID3タグが付いています。この部分はスキップして処理します。)

AVI出力:
出力可能な圧縮方式には制限があります。アニメで良く使われていて、調
べて見たら、性質がなんとか分かったものだけです
映像はVP3かVP6に限ります。これは、キーフレーム(完全な1フレームの
画像)を認識する方法がわかったからです。
音声はMP3かAACです。
画像は、NSVもAVIも1データが1フレームなのでそのままコピーします。
ただし、音声がMP3かAACかでフレーム数を調整しています。

音声がMP3の場合は、音声もそのままコピーします。ただし、MP3の音声
データの演奏時間は、映像の時間よりも短くなっています。これは、NSV
のプレーヤは、パケットごとに音声データが尽きると無音になるように
できているのだろうと推測しています。AVIでは音ズレとなるため、映像
フレームを間引いて調節しています。音ズレを検出すると、遡ってキー
フレームの直前のフレームを削除します。(キーフレームは残す。)

音声がAACの場合は、PCMにデコードして出力します。これは、AACのまま
AVIに入れてみたのですが、再生ができなかったためです。CoreAACなどの
デコーダをインストールしてもたどりつかないようです。

■インストール
インストールはありません。展開してできるEXEを実行してください。適宜
ショートカットを作成するなど工夫してください。

もし、VP6のサムネイル表示が必要ならEXEと同じディレクトリにvp6vfw.dll
を入れてください。vp6_vfw_codec.exeをインストールしている場合は、
そのままで使用できます。(vp6_decoder.exeは、DirectShowフィルタで、
vp6vfw.dllをインストールしないようです。)

■ディレクトリ構成
Readme.txt //このファイル
NsvSplit.exe //プログラム本体
[ja-JP]------NsvSplit.resources.dll //日本語用リソース

■動作環境
WindowsXP
Microsoft .NET Framework Version 2.0 が必要です。

■免責事項、および権利義務
この提供物を利用したことによって生じるいかなる事象にも責任を負うことが
できません。
私はソースコードを私自身が書いたということのみを主張します。ご連絡をい
ただければ、すべてのソースコードを提供します。プログラムの作成や実行に
は、コンパイラ、ランタイム、およびOSといった、他のソフトウエアを必要と
しますが、利用者のそれぞれが有する使用許諾の範囲でご利用ください。私に
は何の権利も影響力もありません。
個人が非営利で利用されることには、当然ながら、何の制限もありません。使
用目的をご連絡いただければ、すべてのソースコードを提供します。

■使い方1
 1.「NSVファイルを開く」で.nsvファイルを開きます。
   開けるのはビデオのコーデックがVP31の場合です。また、VP6xも可能で
   すが、この場合は、vp6vfw.dllが必要です。
 2.リストボックスからフレームを選択します。リストボックスに表示され
   ているのは、1フレームで描画可能なキーフレームのみです。
   「V」ボタンで、開始、または終了位置を記録します。
   開始、終了位置には、最初、それぞれ先頭と最終フレームの番号が入っ
   ています。
 3.開始、終了位置には、それぞれ「<」「>」ボタンがあり前後に移動で
   きます。
 4.「NSV出力」か「AVI出力」ボタンを押して選択部分をファイル名を指定
   して出力します。
   入力ファイルを読みながら出力するので、同じファイルには書き込めま
   せん。
 5.別のファイルを開く前には、「NSVファイルを閉じる」を行ってくださ
   い。この処理は入力ファイルをクローズするのみで、保存などの機能は
   ありません。

■使い方2
 1.NSVを開いていない状態で、「NSVファイルのエラー除去」でNSVファイル
   を開きます。
   この処理は、コーデックに依存しません。NSVパケットをそのまま扱い
   ます。
 2.開かれたNSVファイルのパケットの属性がリストボックスに表示されます。
   例とえば、1つのNSVファイルに30fpsと29.97fpsの番組が入っている場
   合には、2行表示されます。
 3.「保存」ボタンをクリックすると、リストボックス中のチェックされた
   部分を、それぞれ異なるファイルに出力します。
   ファイル名は、ビデオ属性から作った文字列を付加したものになります。
   注)同名のファイルが有る場合は上書きされます。

■履歴
 0.2 最初のリリース
 0.3 1)入力と出力が同じファイルの場合書き込まないように。
    2)ファイルのドロップの場合のディレクトリを、次回のメニューから
      のオープンにも反映させる。
 0.4 1)最初のタブストップをListBoxに
    2)VP6のキーフレーム判定をByte0のMSB offで、かつByte1の下ニブル6に
      変更
    3)「ツール」「NSVファイルのエラー除去」で、おなじ属性の箇所を
     上書きしてしまうのを修正。
 :
 2.0 1)環境が.NET Framework Version 2.0になってしまった。
    2)VP6のキーフレーム判定を変更。[Byte1の下ニブル」をbit1-3の3ビット
     で判定に。
    3)リストボックスに、時間を追加。
    4)メニューをボタンに。
    5)AVI出力機能を追加。(AACはPCMになる)
    6)音も映像も長さがゼロのパケットを捨てていたが、出力対象にした。
     長さゼロの映像も1フレーム時間消費するようだ。
    7)SUBTのあるパケットを正しく認識できていなかったのを修正。
    8)Videoの長さがゼロなのに、続く1バイトを読んでキーフレームの判断を
     していた。
    9)試行錯誤を繰り返したがAAC音声の出力は素朴な方法(一時ファイルや
     先頭の映像ディレイをしない方法)に戻した。
  10)FAAD2のfaacDecSetConfiguration()は、引数のfaacDecConfigurationの
    内容の一部しか設定しないことが分かった。アドレスに直接代入。
 2.1 1)アーカイブを作り損ねていた。(ZIPの中にさらにZIPが)
    2)NSVファイル読み込みの進捗表示をモードレスにしたが、メインフォーム
     のXが押せる。押すと内容のないダイアログが表示されるのを修正。
    3)SUBTのあるパケットのSUB読み飛ばしに失敗していた。
    4)NSVの出力の最終位置が正しくなかった。
    5)DIAGボタンを付けて、処理結果レポートとパケットのダンプができるように
     した。