サウンドの例:Podcast PlayerFlash Player 9 以降、Adobe AIR 1.0 以降 ポッドキャストとは、オンデマンドで、またはサブスクリプションによってインターネット配信されるサウンドファイルです。 通常、ポッドキャストは、ポッドキャストチャンネルとも呼ばれるシリーズの一部としてパブリッシュされています。 ポッドキャストエピソードは、1 分で終わるものから数時間かかるものまであるため、再生しながらストリーミングされます。 ポッドキャストエピソードは別名アイテムとも呼ばれ、多くの場合は MP3 ファイル形式で配信されます。 ビデオポッドキャストも一般的ではありますが、このサンプルアプリケーションでは MP3 ファイルを使用するオーディオポッドキャストのみを再生します。 この例は、フル機能を備えたポッドキャストアグリゲーターアプリケーションではありません。 例えば、このアプリケーションは特定のポッドキャストへのサブスクリプションを管理したり、アプリケーションの次回実行時のために、ユーザーがどのポッドキャストを聴いていたかを覚えるということはありません。 だたし、より多くの機能を備えたポッドキャストアグリゲーターのたたき台として使用することができます。 Podcast Player の例では、次の ActionScript プログラミング手法を示します。
このサンプルのアプリケーションのファイルを入手するには、www.adobe.com/go/learn_programmingAS3samples_flash_jp を参照してください。 Podcast Player アプリケーションのファイルは、Samples/PodcastPlayer フォルダーにあります。 このアプリケーションは次のファイルで構成されています。
ポッドキャストチャンネルの RSS データの読み取りPodcast Player アプリケーションは、最初にいくつかのポッドキャストチャンネルとエピソードに関する情報を読み取ります。 1. アプリケーションはまず、ポッドキャストチャンネルのリストを含む XML 設定ファイルを読み取り、チャンネルのリストを表示します。 2. ユーザーがいずれかのポッドキャストチャンネルを選択すると、チャンネルの RSS フィードが読み取られ、チャンネルエピソードのリストが表示されます。 この例では、URLLoader ユーティリティクラスを使用し、テキストベースのデータをリモートまたはローカルのファイルから取得します。 Podcast Player はまず URLLoader オブジェクトを作成し、playerconfig.xml ファイルから XML 形式の RSS フィードのリストを取得します。 次に、ユーザーがリストから特定のフィードを選択すると、新しい URLLoader オブジェクトが作成され、フィードの URL から RSS データを読み取ります。 SoundFacade クラスを使用した、サウンドのロードと再生の簡便化ActionScript 3.0 のサウンドアーキテクチャは強力ですが、複雑でもあります。 サウンドの基本的なロード機能と再生機能しか必要としないアプリケーションでは、シンプルなメソッド呼び出しとイベントによって複雑さを隠すことができるクラスを使用することができます。 ソフトウェア設計パターンの分野で、このようなクラスはファサードと呼ばれます。 SoundFacade クラスは、次のタスクを実行するために単一のインターフェイスを提供します。
SoundFacade クラスは、ActionScript サウンドクラスの大半の機能を、複雑さを軽減した形で提供します。 次のコードは、クラス宣言、クラスプロパティおよび SoundFacade() コンストラクターメソッドを示します。 public class SoundFacade extends EventDispatcher { public var s:Sound; public var sc:SoundChannel; public var url:String; public var bufferTime:int = 1000; public var isLoaded:Boolean = false; public var isReadyToPlay:Boolean = false; public var isPlaying:Boolean = false; public var isStreaming:Boolean = true; public var autoLoad:Boolean = true; public var autoPlay:Boolean = true; public var pausePosition:int = 0; public static const PLAY_PROGRESS:String = "playProgress"; public var progressInterval:int = 1000; public var playTimer:Timer; public function SoundFacade(soundUrl:String, autoLoad:Boolean = true, autoPlay:Boolean = true, streaming:Boolean = true, bufferTime:int = -1):void { this.url = soundUrl; // Sets Boolean values that determine the behavior of this object this.autoLoad = autoLoad; this.autoPlay = autoPlay; this.isStreaming = streaming; // Defaults to the global bufferTime value if (bufferTime < 0) { bufferTime = SoundMixer.bufferTime; } // Keeps buffer time reasonable, between 0 and 30 seconds this.bufferTime = Math.min(Math.max(0, bufferTime), 30000); if (autoLoad) { load(); } } SoundFacade クラスは、独自のイベントを送出できるよう EventDispatcher クラスを拡張します。 クラスコードは、まず Sound オブジェクトと SoundChannel オブジェクトのプロパティを宣言します。 このクラスは、サウンドをストリーミングするときに使用する、サウンドファイルの URL の値と bufferTime プロパティも格納します。さらに、ロードおよび再生の動作に影響するブールパラメーター値のいくつかを受け取ります。
bufferTime パラメーターのデフォルト値は -1 です。コンストラクターメソッドが bufferTime パラメーターに負の値を検知した場合、bufferTime プロパティを SoundMixer.bufferTime の値に設定します。これにより、アプリケーションのデフォルト値は、必要に応じてグローバルな SoundMixer.bufferTime の値になります。 autoLoad パラメーターが true に設定されている場合、コンストラクターメソッドはすぐに次の load() メソッドを呼び出し、サウンドファイルのロードを開始します。 public function load():void { if (this.isPlaying) { this.stop(); this.s.close(); } this.isLoaded = false; this.s = new Sound(); this.s.addEventListener(ProgressEvent.PROGRESS, onLoadProgress); this.s.addEventListener(Event.OPEN, onLoadOpen); this.s.addEventListener(Event.COMPLETE, onLoadComplete); this.s.addEventListener(Event.ID3, onID3); this.s.addEventListener(IOErrorEvent.IO_ERROR, onIOError); this.s.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onIOError); var req:URLRequest = new URLRequest(this.url); var context:SoundLoaderContext = new SoundLoaderContext(this.bufferTime, true); this.s.load(req, context); } load() メソッドは新しい Sound オブジェクトを作成し、すべての重要なサウンドイベントのリスナーを追加します。その後、bufferTime 値に渡す SoundLoaderContext オブジェクトを使用して、Sound オブジェクトにサウンドファイルをロードするよう指示します。 url プロパティは変更することができるので、SoundFacade インスタンスを使用して異なるサウンドファイルを連続して再生することができます。url プロパティを変更して load() メソッドを呼び出すだけで、新しいサウンドファイルがロードされます。 次の 3 つのイベントリスナーメソッドは、SoundFacade オブジェクトがどのようにロードの進行状況をトラッキングし、サウンドを再生するタイミングを決定するかを示します。 public function onLoadOpen(event:Event):void { if (this.isStreaming) { this.isReadyToPlay = true; if (autoPlay) { this.play(); } } this.dispatchEvent(event.clone()); } public function onLoadProgress(event:ProgressEvent):void { this.dispatchEvent(event.clone()); } public function onLoadComplete(event:Event):void { this.isReadyToPlay = true; this.isLoaded = true; this.dispatchEvent(evt.clone()); if (autoPlay && !isPlaying) { play(); } } サウンドのロードが開始すると、onLoadOpen() メソッドが実行されます。サウンドをストリーミングモードで再生できる場合、onLoadComplete() メソッドは isReadyToPlay フラグをすぐに true に設定します。isReadyToPlay フラグは、「再生」ボタンをクリックするなどのユーザーアクションに反応して、アプリケーションがサウンドの再生を開始できるかどうかを決定します。SoundChannel クラスはサウンドデータのバッファリングを管理するので、play() メソッドを呼び出す前に十分なデータ量がロードされたかどうかを明示的に確認する必要はありません。 ロードプロセス中は、onLoadProgress() メソッドが定期的に実行されます。このメソッドは、SoundFacade オブジェクトを使用するコードによって使用される ProgressEvent オブジェクトのクローンを送出するだけです。 サウンドデータが完全にロードされると、onLoadComplete() メソッドが実行されます。必要であれば、非ストリーミングサウンドのために play() メソッドを呼び出します。play() メソッドを以下に示します。 public function play(pos:int = 0):void { if (!this.isPlaying) { if (this.isReadyToPlay) { this.sc = this.s.play(pos); this.sc.addEventListener(Event.SOUND_COMPLETE, onPlayComplete); this.isPlaying = true; this.playTimer = new Timer(this.progressInterval); this.playTimer.addEventListener(TimerEvent.TIMER, onPlayTimer); this.playTimer.start(); } } } サウンドが再生できる状態になると、play() メソッドは Sound.play() メソッドを呼び出します。生成される SoundChannel オブジェクトは、sc プロパティに格納されます。その後、play() メソッドは Timer オブジェクトを作成します。これを使用すると、playback progress イベントを定期的に送出することができます。 再生の進行状況の表示Timer オブジェクトを作成して再生を監視する処理は複雑なので、コードの実行は一度きりにする必要があります。 この Timer ロジックを、SoundFacade クラスのような再利用可能なクラスにカプセル化することで、アプリケーションはサウンドのロード時や再生時に同様の progress イベントを監視することができます。 SoundFacade.play() メソッドによって作成される Timer オブジェクトは、TimerEvent インスタンスを毎秒送出します。以下に示す onPlayTimer() メソッドは、新しい TimerEvent が受信されるたびに実行されます。 public function onPlayTimer(event:TimerEvent):void { var estimatedLength:int = Math.ceil(this.s.length / (this.s.bytesLoaded / this.s.bytesTotal)); var progEvent:ProgressEvent = new ProgressEvent(PLAY_PROGRESS, false, false, this.sc.position, estimatedLength); this.dispatchEvent(progEvent); } onPlayTimer() メソッドは、再生の監視の節で説明したサイズ予測方法を実装します。イベントタイプ SoundFacade.PLAY_PROGRESS で新しい ProgressEvent インスタンスが作成されます。そのとき、bytesLoaded プロパティは SoundChannel オブジェクトの現在位置に設定され、bytesTotal プロパティはサウンドデータの予測長に設定されます。 再生の一時停止と再開前述の SoundFacade.play() メソッドは、サウンドデータの開始位置に対応する pos パラメーターを受け取ります。pos 値がゼロの場合、サウンドは最初から再生されます。 SoundFacade.stop() メソッドは、次に示す pos パラメーターも受け取ります。 public function stop(pos:int = 0):void { if (this.isPlaying) { this.pausePosition = pos; this.sc.stop(); this.playTimer.stop(); this.isPlaying = false; } } SoundFacade.stop() メソッドが呼び出されると pausePosition プロパティが設定されるので、アプリケーションは同じサウンドの再生を再開する場合の再生ヘッドの位置を特定できます。 以下に示す SoundFacade.pause() メソッドおよび SoundFacade.resume() メソッドは、それぞれ SoundFacade.stop() メソッドおよび SoundFacade.play() メソッドを呼び出し、呼び出すたびに pos パラメーター値を渡します。 public function pause():void { stop(this.sc.position); } public function resume():void { play(this.pausePosition); } pause() メソッドは、現在の SoundChannel.position 値を play() メソッドに渡します。このメソッドは、この値を pausePosition プロパティに格納します。resume() メソッドは、開始位置として pausePosition 値を使用し、同じサウンドを再生を開始します。 Podcast Player の拡張例この例では、再利用可能な SoundFacade クラスを主に使用する、必要最小限の機能だけを備えた Podcast Player を示します。 次のような機能を追加して、アプリケーションの利便性を高めることもできます。
|
|