JMFおよびJavaMediaAPIの進捗状況

私の最初のJavaWorldの記事は、Java Media Framework(JMF)にあったときのことです。さまざまなメディアAPIが成熟するにつれ、事態は一巡したと感じています。したがって、最後のメディアプログラミングのコラムでは、JMFとすべてのJava MediaAPIの一般的な状態を再検討します。

JMFおよびその他のJavaMediaテクノロジー、それらの実装を開発している企業、および開発者が利用できるようにするために、いくつかの注目すべき変更がありました。この記事は、必要に応じて以前の記事の資料を更新します。

重要な注意事項:Java Media Frameworkは、マルチメディアストリーム(ファイル、ネットワークストリームなど)を同期するための特定のAPIです。これは、Java 2D、Java 3D、JavaSpeechなどを含むいくつかのJavaMediaAPIの1つです。私はJavaのメディアフレームワークを参照して、JMF用語予約のJavaメディアをマルチメディアのAPIのコレクション全体のために。

JMFの歴史と基本

JMF 1.0、別名Java Media Player APIのうち、私は1997年4月に次のように書きました(「参考文献」を参照)。

Java Media Framework(JMF)の一部であるJava Media Player APIを使用すると、Javaプログラマーはアプレットやアプリケーションにオーディオとビデオを簡単に埋め込むことができます。静的マルチメディアとストリーミングマルチメディアの両方が、任意の有効なURLからサポートされます。JMFプレーヤーは他のプレーヤーによって制御され、複数のオーディオおよびビデオサンプルの同期再生を提供します。

この情報は、過去2年間の更新と追加にも当てはまります。ただし、JMFは、特に次の2.0 APIリリース(1999年の後半に予定)で、新しい機能を進化させ、範囲を拡大しました。

JMF業界のプレーヤー

まず、業界のプレーヤーを見てみましょう。Sun、Silicon Graphics(SGI)、およびIntelは、1998年半ばにオリジナルのJMF1.0を設計および指定しました。APIの初期バージョン以降の暫定的に、SGIとIntelの両方がJMF仕様プロセスから撤退しました。しばらくの間、JMFユーザーコミュニティでは、SunがJMFをサポートする唯一のベンダーであるという重大な懸念がありました。この状況は望ましくありませんでした。

幸いなことに、1998年後半にIBMはJMFに関心を持って介入しました。IBMがSunに参加した直後に、1.0 APIのすべてのJava実装がリリースされました(1998年12月)。Javaプラットフォーム用のJMF1.1として知られるこの実装は、Win32およびSolarisネイティブのJMF 1.1実装(パフォーマンスパックとして知られる)でサポートされるコンテンツおよびプロトコルタイプの限定的ですが重要なサブセットをサポートします。)。オールJavaJMF 1.1の可用性は、このテクノロジーがJava1.1準拠またはJava2ランタイムで利用可能になったという点で、JMFの主要なマイルストーンでした。実際、JMF 1.1 Java実装は、開発者がJMFアプレットとともにダウンロードするためにJARファイルに関連するJMFクラスのみを含めることができるツールを備えたWeb指向バージョンでも利用できます。これにより、JMFベースのアプレットをWebサーバーにデプロイして、Java1.1準拠のブラウザーで使用できるようになります。 NetscapeとMicrosoftはどちらも、最近のブラウザリリースのNavigatorとInternetExplorerでそれぞれJava1.1、つまりJMF 1.1 forJavaをサポートしています。

IBMは、SunがJMF 2.0 APIをコードファイン化するのを支援しています。これには、仕様が含まれ、次のJMFAPIであるJavaMediaCaptureのリファレンス実装が提供されます。IBMが、その後JMF機能をビジネス指向のJavaベースのソフトウェア製品のいくつかに組み込む方法を理解することを期待しましょう。これは、JMFテクノロジーの寿命にとって潜在的に良いことです。

JMF 2.0と1.0の新機能は何ですか?

JMF 1.0 APIは、同期されたオーディオとビデオの再生を処理するために必要なコンポーネントを指定します。JMF 1.0の機能のレビューについては、以前のJMFの記事(「参考文献」を参照)を参照してください。

JMF 2.0は、仕様にいくつかの重要な追加を行います。

  • オーディオとビデオのキャプチャ
  • オーディオとビデオのストリーミング、それによってクライアントに加えてすべてのJavaストリーミングサーバーを構築する可能性
  • プレーヤー内のプラグ可能なコーデックのサポート

