第 4 章 ユーザーインタフェースの設計
4.4 マルチメディアデータの使用
4.4.2 プレゼンタの利用
iアプリ実行環境では、アニメーションを含む画像の再生やサウンドの再生を行う機能が提供され ます。画像を再生するクラスとサウンドを再生するクラスとしてそれぞれ、VisualPresenter と AudioPresenter があります。
注意事項:
● VisualPresenterはコンポーネントであり、高レベルAPIにてPanelオブジェクトに追加して使用しま す。VisualPresenterでは、標準的に再生可能な動画メディアとしてGIFアニメーションおよびiモーシ ョン形式データをサポートしています(iモーション形式データについては4.4.5項参照)。
● AudioPresenterはコンポーネントではありません。AudioPresenterはPanel表示時、Canvas表示 時のいずれの場合も使用することができます。
● NTTドコモの提供するDoJa-2.0プロファイル以降対応のiアプリ開発環境では、AudioPresenterはMFi 形式データとMIDI形式データをサポートしています。iアプリ開発環境を使用した実際の開発手順などに ついては第15章を参照してください。
【DoJa-2.0】
NTTドコモの提供するDoJa-1.0プロファイル対応iアプリ開発環境では、サウンドデータとしてMFi 形式データを使用することはできません。DoJa-1.0対応iアプリ開発環境で使用可能なサウンドデータ はMIDI形式データのみとなります。
● 携帯電話の中には、iアプリやブラウザ、通話などを、タスクを切り替えながら並列に起動して利用できる ものがあります。このような携帯電話において、別のタスクでサウンドや音声を取り扱う機能が起動されて いる状態では、iアプリからサウンドや音声を取り扱う機能(AudioPresenterによるサウンド再生や VisualPresenterによるiモーション再生など)を使用すると例外(UIException)が発生します。
Copyright Ⓒ 2008-2012 NTT DOCOMO, Inc. All Rights Reserved.
iアプリのサウンド・音声関連機能と同時に使用できない機能には、通話機能や音楽プレーヤーなどがあり ます(機種によっては音楽プレーヤーを実行中にiアプリがサウンド再生を行っても例外を発生させず、音 楽プレーヤーとiアプリのサウンドの切り替え制御などを行うものもあります)。
次に、 VisualPresenter クラスを使って画像を再生する例と、 AudioPresenter クラスを使っ てサウンドを再生する例を示します。
この例では、画像ファイルやサウンドファイルとして、iアプリの JAR ファイルに同梱されたリ ソースを使用しています(”resource:///”で始まる URL の使用)。リソースについては、第 7 章 を参照してください。なお、この URL にはリソースだけではなく、Web サーバー上のファイルを 示す HTTP の URL や、ScratchPad 上の位置を示す URL を指定することもできます。
例: 画像ファイルの表示
package uidemo;import java.util.*;
import com.nttdocomo.ui.*;
import com.nttdocomo.io.ConnectionException;
public class VisualPresenterDemo extends UIDemoPanel {
int px, py; // 現在の画像の表示位置(VisualPresenter内)
VisualPresenter theVP; // プレゼンター
Button startButton; // GIFアニメーション再生ボタン Button stopButton; // GIFアニメーション停止ボタン ListBox repeatChoice; // 繰り返し再生指示用チェックボックス Ticker ticker; // キーマップ説明用ティッカーテープ
static String instr = "Control ImagePos: Key 2-Down 8-Up 4-Left 6-Right";
/**
* VisualPresenterDemo コンストラクタ
* 必要な画像データを取得して、VisualPresenterに引き渡す。
*/
VisualPresenterDemo() { // 画像データを取得する。
MediaImage mi =
MediaManager.getImage("resource:///uidemo/img/singleloop.gif");
// use()メソッドを呼び出すまで画像データを利用することはできない。
try {
mi.use();
} catch (ConnectionException ce) { // ここで入出力の例外を処理する。
} catch (UIException uie) { // ここでUIの例外を処理する。
}
px = 0;
py = 0;
theVP = new VisualPresenter();
theVP.setImage(mi);
ticker = new Ticker(instr);
startButton = new Button("start");
stopButton = new Button("stop ");
repeatChoice = new ListBox(ListBox.CHECK_BOX);
Copyright Ⓒ 2008-2012 NTT DOCOMO, Inc. All Rights Reserved.
repeatChoice.append("Repeat");
add(theVP);
add(ticker);
add(startButton);
add(stopButton);
add(repeatChoice);
// メディアリスナーを設定する。
theVP.setMediaListener(new MediaListenerClass());
setTitle("Status Line");
this.setComponentListener(new ListenerClass());
this.setKeyListener(new KeyListenerClass());
}
class KeyListenerClass implements KeyListener { /**
* キーリリースイベントは無視する。
*/
public void keyReleased(Panel p, int key) {}
/**
* キープレスイベントにより画像表示位置の調整を行う *
* @param p イベントの発生したPanel * @param key 押されたキーの値
*/
public void keyPressed(Panel p, int param1) { if (VisualPresenterDemo.this == p) {
if (param1 == Display.KEY_8) { // 画像の位置(下)
py--;
} else if (param1 == Display.KEY_2) { // 画像の位置(上)
py++;
} else if (param1 == Display.KEY_4) { // 画像の位置(左)
px++;
} else if (param1 == Display.KEY_6) { // 画像の位置(右)
px--;
}
// VisualPresenterのsetAttribute()メソッド呼び出しにより // 画像表示位置を設定する。
theVP.setAttribute(VisualPresenter.IMAGE_XPOS, px);
theVP.setAttribute(VisualPresenter.IMAGE_YPOS, py);
} } }
class ListenerClass implements ComponentListener { /**
* コンポーネントイベントにより再生の開始、停止を制御する *
* @param c イベントの発生したコンポーネント * @param type イベントタイプ
* @param param イベントパラメータ */
public void componentAction(Component c, int type, int param) { if (c == startButton) { // 再生ボタンを押すと再生開始 theVP.play();
} else if (c == stopButton) { // 停止ボタンを押すと再生停止
Copyright Ⓒ 2008-2012 NTT DOCOMO, Inc. All Rights Reserved.
theVP.stop();
} } }
class MediaListenerClass implements MediaListener { /**
* VisualPresenterからのイベントを受け取り、必要に応じて再度再生を行うための * メディアリスナー。ループ再生機能はここで実現される。
*/
public void mediaAction(MediaPresenter source, int type, int param) { if (source == theVP) {
switch (type) {
// 画像の再生完了イベントはここで処理される。Panelタイトルに // 再生を完了したことを表示し、必要に応じて再度再生を繰り返す。
// この処理は非ループ再生型GIFアニメーションでのみ有用。
case VisualPresenter.VISUAL_COMPLETE : setTitle("Complete");
if ((repeatChoice.isIndexSelected(0))) { ((VisualPresenter) source).play();
setTitle("[Comp]Play again");
} break;
// 画像の再生開始イベントはここで処理される。
// Panelタイトルに再生を開始したことを表示する。
case VisualPresenter.VISUAL_PLAYING : setTitle("Playing");
break;
// 画像の再生停止イベントはここで処理される。
// Panelタイトルに再生を停止したことを表示する。
case VisualPresenter.VISUAL_STOPPED : setTitle("Stopped");
break;
} } } } /**
* MediaImageは不要になったら破棄(unuse()およびdispose())すべきである。
* 破棄することにより資源の解放が行われる。ここではMediaImageを再利用する可能性 * があるため破棄は行わない。
*/
public void leave() { }
}
例: サウンドファイルの再生
package uidemo;
import com.nttdocomo.ui.*;
import com.nttdocomo.io.ConnectionException;
public class AudioPresenterDemo extends UIDemoPanel { ListBox loopChoice; // ループ再生フラグ
サウンド再生ボタン
Copyright Ⓒ 2008-2012 NTT DOCOMO, Inc. All Rights Reserved.
Button stopButton; // サウンド停止ボタン Label statusLabel; // ステータス表示ラベル AudioPresenter theAP; // AudioPresenter MediaSound theMediaSound; // MediaSound /**
* AudioPresenterDemo コンストラクタ
* 再生/停止用の2つのボタンと、ループ再生を選択するためのチェックボックスを作成する。
*/
AudioPresenterDemo() {
loopChoice = new ListBox(ListBox.CHECK_BOX);
loopChoice.append("loop");
playButton = new Button("play");
stopButton = new Button("stop");
statusLabel = new Label("status line");
theMediaSound =
MediaManager.getSound("resource:///uidemo/img/music.mld");
// use()メソッドを呼び出すまでサウンドデータを利用することはできない。
try {
theMediaSound.use();
} catch (ConnectionException ce) { // ここで入出力の例外を処理する。
} catch (UIException uie) { // ここでUIの例外を処理する。
}
theAP = AudioPresenter.getAudioPresenter();
theAP.setSound(theMediaSound);
this.add(playButton);
this.add(stopButton);
this.add(loopChoice);
this.add(statusLabel);
this.setComponentListener(new ListenerClass());
theAP.setMediaListener(new MediaListenerClass());
}
class ListenerClass implements ComponentListener { /**
* サウンドデータの再生/停止を制御するためのボタンのイベントを受け取る
* リスナークラス。
*/
public void componentAction(Component c, int type, int param) { if (c == playButton) {
theAP.play();
} else if (c == stopButton) { theAP.stop();
} }
}
class MediaListenerClass implements MediaListener { /**
* AudioPresenterからのイベントを受け取り、必要に応じて再度再生を
* 行うためのメディアリスナー。ループ再生機能はここで実現される。
*/
public void mediaAction(MediaPresenter source,int type,int param) { if (source == theAP) {
switch(type) {
// サウンドの再生完了イベントはここで処理される。ステータス表示ラベル // に再生を完了したことを表示し、必要に応じて再度再生を繰り返す。
case AudioPresenter.AUDIO_COMPLETE:
statusLabel.setText("complete");
Copyright Ⓒ 2008-2012 NTT DOCOMO, Inc. All Rights Reserved.
if (loopChoice.isIndexSelected(0))
((AudioPresenter)source).play();
break;
// サウンドの再生開始イベントはここで処理される。
// ステータス表示ラベルに再生を開始したことを表示する。
case AudioPresenter.AUDIO_PLAYING:
statusLabel.setText("playing ");
break;
// サウンドの再生停止イベントはここで処理される。
// ステータス表示ラベルに再生を停止したことを表示する。
case AudioPresenter.AUDIO_STOPPED:
statusLabel.setText("stopped ");
break;
} }
} }
/**
* この画面が非表示になる際に、サウンドの再生を停止するため、AudioPresenter.stop()メソッド
* の呼び出しを行う。MediaSoundをこれ以上使用しない場合は、MediaSound. unuse()メソッドお
* よびMediaSound.dispose()メソッドも呼び出すべきである(各種資源の解放が行われる)。ここで
* はMediaSoundを再度利用する可能性があるため、これらのメソッドは呼び出さない。
*/
public void leave() { theAP.stop();
} }
【DoJa-2.0】
● DoJa-1.0プロファイルでは、メディアデータがセットされていないメディアプレゼンタに対しstop()メソ
ッドを呼び出した際の振る舞いはメーカーに依存していました。これに対しDoJa-2.0プロファイル以降では、
メディアデータがセットされていないメディアプレゼンタに対しstop()メソッドを呼び出すと例外
(UIException)が発生します。メディアプレゼンタにメディアデータがセットされているかどうかは MediaPresenter.getMediaResource()メソッドを使用して判定してください。
● DoJa-2.0プロファイル以降では、VisualPresenterによるアニメーションGIF再生について以下の規定が
追加されています。
・ 再生可能なフレーム数は、最低限8フレームが保証されます。
・ ループ型アニメーションGIFを再生した場合、1回のループが終了する毎に再生完了イベントが発生しま す。
・ ループ型アニメーションGIFの最大ループ回数は16回です。これを超えたループ回数が指定されている 場合でも、16回ループした時点で再生は停止します。
【DoJa-3.0】
DoJa-3.0プロファイル以降では、メディアデータの取得元としてURLだけでなくデータファイルのバイトイ
メージを指定することができます。バイトイメージは、byte配列またはInputStreamの形式で与えること ができます。
またDoJa-3.0プロファイル以降では、AudioPresenterに関して以下の項目を調整するための属性が追加さ
れています。
・ テンポ(AudioPresenter.CHANGE_TEMPO)
・ ボリューム(AudioPresenter.SET_VOLUME)
・ キー(AudioPresenter.TRANSPOSE_KEY)
Copyright Ⓒ 2008-2012 NTT DOCOMO, Inc. All Rights Reserved.
類似の機能がDoJa-2.0プロファイルのiアプリオプションAPI(AudioPresenter2クラス)に含まれていま すが、それらとはプログラミング上の互換はありませんのでご注意ください。
【DoJa-4.0】
DoJa-4.0プロファイル以降では、メディアデータの共通インタフェースであるMediaResourceに以下の機能
が追加されました。
・ isRedistributable(): このメディアデータが再配布可能に設定されているかどうかを取得します。
再配布可否が設定できるかどうか、およびその設定方法は、メディアデータの種類により異なります。
再配布不可としてネイティブの保存領域に保存されたデータは、メール添付や赤外線機能などを使用し て携帯電話外部に持ち出すことはできません。
・ setRedistributable(): このメディアデータに、再配布可/不可の設定を行います。
・ getProperty(): メディアデータのプロパティ値を取得します。サポートされるプロパティの種別は、
メディアデータの種別ごとに定められています。DoJa-4.0プロファイルでは、以下のプロパティがサポー トされています。
- MediaSound.AUDIO_3D_RESOURCES
このメディアサウンドのデータに3Dサウンド制御情報(定位情報)が埋め込まれている場合、そ れを使用するためには3Dサウンド制御リソースをいくつ必要とするかを取得します。3Dサウン ド制御および3Dサウンド制御リソースについては13章を参照してください。
- MediaImage.MP4_AUDIOTRACK
このメディアイメージのデータがiモーション形式データである場合、データに含まれるオーデ ィオトラックの数(数を表す数字文字列)を取得します。
- MediaImage.MP4_TEXTTRACK
このメディアイメージのデータがiモーション形式データである場合、データに含まれるテキス トトラックの数(数を表す数字文字列)を取得します。
- MediaImage.MP4_VIDEOTRACK
このメディアイメージのデータがiモーション形式データである場合、データに含まれるビデオ トラックの数(数を表す数字文字列)を取得します。
【DoJa-4.1】
DoJa-4.1プロファイル以降、メーカーによってはMediaManager.getImage()メソッドの引数にFlashコン テンツのデータを指定して呼び出すことで、MediaImageオブジェクトを取得することをサポートすることが あります。ただし、Flashコンテンツから生成されたMediaImageオブジェクトは、プレゼンタで再生するこ とはできません。Flashコンテンツから生成されたMediaImageオブジェクトは、ImageStore.addEntry() メソッドによりFlashコンテンツをネイティブの画像保存領域に保存する目的でのみ使用することができます。
【DoJa-5.0】
DoJa-5.0プロファイル以降のMediaManagerクラスでは、複数のMediaImageオブジェクト、または複数の
MediaSoundオブジェクトを一括して利用可能状態にするためのstaticメソッドuse()が設けられています。
このuse()メソッドでは、メディアデータオブジェクトの利用を一度きりとするかどうかを指定することがで
きます。メディアデータオブジェクトにおける「一度きり」の利用指定については、4.4.7項も参照してくださ い。
なお、DoJa-5.0プロファイルにてAudioPresenterクラスに以下の機能が追加されています。ただしこれら はオプショナルであり、サポートの有無はメーカーにより異なります。
・ ループ演奏指定およびループ再生イベント(LOOP_COUNT属性およびAUDIO_LOOPEDイベント)
・ iモーションのオーディオトラックの再生(getAudioTrackPresenter()メソッド)
・ 曲全体の演奏時間の取得(getTotalTime()メソッド)