TMPGEnc Video Mastering Works 5でVC-1の映像を読み込む方法(無理やり)

以前も少し記載したかもしれませんが、TMPGEnc Video Mastering Works 5ではVC-1のファイルは読み込めません。正確には読み込めるのですが、映像としては使用できません。ですので、VC-1DTS-HDの場合、そのままの状態ではTMPGEnc5ではまったくつかいものになりません。DTS-HDの音声の場合は、色々細工をすれば読み込めるようになるのですが、VC-1の場合はどうやってもできなかったのですが、いろいろインターネットを検索するとできるようになりましたので、記載したいと思います。
ただし、これは無理やりTMPGEnc5で処理させていますが、この処理の過程でAviUtiを用いるので、その時点でエンコードしてもよいと思います。僕は、TMPGEnc5のバッチ処理とかからみで、TMPGEnc5で処理させているだけのお話になります。

必要なもの

AviUtl
HaaliMediaSplitter
mkvmerge
SupTitle

大手のものは、Googleで検索すれば、おそらく結果に表示されると思います。

手順

映像、音声、字幕を取り出す

tsMuxeRで、映像、音声、字幕を取り出します。対象のファイルをtsMuxeRに放り込んで、
codecがVC-1
codecがDTS-HD or AC3
codecがPGS、langが対象の言語(日本語の場合jpn)
のファイルを選択し、Demuxして適当な場所に書き出します。

VC-1Matroska形式に変換する

先ほどの手順で変換したVC-1の映像を、mkvmergeでmkvファイルに変換します。
mkvmergeを立ち上げて、映像ファイルを放り込み、MUX開始ボタンを押します。

音声を変換する

AC3の場合は、特に必要ありませんが、DTS-HDの場合はAAC等に変換しておいてください。

映像ファイルを作成する

AviSynthを使います。以下のようなavsファイルを準備します。

LoadPlugin("vss.dll")
LoadPlugin("SupTitle.dll")


DSS2("test.mkv").SupTitle("test.sup", forcedOnly=false, swapCbCr=false, relocate=true, relocOffset="")

vss.dllは、HaaliMediaSplitterのインストールが必要です。僕の場合、C:\Program Files (x86)\Haali\MatroskaSplitterにありました。フルパスで記載します。
SupTitle.dllは、ホームページからダウンロードできます。展開して適当に配置して、そのフルパスを記載します。
DSS2で、mkvファイルを指定し、SupTitleに字幕ファイルを指定します。
このファイルを、一度再生させてみて、映像、字幕が表示されるか確認します。ちなみに、音声は再生されません。
赤い文字で、エラーみたいなものが表示された場合は、修正します。大体、dllのパスが違っていたり、ファイルのパスが違っていたりするものが多いと思います。

AviUtl用のプロジェクトを用意する

これは、おそらく僕の環境の問題かもしれませんが、TMPGEnc5に上記で作成したavsファイルを指定しても、TMPGEnc5がフリーズして正常に読み込んでもらえません。これでいったんあきらめていたのですが、AviUtl用のプロジェクトにすると、読み込んでもらえたので、AviUtlを使います。
AviUtlを起動して、avsファイルを放り込んで、編集プロジェクトの保存で、適当な場所に保存します。

TMPGEnc5でエンコード

TMPGEnc5を起動し、aviutlのプロジェクトを指定します。すると、いつもの見慣れた画面が表示されます。
avsには映像のみで、音声はふくまれておりませんので、音声を別途指定します。
あとは、適当にエンコードしてあげます。

その他

結局のところ、AviUtlで読み込めるということは、そのままAviUtlで処理しても問題ないと思います。僕の場合、エンコーディングの処理はすべてTMPGEnc5で行っており、その関係でAviUtlではなくTMPGEnc5を使っているだけの話です。

結びに

前回の本編が複数m2tsに分割された場合、今回のVC-1コーデックの場合、いずれも色々下処理は必要になりますが、TMPGEnc5で処理できるようになりました。
本当にいい時代になったな〜と

分割されたm2tsをひとつのm2tsへ結合する方法

ブルーレイのディスクをリッピングして、エンコードしようと思い本編を確認すると、本編が複数のm2tsに分割されている場合があります。
今回初めてこのケースを体験したわけですが、今までは本編がひとつのm2ts(20GB以上)になっているものしか経験ありませんでした。

ひとつひとつ結合するのは面倒だし、そもそもm2tsのファイル名の順番 = 再生順でもないので、ひとつひとつ再生して再生順を探すのも面倒だなーと思っていたのですが、解決法がありました。

またまた、tsMuxeRの出番です。
ブルーレイのディスクをリッピングすると、PLAYLISTというフォルダがあると思います。
その中に、***.mplsというファイルがあります。たくさんあるので、どれが本物かわからないのですが、割とファイルサイズが大きいものが本物です。ちなみに、バイナリファイルなので、テキストエディタで開いても、よくわからないと思います。バイナリエディタで開くと、m2tsのファイル名が確認できます。