JMF 2.0とその新機能の詳細については、現在バージョン0.5の早期アクセスで利用可能なJava Media Frameworkプログラマーズガイド(「参考文献」を参照)を参照してください。

JMF開発ツールとランタイムのインストール

Silicon GraphicsとIntelはどちらも、それぞれのWebサイトから以前のバージョンのJMFを削除しました。ただし、SunサイトからWin32、Solaris、およびJavaプラットフォーム用の最新のリファレンス実装(JMF 1.1と表記、1.0 API仕様に準拠)をダウンロードできます(「参考文献」を参照)。

全JavaバージョンのドキュメントにはAIXが具体的に記載されており、IBMがこのソフトウェアをAIXJavaランタイムでテストしていることを示していることに注意してください。JMFの将来のリリース(2.0以降)では、純粋なJava実装であろうとOS固有のネイティブ実装であろうと、IBMオペレーティング環境を具体的にサポートすることを期待しています。

更新されたJMFの例

以前のJMF記事からJMF1.0ベータ準拠の例を更新して、JMF 1.0API準拠の環境で実行できるようにしました。サンプルコードをダウンロードして、独自のメディアファイルを使用してJMF1.1実装で試すことができます。アプレットは、利用可能になったときにJMF2.0ランタイムでも実行する必要があります。(この記事に関連するすべてのファイルをzip形式でダウンロードするには、「参考文献」を参照してください。)

001 //次のパッケージステートメントをコメントアウトして、個別にコンパイルします。002 //パッケージcom.javaworld.media.jmf; 003 004 importjava.applet。*; 005 importjava.awt。*; 006 importjava.net。*; 007インポートjava.io. *; 008 importjavax.media。*; 009 010 / ** 011 * JMF11Appletは、1997年4月からJMFAppletを更新します。012* JMF 1.1API準拠のJavaWorld記事。013 *の記事を参照してください:

014 * //www.javaworld.com/jw-04-1997/jw-04-jmf.html 015 *

016 *さらに、JMF11Appletは017 * Java 1.1(およびそれ以降)のイベントモデルを使用するように作り直されました。この018 *バージョンは、Java 2 019 *およびJMF1.1 all-Java実装、1999年5月に開発およびテストされています。020*

021 *このアプレットは、Webサーバーのダウンロード用にJMF 1.1 023 *で提供されているjmf-server.jarを使用してパブリックWebサーバーに展開できます。このJARアーカイブには、024 *必要なJMFall-Javaランタイムクラスが含まれています。 JMF11Applet 025 *は、1999年6月の026 *列にこの方法で展開されました。

