2011年11月25日

DVDデータ変換

DVDからAVI形式ファイルの変換をやってみます。

手順としては
1.DVD Decrypterダウンロード&インストール

2.BatchDOO!ダウンロード&インストール

3.DVD DecrypterでFileモードで取り込み

4.BatchDOO!でVOBをaviに変換

って感じです。
では、順番にいきましょう。

1.DVD Decrypterダウンロード&インストール

以下のサイトにアクセスして、ダウンロード〜インストールまで
済ませて下さい。
DVD Decrtpterダウンロード&インストール

日本語化のやり方も載ってますが、別に英語でも問題ないかと思います。
この手順ではメンドクサイから英語版の前提で説明します。
その場合、上記リンク先サイトの「ステップ2」までやっといてください。
もしzipの解凍ツールがない場合はここからどうぞ。

2.BatchDOO!ダウンロード&インストール

以下のサイトからダウンロードしてください。
BatchDOO!ダウンロード

上記の[Download]ボタンをクリックしてダウンロードします。
「BatchDOO.zip」というファイルが取得できたはずです。
それを解凍した中にある[BATCHDOO.exe]が起動ファイルです。
起動するときはこれをダブルクリックします。 これは後で使います。
初回起動時に提供元の要らないソフトインストールを促されるので、チェックをはずしてから
OKを押しましょう。不要なものが勝手にインストールされるのでうっとおしいです。

3.DVD DecrypterでFileモードで取り込み
ドライブに変換したいDVDをセットしたら、DVD Decrypterを起動します。
メニューから[Mode]-[File]を選択します。

続いて、[Destination]をクリックし、ファイルの出力先を決めます。
ちなみに沢山ファイルが出力されるので、デスクトップとかにフォルダを作成して、
そこを指定したほうがいいです。ここでは
デスクトップ\DVD_DATA
を出力先に設定しました。

こんな感じになると思います。

DVD_conv1

したらば、下側にある絵の箇所をクリックして、取り込みを開始します。
すると、以下のように処理が始まるのでしばし待ちます。
ちなみに、完了したときに音楽が鳴るので音量を大きくしているとびっくりしますので注意(笑)

DVD_conv2

出力先のフォルダを見てみましょう。なんだか色々とファイルがありますね。
この中のVOBファイルを変換していくことになります。

DVD_conv3

ただし、VOBファイルというのは実は中身mpeg2ですので、拡張子をmp2に変更すると普通に
windows media playerで視聴できます。ただし、問題は サイズがでかいってことですね。
なので、このそれが我慢できる人はこの時点でやめてもかまいません。

4.BatchDOO!でVOBをaviに変換
BatchDOO!を起動します。するとこんな画面が出てくると思います。

DVD_conv4

まず、変換したVOBを[対象ファイル]にドロップします。複数いっぺんで大丈夫です。
次に、保存先も決定。

このソフトは素晴らしいことに、面倒な各種設定が目的に応じて自動選択できるように
なっています。ここでは[PC向け-Xvid(中画質)]を選択してみましょう。

DVD_conv5

あとは右側の[GO]ボタンを押すだけ。簡単ですね。
ただ、けっこう時間かかります。PCにもよりけりですが。まあしばらくほっときましょう。

完了すると、保存先フォルダに.aviファイルができてますね。これで変換自体は完了です!

補足

VOBが分かれていれば当然ファイルが分かれてますね・・・
結合はたぶんできるんですが、色々試しているうちにメンドクサクなっちゃいました。
簡単にはできなそう。いいじゃん連続再生すれば・・・

どうしてもやりたい人は「UniteMovie」「VirtualDubMod」が必要なので、適宜調べてみてください(なげやり)。
たぶん、flv形式とかであれば簡単なんだと思います。たぶん。

posted by sandman at 13:18| Comment(0) | その他技術ネタ | このブログの読者になる | 更新情報をチェックする

2011年11月13日

OSGI入門 その3 〜Serviceの動的アップデート〜


さて、前回はupdateが上手くいかないところでしたね。まずはOSGIの仕様はBundleのupdateについて
どのように規定しているのでしょうか。仕様を見てみます。
※ちなみに、仕様のドキュメントはここからダウンロードできます。

The update process supports migration from one version of a bundle to a newer version of the same
bundle. The exports of an updated bundle must be immediately available to the Framework. If none
of the old exports are used, then the old exports must be removed. Otherwise, all old exports must
remain available for existing bundles and future resolves until the bundle is refreshed, see Refreshing
on page 148, or the Framework is restarted.

(訳)
updateプロセスはある同一バンドルに関して、古いバージョンから新しいバージョンへの移行をサポート
します。updateされるバンドルがexportしているサービスは直ちにフレームワーク内で有効化されなければなりません。
もし、古いexportがすべて使われなくなったなら、それは取り除かれなければなりません。それ以外の場合、すべての古い
exportはそのバンドルがrefreshされるか、フレームワークが再起動されるまで、既存バンドルおよび以降にインストール
されるバンドルから使用可能な状態に残しておかなければなりません。