で、手探りになるのですが、ファイルサイズの大きいmplsをtsMuxeRに放り込むと、不思議に解析してくれます。
これを、m2tsにmuxしてあげれば、OKです。
我々が見慣れている巨大m2tsファイルが生成されるので、あとは通常の手順でいろいろできるのではないかと思います。

JUnit4を使ってみました(今さら・・・)

僕が始めて触ったテスト用のフレームワークはJUnit3でした。
テストコードを書く楽しさ、重要性、そしてそのコストとそれに見合うだけの品質を得られるか、当時は夢中でテストを結構書きました。
テストを書けば、もしメインのプログラムに修正が発生した場合、テストコードも修正になる。単純に工数が若干あがります。でも、そのかわり、勇気を振り絞らなくても、public系の関数を修正できたりします。
でも、テストは非常に難しいです。おそらく、メインのプログラムを書くより、テストのプログラムを書くほうが難しいのではないかと思うくらい。


まぁ、話はそれましたが、JUnit3を5年近く使ってきて、今度の手前のプロジェクトで初めてJUnit4を触ってみました。本当に、本当に今さら感が漂いますが、ちょっとだけ比較したいと思います。

テストの記述がアノテーションになったよ

Junit3では、TestCaseというクラスを継承したサブクラスを使って、かつテストする関数名はtestから始まる必要がありました(はず)。Junit4からはアノテーションを記述します。ですので、関数名は自由につけれます。

junit3の場合

public class FileTest extends TestCase{
	public void testファイルが存在するかな() {
		fail();
	}
}

Junit4の場合

import static junit.framework.Assert.*;

public class FileTest
	@Test
	public void ファイルが存在するかな() {
		fail();
	}
}

こんな感じです。まぁ、便利になったと思います。ただ、assert系の関数はあらかじめインポートしておく必要があります。

例外がテストできるようになったよ

こういう書き方をすると、JUnit3が例外のテストができなかった印象をもたれるかもしれませんが、JUnit4では例外を例外のテストすることができるようになりました。
JUnit3の場合

public class FileTest extends TestCase{
	public void testファイルが存在するかな() {
		Hoge hoge = new Hoge();
		try {
			// aruyoはファイルが存在しない場合は、FileNotFoundExceptionを送出する
			hoge.aruyo(new File("hogehoge"));
			fail();
		} catch (FileNotFoundException e) {
			assertTrue(true);
		}
	}
}

Junit4の場合

public class FileTest
	@Test(expected = FileNotFoundException.class)
	public void ファイルが存在するかな() {
		Hoge hoge = new Hoge();
		hoge.aruyo(new File("hogehoge"));
	}
}

僕の場合、こんな感じです。確かに例外のテストはコード量は減りましたね。これは便利です。

テストの前に一度だけ実行機能がついたよ

JUnit3はテスト実行前にしておきたい処理はTestCase#setUp関数をオーバーライドすればよいのですが、これはtest関数が実行されるたびに、setUp関数が呼ばれますので、たとえばテストクラスにtest関数が100個あったら、setUp関数が100回呼ばれます。たとえば、httpのテストをしたくて、テストの際Jettyを立ち上げる場合、setUpに起動、tearDownに終了を記載すると、100回起動・終了が行われ、テスト時間を多く裂いてしまいます。じゃ、手前の環境でjettyなりtomネコなど立ち上げておけばいいじゃん、ボケ。といわれそうですが、テストはどんな環境でもテスト結果が同じことが大事だと思うし、極論を言えば100人がプロジェクトをcheckoutしてプロジェクトルートのTestSuite実行して、環境の違い等でテスト結果に差異がでると、ちょっとテストとしては不完全なのかなーと思うのです(現実的に難しいですが、これを目指そうという心構え)
JUnit4だと、アノテーションで@BeforeClassと@AfterClassを記述することで、テスト実行前の初期化が行えます。
Junit4の場合

import static junit.framework.Assert.

public class FileTest
	
	private static HttpServer server = new HttpServer();

	@Test
	public void 接続できるかな1() {
	}

	@Test
	public void 接続できるかな2() {
	}

	@BeforeClass
	public static void myBeforeClass() throws Exception {
		server.start();
	}

	@AfterClass
	public static void myAfterClass() throws Exception {
		server.stop();
	}
}

こんな感じで、
myBeforeClass()

接続できるかな1()

接続できるかな2()

myAfterClass()
が実行されます。すべてのテストの実行前に、一度しか実行する必要のない処理については、非常に効率的な書き方をできるようになりました。注意としては、BeforeClass、AfterClassについては、staticで記載しなければならないことです。インスタンス変数を参照できないので、ちょっと面倒なことがありました・・・。


余談として書き方として、もっとも変わったと勝手に思っているのが、TestSuiteの書き方です。

@RunWith(Suite.class)
@SuiteClasses({
	HogeTest.class, 
	HogeHogeTest.class,
	HogeHogeHogeTest.class
})
public class HogeTestSuite {
}

