共有メディアプレイヤー
これまでも少し紹介したように、Live Frameworkによりデータだけでなくアプリケーション自体を共有することが可能です。今回は、アプリケーションの共有を意識したMesh-enabled Webアプリケーションの簡単なサンプルを作ります。
今回作成するアプリケーションを図1に示します。フォルダ内のメディアファイルをボタンとして表示し、クリックするとそのファイルを再生するメディアプレイヤーです。停止ボタンもない見た目も中身も大雑把な作りですが、大きなひとつの特徴は、このアプリケーションをユーザー間で共有したり複数デバイス上で同時実行したときに、アプリケーションに対する操作(クリックで再生)が同期して行われるという点です。
複数ユーザーで実行した場合、全員が同じメディアファイルを再生することになるわけですね。アプリケーション間の通信には、これまで本連載で紹介したData FeedとData Entryリソースを使います。アプリケーション作成後にアプリケーションの共有方法についても触れています。
作成するメディアプレイヤーが参照するファイルはLive Meshフォルダ内の拡張子がwmaまたはwmvのファイルを参照するものとします。
前回に紹介したとおり、Mesh-enabled Webアプリケーションは許可なくMesh上のLive Meshフォルダにはアクセスできませんので、事前にアクセス許可をアプリケーションに設定します。メディアプレイヤーを共有するユーザーも同様にフォルダアクセス許可の設定とフォルダ自身の共有も必要になります。Live Meshフォルダではなくアプリケーション自身のデータとしてメディアファイルを保存することも可能ですが、今回はこのような仕様にしています。
メディアプレイヤーの作成
まずはメディアプレイヤーのUIやフォルダ参照部分を作成し、その後に同期処理部分を作ります。
それではSilverlight Mesh-enabled Web アプリケーションプロジェクトを作成しましょう。プロジェクトの作成と実行方法は第7回で紹介した通りです。そちらを参照してください。今回もVB.NETを使用しています。
フォルダとメディアファイルの準備
メディアプレイヤーの作成にあたり、メディアファイルをLive Meshフォルダに用意しておきましょう。
Live Framework Developer Sandboxにサインインして、Live Desktop上で適当なフォルダを作成しメディアファイルをアップロードします(図2)。ここではMediaというフォルダ名にしました。
ちなみにこれらのメディアファイルはLive Desktop上で再生が可能になっています。
ファイル一覧の表示
Live Meshフォルダ内にあるファイルを取得し、アプリケーションのウィンドウに一覧表示する部分を作成します。SilverlightプロジェクトにあるPage.xamlのGrid以下を次のように編集します。
メディアファイルの再生のためのMediaElementコントロール(非表示にしています。つまり動画も音声のみ再生です)とコレクションを表示するためにItemsControlコントロールを記述しています。ItemsControlに設定するコレクションのアイテムはData Entryのリソースを格納するようこの後コーディングします。
コレクションの各アイテムの表示方法は<DataTemplate>に定義しています。Buttonコントロール内にImage、TextBlockコントロールがあります。TextBlockにはリソースのTitleプロパティを表示するよう指定しています。Imageコントロールには音符の画像を指定しています。画像は適当に用意していただくか、このコントロール自体を削除しても構いません。
続いてMesh上のLive Meshフォルダからメディアファイルを取得し、アプリケーションに表示するロジック部分を記述します。ファイルPage.xaml.vb内に次のメソッドを追加します。
上記メソッドではMesh上のMesh ObjectからLive Meshフォルダであるものを探し、さらにその中のファイルについて拡張子がwmaとwmvであるものをItemsControlのItemsコレクションへ追加しています。コレクションへ追加しているアイテムはData EntryのResourceプロパティの内容(DataEntryResourceオブジェクト)です。
このメソッドをアプリケーションロード時に呼び出すようmeshAppLoadedメソッド内に追記しておきましょう。
ボタンクリック時のイベント処理は、クリック時に対象のメディアファイルが再生されるよう仮に次のように記述しておきます。
引数のsenderオブジェクトからクリックされたボタンを取得し、ButtonオブジェクトのDataContextプロパティからData Entryのリソースを取得しています。メディアファイルへのURLはEditMediaLinkプロパティから取得し、これをMediaElementコントロール(名前Player)のSourceプロパティに指定することでメディアファイルの再生が可能です。最後にPlayメソッドを呼んでいます。
Live Meshフォルダのアクセス許可
ここまでを実行してみましょう。初回実行時のみ、Azure Services Developer Portal上にプロジェクトの作成や、アプリケーションパッケージのアップロード作業などが必要です。
初めて実行する場合は、Live Meshフォルダへのアクセスをアプリケーションに対して許可していないため、ひとつもファイルが表示されないはずです。Live Framework Developer Sandboxにサインインし、Appタブから対象アプリケーションを選択しアクセス許可を変更します。「edit」リンクをクリックし、移動ページ先の「change」リンクからメディアファイルが入っているフォルダを選択します(図3、4)。
アクセス許可設定後、再度アプリケーションを実行してみましょう。フォルダ内のメディアファイルがボタンとして表示され、クリックするとそのファイルが再生されれば成功です。
プレイヤー操作の同期
作成したメディアプレイヤーは、アプリケーションを共有しているユーザーが同時に使用していたとしても独立して動くだけです。アプリケーションを共有している場合、その操作が同期するように改良してみましょう。
操作の同期には、アプリケーションのデータ保存領域として利用できるData FeedとData Entryリソースを使用します。以下のクラスを用意し、メディアプレイヤーに対する操作をひとつのオブジェクトとして表します。
Commandプロパティに「play」などの操作を表す文字列、ArgumentプロパティにはメディアファイルのURLなどの値を設定して使います。本記事では再生を表す「play」コマンドしか使用しませんが、拡張した場合にも利用できるようにとこのようにしています。このクラスのひとつのオブジェクトを、ひとつのData Entryの値としてMesh上に保存します。
Data EntryはData Feed内に格納する必要があります。アプリケーション自身のData FeedコレクションにひとつのData Feedを用意し、ここにData Entryを追加します。
メディアファイルの再生などの処理は、Data Feed内のData Entryに対する変更通知を受けたっときに行います。Data Feed内には複数のData Entryが存在する可能性があるため、最新のData Entryを参照するものとします。Data FeedやData Entryなどの変更通知の受信については第5回でも紹介しています。
ここまでのメディアプレイヤー動作イメージを図5に示します。
それではコードを書いていきましょう。まず、Data Feedの追加です。アプリケーション
ロード時にData Feedがひとつもない場合は新しく作成し追加します。meshAppLoadedメソッド内を次のように変更します。
追加処理は非同期のため追加完了時のイベントの関連付けを行っています。また、Data Feedの追加完了後、または既にData Feedがあった場合はData Feedがあることを確認した後に、イベントの関連付けの処理を行います。それぞれ必要なメソッドの内容は次の通りです。
イベント関連付けは以下の3種類を処理しています。
- Data Feed内のData Entryの変更通知を受信したときのイベント
- Data Feedを最新に更新したときのイベント
- Data Feed内にData Entryを追加完了したときのイベント
Data Entry変更通知受信イベントは、メディアプレイヤーの操作を行うタイミングでしたね。最新のData Entryを取得するためData Feedの更新を行い、その更新完了を知るためにData Feed更新完了イベントも処理しています。
Data Entryの追加処理は非同期で行われますが、現在のライブラリではData Entryに対する追加・削除等の処理完了までその他のData Entryも操作ができないという嫌らしい仕様があります。Data Entryの追加が同時実行されないようData Entry追加完了のイベントも処理しています。
イベント処理の前にボタンクリック時の処理を変更します。クリック時に直接メディアファイルを再生していましたが、ここではPlayerCommandオブジェクトを作成しData Entryの値として設定します。そしてData Feedへ追加のみ行うよう変更します。
Data Entry追加時、追加処理が同時実行されないようにしています。追加完了時のイベント処理は次のようになります。
Data Entryが変更通知を受けとったとき、Data Feedの更新を行い、Data Feed更新完了後にData Entryを参照し、メディアプレイヤーの操作を処理します。
コーディングは以上です。ここまでを実行してみましょう。ボタンをクリックするとメディアファイルが再生されたでしょうか? 見た目からわかる動作は変化ありませんが、内部ではData Entryの追加とその変更通知を経てメディアファイルが再生されています。メディアプレイヤーを別のWebブラウザ等で開くと操作が同期されていることもわかります。
サンプルでは、Data Entryを追加するばかりで削除はしていません。実際にアプリケーションとして洗練させるには、より多くのData FeedやData Entryの管理が必要になります。
アプリケーションの共有
最後にアプリケーションの共有について紹介します。アプリケーションを共有するにはいくつかの方法があります。Mesh-enabled Webアプリケーションの場合、Mesh barからユーザーを招待する方法が最も簡単です。共有したいアプリケーションのMesh barのMemberから「Invite」をクリックし、招待したいユーザーのメールアドレスを入力します(図6)。
招待されたユーザーは図7のようなメールを受け取ります[1]。メール内のリンクからLive Framework Developer Sandboxへ移動し、アプリケーションのインストールが可能になります(図8)。
招待されたユーザーもLive Framework CTPの利用登録が完了している必要があります。
Mesh bar以外からの方法として、Azure Services Developer PortalのMesh-enabled Webアプリケーションのプロジェクト ページにある「Install URL」のアドレス(図9)をユーザーへ教え、アクセスしてもらうことでもアプリケーションをインストールできます。
アプリケーション開発時にはプロジェクトをデバッグ実行すると、最新のアプリケーションがLive Desktop上で表示されていたと思いますが、招待された別ユーザーが同じアプリケーションを起動すると古いバージョンのアプリケーションが表示されてしまうかもしれません。そのような場合には、もう一度Azure Services Developer Portalからアプリケーションパッケージをアップロードしてください(図9のUpload Packageボタンから)。
コードによる招待
Mesh-enabled Webアプリケーションの場合、以上で事足りると思いますが、本連載の第6回で作成したような.NET Frameworkによるクライアントアプリケーションの場合も簡単に補足しておきます。
Live Framework .NET KitやSilverlight Kitを使用している場合、Mesh Objectを共有するためにユーザーに招待メールを送信するメソッドが用意されています。.NET Kitの場合のコードを以下に示します。Silverlight Kitの場合も基本的に同じです。
招待はInvitationクラスとMemberクラスを使用します。Resource.PendingInvitationプロパティにInvitationオブジェクトを指定したMemberオブジェクトをMesh ObjectのMemberコレクションに追加すると招待メールが送信されます。
Invitationオブジェクトでは有効期限を設定し、Memberオブジェクトはメールアドレスのほか、アクセス許可の種類(コンストラクタ第2引数)とMesh Objectのオーナーか否か(第3引数)を指定可能です。
今回はここまでです。いかがでしたでしょうか。アプリケーションの共有は、今のところLive Framework CTPの利用が招待制のため手間が多いですが、自由に利用できるようになればアイデア次第でおもしろいアプリケーションが作れそうですね。