なるほど、つまり変更を完全に有効にするにはOSGIフレームワークを再起動するか、「refresh」をかけろ
ということですね。もちろん、フレームワークの再起動をせずにやりたいので、refreshコマンドを使ってみましょう。

・refreshコマンドを使おう!

前回のプログラムをそのまま使います。適当な文字列でMyServiceImpleを修正してからrefreshをかけます。
すると・・・

osgi>refresh 2

osgi> ServiceConsumerBundle stop
ServiceBundle stop
ServiceBundle start
Service registed
ServiceConsumerBundle start
This is my service! version 2!
This is my service! version 2!
This is my service! version 2!

でけました。でもその前に標準出力をよく見てみると、ConsumerBundleも再起動されていることに気づきます。
つまり・・・

refresh→ConsumerBundle停止→ServiceBundle再起動→ConsumerBundle起動

となるわけです。要するに、refreshコマンドを打つと、対象バンドルがexportしているパッケージに依存しているバンドル
を停止し、対象バンドルを再起動してから、依存バンドルを起動するということのようですね。

うーん。なんか嫌ですね。できることなら、updateしたバンドルだけ再起動して終わりたいものです。
上記の仕様を見るかぎりだと駄目そうなんですが、実はこれやり方があります。といっても大したことではなく
バンドルの構成を変更するだけです。どうするかというと「IFと実装を別バンドルにする」これだけです。

・IFと実装を別バンドルに!

ではさっそくやってみましょう。といってもただIFと実装を分けるだけです。以下のバンドルを作成します。

■IFだけのバンドル
ServiceIFBundle

■実装バンドル
ServiceBundle2

■消費バンドル
ServieConsumer2

中身は前回と全く一緒。ただIFをMyServiceIFに移しただけです。もちろんIFがServiceIFBundleに移ったので
exportしているのはServiceIFBundleで残りの二つはそれをimportすることになります。

この3バンドルを構成して実行しましょう。

osgi> ServiceBundle start
Service registed
ServiceConsumerBundle start
This is my service!
This is my service!

ここまでは一緒ですね。ではMyServiceImplを適当に修正して、updateしてみましょう。

osgi> update 3
ServiceBundle stop
ServiceBundle start
Service registed
This is my service! update version
This is my service! update version
This is my service! update version

おお!ちゃんと新しいの取れてますね。素晴らしいです。

・IFバンドルと実装を別にすることについての補足

私が見る限り、OSGIの仕様として「IFと実装のバンドルはわけなさい」と規定しているわけではなさそうです。
ただ、ネットを調べてみると、この話題は議論されています。

Different osgi bundles with implementations of the same interface - where to place that inferface?

ここでの回答もやはり「分けた方がいい」とあります。理由は実装を後で置き換えられるということと、それから
対象バンドルを消費バンドルの再起動なしにhot replaceできるという理由が挙げられています。後者はまさに
今われわれが実験したことですね。

やはり、イディオムとしてはIFバンドルと実装バンドル分けておいたほうがいいんだと思われます。また、他の
利点としてはA実装バンドル⇔B実装バンドルというようにお互いのサービスを呼び合うような場合、IFと実装が
同居していると相互参照でエラーになっちゃいます。分けておけば、たすきがけのように呼び合えますね。

さて、次はServiceTrackerあたりをやろうかと思います。たぶん。

では。
posted by sandman at 16:07| Comment(0) | Java | このブログの読者になる | 更新情報をチェックする

OSGI入門 その2 〜Serviceについて〜


前回は導入として、Hello Worldをやりましたが、今回からはOSGIの肝であるサービスの話をしていきます。
前述の通り、OSGIはバンドルと呼ばれるプログラムコンポーネントの集合体を動かすためのフレームワークです。
Serviceとはそのひとつのバンドルが公開する一連の処理を意味します。Javaオブジェクトであればなんでも
サービスになりえます。しかし、実際にはまず公開するIFを作成して、サービスとして登録するのはそのIFの
実装クラスになるでしょう。

・サービスバンドルの作成
まずはサービスバンドルを作ります。前回と同様、プラグインプロジェクトにて以下のプロジェクトを作成します。

プロジェクト名:ServiceBundle
Activator:test.service1.activator.Activator

続いてIFの作成

package test.service1.serviceif;

/**
 * サービスinterface
 * @author rag-timer
 *
 */
public interface MyServiceIF {
	/**
	 * なんらかのサービス
	 */
	public void print();
}

お次に実装の作成

package test.service1.serviceimpl;

import test.service1.serviceif.MyServiceIF;

public class MyServiceImpl implements MyServiceIF {
	@Override
	public void print() {
		System.out.println("This is my service!");
	}
}

なんの意味もないサービスですが、とりあえずこれで登録するネタはそろいました。では、Activatorで登録します。
サービスの登録にはBundleContext#registerService()を使用します。