027 * //www.javaworld.com/jw-06-1999/jw-06-media.html 028 * 029 * @author Bill Day 030 * @version 1.1 031 * @see javax.media.ControllerEvent 032 * @see javax .media.ControllerListener 033 * @see javax.media.Manager 034 * @see javax.media.NoPlayerException 035 * @see javax.media.Player 036 * @see javax.media.RealizeCompleteEvent 037 ** / 038 039 public class JMF11Applet extendsアプレットはControllerListener {040プライベートURLmyURL = null;を実装します。 041プライベートプレーヤーmyPlayer = null; 042プライベートコンポーネントmyVisual = null; 043プライベートコンポーネントmyControls = null; 044プライベートパネルvisualPanel = null; 045 046 / ** 047 * JMF11Appletを初期化します。インターフェイスをレイアウトし、048 * init()でプレーヤーを作成します。 049 ** / 050 public void init(){051 super.init(); 052 053 // AWT LayoutManagerを指定します。 054 setLayout(new BorderLayout());055 056 // JMF11Appletが埋め込まれているWebページからURLをロードします。057Stringasset= getParameter( "ASSET"); 058 059 // URLを確認し、それを保持するURLオブジェクトを作成します。 060 if(asset.equals( "")){061 //アプレットにアセットを入力していません。 062} else {063 try {064 myURL = new URL(getDocumentBase()、asset); 065} catch(MalformedURLException e){066 //不完全なアセットを入力したか、間違ったURLを作成しました。 067 //より堅牢なアプレットはこれを適切に処理する必要があります。 068} 069} 070 try {071 //ここに興味深いビットがあります。 Managerは、072 //このURLの実際のプレーヤーを作成するために使用されます。次に073 // myPlayerのControllerListenerとしてJMF11Appletを追加します。 074 //これにより、RealizeCompleteEventsに応答できます。 075 myPlayer = Manager.createPlayer(myURL); 076 myPlayer.addControllerListener(this);077} catch(IOException e){078 // I / Oで問題が発生しました。出口。 079 System.out.println( "プレーヤーを作成しようとしているI / Oの問題...終了しています"); 080 System.exit(1); 081} catch(NoPlayerException e){082 //使用可能なプレーヤーを返すことができません。出口。 083 System.out.println( "使用可能なプレーヤーが返されませんでした...終了します"); 084 System.exit(1); 085} 086} 087 088 / ** 089 *デフォルトのアプレット開始メソッドをオーバーライドしてPlayerの090 * Realize()を呼び出します。これにより、最初に実現が行われ、091 *がcontrollerUpdate()092 *メソッドでGUI構築の最後のビットをトリガーします。再生を自動的に開始しません。ユーザーが094 *メディアサンプルの再生を開始するには、アプレットの[再生]ボタンをクリックするために093 *が必要です。 095 ** / 096 public void start(){097 myPlayer.realize();098} 099 100 101 / ** 102 *デフォルトのアプレット停止メソッドをオーバーライドしてmyPlayer.stop()103 *およびmyPlayer.deallocate()を呼び出し、誰かがブラウザでこのページを終了した場合にリソースを適切に解放するようにします104 *。 105 ** / 106 public void stop(){107 myPlayer.stop(); 108 myPlayer.deallocate(); 109} 110 111 / ** 112 *実現がいつ完了するかを知る必要があるため、113 * controllerUpdate()を使用してRealizeCompleteEventsを処理します。 114 * RealizeCompleteEventを受信すると、115 *をレイアウトし、ビデオコンポーネントとコントロールを116 *アプレットGUIに表示します。 117 ** / 118 public void controllerUpdate(ControllerEvent event){119 if(event instanceof RealizeCompleteEvent){120 //System.out.println("Received RCE ... "); 121 //これで、実現プレーヤーができました。122 // VisualComponentとControlPanelComponentを取得し、//それらをアプレットにパックできます。 124 myVisual = myPlayer.getVisualComponent(); 125 if(myVisual!= null){126 // VisualComponent 127 //がBorderLayoutによってサイズ変更されないようにするために、// FlowLayoutを使用してvisualPanel内にネストします。 129visualPanel = new Panel(); 130visualPanel.setLayout(new FlowLayout()); 131visualPanel.add(myVisual); 132 add(visualPanel、BorderLayout.CENTER); 133 //System.out.println("VisualComponentを追加しました... "); 134} 135 myControls = myPlayer.getControlPanelComponent(); 136 if(myControls!= null){137 add(myControls、BorderLayout.SOUTH); 138 //System.out.println( "追加されたコントロール..."); 139} 140 // invalidate(); 141 validate(); 142} 143 //それ以外の場合は、単にイベントを消費します。 144} 145}124 myVisual = myPlayer.getVisualComponent(); 125 if(myVisual!= null){126 // VisualComponent 127 //がBorderLayoutによってサイズ変更されないようにするために、// FlowLayoutを使用してvisualPanel内にネストします。 129visualPanel = new Panel(); 130visualPanel.setLayout(new FlowLayout()); 131visualPanel.add(myVisual); 132 add(visualPanel、BorderLayout.CENTER); 133 //System.out.println("VisualComponentを追加しました... "); 134} 135 myControls = myPlayer.getControlPanelComponent(); 136 if(myControls!= null){137 add(myControls、BorderLayout.SOUTH); 138 //System.out.println( "追加されたコントロール..."); 139} 140 // invalidate(); 141 validate(); 142} 143 //それ以外の場合は、単にイベントを消費します。 144} 145}124 myVisual = myPlayer.getVisualComponent(); 125 if(myVisual!= null){126 // VisualComponent 127 //がBorderLayoutによってサイズ変更されないようにするために、// FlowLayoutを使用してvisualPanel内にネストします。 129visualPanel = new Panel(); 130visualPanel.setLayout(new FlowLayout()); 131visualPanel.add(myVisual); 132 add(visualPanel、BorderLayout.CENTER); 133 //System.out.println("VisualComponentを追加しました... "); 134} 135 myControls = myPlayer.getControlPanelComponent(); 136 if(myControls!= null){137 add(myControls、BorderLayout.SOUTH); 138 //System.out.println( "追加されたコントロール..."); 139} 140 // invalidate(); 141 validate(); 142} 143 //それ以外の場合は、単にイベントを消費します。 144} 145}= null){126 // VisualComponent 127 //がBorderLayoutによってサイズ変更されないようにするために、// FlowLayoutを使用してvisualPanel内にネストします。 129visualPanel = new Panel(); 130visualPanel.setLayout(new FlowLayout()); 131visualPanel.add(myVisual); 132 add(visualPanel、BorderLayout.CENTER); 133 //System.out.println("VisualComponentを追加しました... "); 134} 135 myControls = myPlayer.getControlPanelComponent(); 136 if(myControls!= null){137 add(myControls、BorderLayout.SOUTH); 138 //System.out.println( "追加されたコントロール..."); 139} 140 // invalidate(); 141 validate(); 142} 143 //それ以外の場合は、単にイベントを消費します。 144} 145}= null){126 // VisualComponent 127 //がBorderLayoutによってサイズ変更されないようにするために、// FlowLayoutを使用してvisualPanel内にネストします。 129visualPanel = new Panel(); 130visualPanel.setLayout(new FlowLayout()); 131visualPanel.add(myVisual); 132 add(visualPanel、BorderLayout.CENTER); 133 //System.out.println("VisualComponentを追加しました... "); 134} 135 myControls = myPlayer.getControlPanelComponent(); 136 if(myControls!= null){137 add(myControls、BorderLayout.SOUTH); 138 //System.out.println( "追加されたコントロール..."); 139} 140 // invalidate(); 141 validate(); 142} 143 //それ以外の場合は、単にイベントを消費します。 144} 145}133 //System.out.println("VisualComponentを追加しました... "); 134} 135 myControls = myPlayer.getControlPanelComponent(); 136 if(myControls!= null){137 add(myControls、BorderLayout.SOUTH); 138 //System.out.println( "追加されたコントロール..."); 139} 140 // invalidate(); 141 validate(); 142} 143 //それ以外の場合は、単にイベントを消費します。 144} 145}133 //System.out.println("VisualComponentを追加しました... "); 134} 135 myControls = myPlayer.getControlPanelComponent(); 136 if(myControls!= null){137 add(myControls、BorderLayout.SOUTH); 138 //System.out.println( "追加されたコントロール..."); 139} 140 // invalidate(); 141 validate(); 142} 143 //それ以外の場合は、単にイベントを消費します。 144} 145}