こんな感じ。一度じゃ覚えれないかな・・・。
ちなみに、僕が試した感じだと、このHogeTestSuiteにBeforeClass、AfterClassを記述した場合は、指定してあるTestSuiteの実行前、実行後に呼ばれる感じなので、テーブル作ったりとか、消したりとかは、ここでするとよいかもしれませんが。

豆な知識として、もうデファクトスタンダードかもしれませんが、Eclipseを使う場合、QuickJUnitプラグインを使うとテストが非常に楽に実行できます。
// 最近は別の流行とかあるのかな・・・

Operaの話

実は、もう10年来のOperaユーザなのですが、機能的なアップデートが多いせいかわからないですが、バージョンアップを重ねるごとに重く、ちょっと挙動不審なところがあると思います。

livedoor Readerで、キーボードショートカットを使うとかなりの確立で、operaのキーボードショートカットがきかなくなる。
DragonFlyを使うと、たまにOperaが落ちる。(デバッグ等に使用しているわけではなく、誤って起動してしまった)
タブなどの操作レスポンスが落ちた気がする。

まぁ、僕の環境だけかもしれないですが、ちょっとOperaらしさがあんまりなくなってきているな〜と。
FireFoxChromeプラグインで拡張できるのに対して、Operaも拡張できるらしいですが、あんまりメジャーじゃないからかもしれませんが、あんまりないんですよね・・・。
でも、マウスジェスチャーが標準サポートで、きびきび動くので、乗り換えられないですけどね。

DomaでJNDI経由でDataSourceを取得する方法

先日の宿題。

DomaでJNDI経由でDataSourceを取得する方法。
サーブレットコンテナにTomcat、データベースはPostgreSQLを使いました。

取り急ぎ、以下のようなクラスを作ります。

public class JndiDaoConfig extends DomaAbstractConfig {
	
	protected static final DataSource data_source = createDataSource();

	protected static final Dialect dialect = new PostgresDialect();
	
	protected static DataSource createDataSource() {
		try {
			InitialContext context = new InitialContext();
			DataSource ds = (DataSource)context.lookup("java:comp/env/jdbc/名前");
			
			return ds;
		} catch (NamingException e) {
			throw new RuntimeException(e);
		}
	}
	
	@Override
	public DataSource getDataSource() {
		return data_source;
	}

	@Override
	public Dialect getDialect() {
		return dialect;
	}
	
}

これで、TomcatのServer.xmlJDBCの設定を記載すれば、取得できます。
もちろん、JNDIに登録していないと使用できないので、Eclipseから実行すると、DataSourceがnullになり正常に実行できません。
これでは、あんまり面白くないので、Eclipseで実行してもDataSourceを取得できるようにJNDIに登録してあげます。
僕の場合、JNDIUnitTestHelperというライブラリを使います。
これは、設定ファイルにデータベースとかの設定を記載しておくと、JNDIに登録してくれます。
JUnitのTestCaseを使う場合

public class BaseTestCase extends TestCase {
	
	protected void setUp() throws Exception {
		super.setUp();
		
		if(JNDIUnitTestHelper.notInitialized()) 
			JNDIUnitTestHelper.init("target/test-classes/jndi_unit_test_helper.properties");
		
	}
	
}

jndi_unit_test_helper.propertiesの記載方法は、Google先生がおしえてくれると思います。
あとは、BaseTestCaseのサブクラスでテストを記載すれば、DataSourceが取得されデータベース接続が可能となります。

取り急ぎ、動作は確認しましたが、まだ本格的に使えてはいないので、週末にでも個人的なサイトに組み込んでみようと思います。

Domaを使ってみました

ひょんなことから、Java製O/RマッパーのDomaを知ったので、使ってみました。
ちなみに、僕のスペックはO/Rマッパー歴ゼロです。JDBCの低レベルAPIを使って、ごりごりSQLを書く派です。
さすがに、ResultSetとか、Statementとか取得、開放があるものは手前ライブラリで吸収し、あんまり意識しなくてもよいようにしていましたが・・・。

なぜ、O/Rマッパーを今まで使ってこなかったかというと、もちろん食わず嫌い的なところはあるのですが、何よりライブラリ群が膨大になることでした。

既存のO/Rマッパーとの比較はできないのですが、JDBC派として気がついたところを記載していきます。
1)導入ライブラリが本体のjarで簡潔している(大事)
2)Select系のSQLは外部ファイルで記述する(大事)
3)O/Rマッパーの知識がなくても30分くらいで、はじめの一歩を踏み出せる(大事)
まだ、ぜんぜん使いきれていないので、これからもっと使っていきたいと思います。


宿題
TomcatのJNDIを使う場合はどうするのか調べる

Windows7でbluewindを動かす

たぶん、普通に動くと思うんですが、ちょっと設定がうまくできない場合があるんですよね。
僕の場合、Windows XPの場合は、Capslockキーで起動していたのですが、Windows7だとこれがうまく動作しないんですよね・・・。
いろいろ試したところ、なんかよくわからないのですが、互換モードで実行にすれば、Cpaslockで起動できるみたいです。