/*
 * (non-Javadoc)
 * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
 */
public void start(BundleContext bundleContext) throws Exception {
	Activator.context = bundleContext;

	System.out.println("ServiceBundle start");

	//サービスの実体
	MyServiceIF service = new MyServiceImpl();

	//サービスの登録を行う
	context.registerService(MyServiceIF.class.getName(), service, null);

	System.out.println("Service registed");
}

registerService()の一つ目の引数はサービスのこのOSGIフレームワーク内で識別するための文字列です。
別に文字列であればなんでもかまいませんが、普通IFの名前を使用します。二つ目の引き数にはサービス
の実体を指定します。三つ目はこのサービスのプロパティを指定しますが今回は使いません。

続いて、このサービスを「公開する」ための作業を行います。バンドル間でのサービス呼び出しは一般の
Javaオブジェクトの呼び出しと大して変わりませんが、別バンドルが公開しているIFをそのままimportする
ことはできません。かならず「サービス公開者がexportし」「サービス消費者がimportする」という作業が
必要になります。この設定を行うのがMETA-INF/MANIFEST.MFです。なお公開はパッケージ単位で行います。

ではサービスの公開を行いましょう。MANIFEST.MFをダブルクリックし、[ランタイム」タブを選択して下さい。
左側の[エクスポートされるパッケージ]欄で追加を押下し、IFのパッケージを指定します。

1.png
これでサービス側のバンドルの準備は完了しました。

・サービス消費バンドルを作成

次にクライアントとなるサービス消費バンドルを作成します。

プロジェクト名:ServiceConsumerBundle
Activator:test.serviceconsumer1.activator.Activator

さて、まずはimportを行いましょう。これを行わないと、サービスIFが参照できません。
MANIFEST.MFをダブルクリックして、[依存関係]タブから[インポート済みパッケージ]を選んでサービスIFの
パッケージを選択します。なお、当然、exportをこの段階で行っていなければリストに出てきません。

2.png
続いて以下のようにActivatorを実装します。

package test.serviceconsumer1.activator;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;

import test.service1.serviceif.MyServiceIF;

public class Activator implements BundleActivator {

	private static BundleContext context;

	private boolean flg = true;

	private final Thread myThread = new Thread(){
		public void run(){

			while(flg){

				//ServeiceReferenceの取得
				ServiceReference ref = Activator.context.getServiceReference(MyServiceIF.class.getName());

				//サービスの生成
				MyServiceIF service = (MyServiceIF)Activator.context.getService(ref);

				//サービスの呼び出し
				service.print();

				try {
					Thread.sleep(5000);
				} catch (InterruptedException e) {
					break;
				}

			}
		}
	};

	static BundleContext getContext() {
		return context;
	}

	public void start(BundleContext bundleContext) throws Exception {

		System.out.println("ServiceConsumerBundle start");

		Activator.context = bundleContext;

		//スレッドのスタート
		myThread.start();
	}

	public void stop(BundleContext bundleContext) throws Exception {

		System.out.println("ServiceConsumerBundle stop");

		flg = false;
		Activator.context = null;
	}

}


Activator#startでは、定期的にサービスを使用するスレッドを起動してます。そのスレッドのrun()の中で
BundleContext#getServiceReference()でServiceReferenceオブジェクトを作成します。引数で渡すのは
先ほどサービスの登録に使用したサービス識別用の文字列、すなわちサービスのクラス名です。
作成したServiceReferenceを引数に、BundleContext#getService()でサービスが取得できます。
とりあえずはさらっと流します。

これで実行構成からこの2つのバンドルを構成し、実行すると・・・

osgi> ServicConsumerBundle start
ServiceBundle start
Service registed
This is my service!
This is my service!
・・・

てな感じで表示されるはずです。ちゃんとサービス呼べてますね。

・でもサービスをupdateすると・・・

では前回のようにサービスを書き換えてみましょう。適当にprintlnの文字列を変更して保存し、ssで
IDを確認後

update サービスバンドルのid

を実行します。すると・・・

osgi> Exception in thread "Thread-2" java.lang.NullPointerException: A null service reference is not allowed.
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.getService(BundleContextImpl.java:660)
at test.serviceconsumer1.activator.Activator$1.run(Activator.java:22)

こんなんなっちゃいました。update後、スレッド内の処理でServiceReferenceが取れていないようです。
この解決策は次回にします。

では。
posted by sandman at 00:07| Comment(0) | Java | このブログの読者になる | 更新情報をチェックする

広告


この広告は60日以上更新がないブログに表示がされております。

以下のいずれかの方法で非表示にすることが可能です。

・記事の投稿、編集をおこなう
・マイブログの【設定】 > 【広告設定】 より、「60日間更新が無い場合」 の 「広告を表示しない」にチェックを入れて保存する。


×

この広告は1年以上新しい記事の投稿がないブログに表示されております。