アプレットを独自のWebページに埋め込む方法を示すために、簡単なサンプルHTMLドキュメントexample.html(ここをクリックして今すぐブラウザで試すことができます)を含めました。ASSETタグ内のメディアファイルを変更するだけで、すぐに使用できます。

この例では、JMF 1.1 for Web Serversのダウンロード(JMF Webサイトに記載)を使用して、必要なJMFランタイムクラスを含むコードアーカイブをJMF11Applet自動的にダウンロードできるようにしjmf-server.jarました。これにより、エンドユーザーがインストールするソフトウェアがなくても、アプレットをJava1.1互換のブラウザ内で実行できます。 (JMF for Web Serversバージョンにはカスタマイズツールも含まれていることに注意してくださいJMFCustomizer。これにより、JMF JARファイルからさらに多くの不要なクラスを削除できる可能性があります。このツールは現在Java2では機能しませんが、古いものを使用しているためです。 Swingのパッケージ名。)

example.htmlに埋め込まれた特定の例では、WAVファイル(welcome.wav)をロードし、使用可能にする適切な制御コンポーネント(これは音声のみのメディアファイルであるため、ビデオコンポーネントはありません)を確認し、マルチメディアを再生します。ファイル。WAVファイル(600 KB)およびJMFクラス(570 KB)は、接続速度によっては、マシンにダウンロードするのに数分かかる場合があることに注意してください。

サンプルページを解析した後、Java 1.1準拠のブラウザは、アプレットをロードし、JavaWorldWebサーバーからJMFクラスをサポートする必要があります。アプレットがロードされて実行されたら、再生ボタンを押してWAVサウンドファイルの再生を開始できます。スクロールバーを使用して再生の位置を変更し、[一時停止/再生]ボタンを使用して再生を一時停止して再開してみてください。

JMF 1.1 Javaプラットフォームの実装では、コントロールにすべてJavaウィジェットを使用するため、コントロールはブラウザー間およびプラットフォーム間で同じ外観になります。Solaris7のNetscapeCommunicatorのJVMおよびWin32のInternetExplorerのMicrosoftのJVM内でアプレットがどのように実行されているかに注目してください。

iというラベルの付いたボタンは、JMFアプレットで再生されているメディアファイルに関する情報を提供します。このWebページで実行されているWAVファイルの詳細を取得するには、この情報リンクをクリックしてください。