共有メディアプレイヤー
これまでも少し紹介したように、
今回作成するアプリケーションを図1に示します。フォルダ内のメディアファイルをボタンとして表示し、

複数ユーザーで実行した場合、
作成するメディアプレイヤーが参照するファイルはLive Meshフォルダ内の拡張子がwmaまたはwmvのファイルを参照するものとします。
前回に紹介したとおり、
メディアプレイヤーの作成
まずはメディアプレイヤーのUIやフォルダ参照部分を作成し、
それではSilverlight Mesh-enabled Web アプリケーションプロジェクトを作成しましょう。プロジェクトの作成と実行方法は第7回で紹介した通りです。そちらを参照してください。今回もVB.
フォルダとメディアファイルの準備
メディアプレイヤーの作成にあたり、
Live Framework Developer Sandboxにサインインして、

ちなみにこれらのメディアファイルはLive Desktop上で再生が可能になっています。
ファイル一覧の表示
Live Meshフォルダ内にあるファイルを取得し、
<Grid x:Name="LayoutRoot" Background="White">
<MediaElement x:Name="Player" Visibility="Collapsed" />
<ItemsControl x:Name="MediaListControl" Margin="5" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Margin="1" Click="Button_Click">
<Button.Content>
<StackPanel Orientation="Horizontal">
<Image Source="sound.png" Width="16" Height="16" VerticalAlignment="Center" Margin="2" />
<TextBlock Text="{Binding Title}" VerticalAlignment="Center" />
</StackPanel>
</Button.Content>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
メディアファイルの再生のためのMediaElementコントロール
コレクションの各アイテムの表示方法は<DataTemplate>に定義しています。Buttonコントロール内にImage、
続いてMesh上のLive Meshフォルダからメディアファイルを取得し、
' メディアファイル一覧表示
Private Sub ShowMediaList()
' ItemsControl アイテムクリア
MediaListControl.Items.Clear()
For Each mo In From m In meshApp.LiveOperatingEnvironment.Mesh.MeshObjects.Entries _
Where m.Resource.Type = "LiveMeshFolder"
' Live Mesh フォルダ一覧
Try
For Each df In From d In mo.DataFeeds.Entries _
Where d.Resource.Type = "LiveMeshFiles"
' Live Mesh ファイル一覧
' メディアファイルのみ取得
Dim medias = From de In df.DataEntries.Entries _
Where de.Resource.Type = "File" AndAlso _
(de.Resource.Title.ToUpper.EndsWith(".WMA") OrElse _
de.Resource.Title.ToUpper.EndsWith(".WMV"))
For Each m In medias
' ItemsControl に追加
MediaListControl.Items.Add(m.Resource)
Next
Next
Catch ex As InvalidOperationException
' Ignore
End Try
Next
End Sub
上記メソッドではMesh上のMesh ObjectからLive Meshフォルダであるものを探し、
このメソッドをアプリケーションロード時に呼び出すようmeshAppLoadedメソッド内に追記しておきましょう。
Private Sub meshAppLoaded(ByVal o As Object, ByVal e As EventArgs)
'Mesh application service object is now loaded and usable.
ShowMediaList()
End Sub
ボタンクリック時のイベント処理は、
Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
Dim button = DirectCast(sender, Button)
Dim resource = DirectCast(button.DataContext, DataEntryResource)
Player.Source = resource.EditMediaLink
Player.Play()
End Sub
引数のsenderオブジェクトからクリックされたボタンを取得し、
Live Meshフォルダのアクセス許可
ここまでを実行してみましょう。初回実行時のみ、
初めて実行する場合は、


アクセス許可設定後、
プレイヤー操作の同期
作成したメディアプレイヤーは、
操作の同期には、
Public Class PlayerCommand
Private _command As String =
Public Property Command() As String
Get
Return _command
End Get
Set(ByVal value As String)
_command = value
End Set
End Property
Private _argument As String =
Public Property Argument() As String
Get
Return _argument
End Get
Set(ByVal value As String)
_argument = value
End Set
End Property
End Class
Commandプロパティに
Data EntryはData Feed内に格納する必要があります。アプリケーション自身のData FeedコレクションにひとつのData Feedを用意し、
メディアファイルの再生などの処理は、
ここまでのメディアプレイヤー動作イメージを図5に示します。

- ユーザーの操作によりアプリケーションがData Entryを追加します。
- Data Entryの追加はすべてのアプリケーションに通知されます。
- 通知を受信したアプリケーションは最新のData Entryを参照します。
- 最後にプレイヤーに対する操作を実行します。
それではコードを書いていきましょう。まず、
Private Sub meshAppLoaded(ByVal o As Object, ByVal e As EventArgs)
'Mesh application service object is now loaded and usable.
If meshApp.DataFeeds.Entries.Count = 0 Then
' Data Feed がない場合
' Data Feed 追加完了時のイベント関連付け
AddHandler meshApp.DataFeeds.AddCompleted, AddressOf DataFeed_AddCompleted
' Data Feed の追加
Dim feed = New DataFeed("commands")
meshApp.DataFeeds.AddAsync(feed, Nothing)
Else
' その他イベント関連付け
AddHandlers()
End If
' ファイル一覧表示
ShowMediaList()
End Sub
追加処理は非同期のため追加完了時のイベントの関連付けを行っています。また、
' Data Feed 追加完了
Private Sub DataFeed_AddCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.AsyncCompletedEventArgs)
AddHandlers()
RemoveHandler meshApp.DataFeeds.AddCompleted, AddressOf DataFeed_AddCompleted
End Sub
' イベント関連付け
Private Sub AddHandlers()
' Data Feed 内の Data Entry の変更通知受信
AddHandler meshApp.DataFeeds.Entries.First.DataEntries.ChangeNotificationReceived, _
AddressOf DataEntries_ChangeNotificationReceived
' Data Feed を最新に更新完了
AddHandler meshApp.DataFeeds.Entries.First.UpdateCompleted, _
AddressOf DataFeed_UpdateCompleted
' Data Feed 内にData Entry を追加完了
AddHandler meshApp.DataFeeds.Entries.First.DataEntries.AddCompleted, _
AddressOf DataEntry_AddCompleted
End Sub
イベント関連付けは以下の3種類を処理しています。
- Data Feed内のData Entryの変更通知を受信したときのイベント
- Data Feedを最新に更新したときのイベント
- Data Feed内にData Entryを追加完了したときのイベント
Data Entry変更通知受信イベントは、
Data Entryの追加処理は非同期で行われますが、
イベント処理の前にボタンクリック時の処理を変更します。クリック時に直接メディアファイルを再生していましたが、
Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
Dim button = DirectCast(sender, Button)
Dim resource = DirectCast(button.DataContext, DataEntryResource)
'Player.Source = resource.EditMediaLink
'Player.Play()
' Data Entry 作成
Dim entry = New DataEntry
entry.Resource.SetUserData(Of PlayerCommand)( _
New PlayerCommand With { _
.Command = "play", _
.Argument = resource.EditMediaLink.ToString})
Try
Monitor.Enter(SyncObject)
' Data Entry 追加
meshApp.DataFeeds.Entries.First.DataEntries.AddAsync(entry, Nothing)
Catch ex As Exception
Monitor.Exit(SyncObject)
End Try
End Sub
Data Entry追加時、
' Data Entry 追加完了
Private Sub DataEntry_AddCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.AsyncCompletedEventArgs)
Monitor.Exit(SyncObject)
End Sub
Data Entryが変更通知を受けとったとき、
' Data Entry 変更通知受信
Private Sub DataEntries_ChangeNotificationReceived(ByVal sender As Object, ByVal e As EventArgs)
' Data Feed の更新
meshApp.DataFeeds.Entries.First.UpdateAsync(Nothing)
End Sub
' Data Feed 更新完了
Private Sub DataFeed_UpdateCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.AsyncCompletedEventArgs)
' 最新の Data Entry の取得
Dim entries = From entry In meshApp.DataFeeds.Entries.First.DataEntries.Entries _
Order By entry.Resource.PublishDate Descending
If entries.Count = 0 Then
Exit Sub
End If
' PlayerCommand オブジェクト取得
Dim command = entries.First.Resource.GetUserData(Of PlayerCommand)()
' メディアプレイヤーの操作実行
Select Case command.Command
Case "play"
Player.Source = New Uri(command.Argument)
Player.Play()
Case Else
' Do nothing
End Select
End Sub
コーディングは以上です。ここまでを実行してみましょう。ボタンをクリックするとメディアファイルが再生されたでしょうか? 見た目からわかる動作は変化ありませんが、
サンプルでは、
アプリケーションの共有
最後にアプリケーションの共有について紹介します。アプリケーションを共有するにはいくつかの方法があります。Mesh-enabled Webアプリケーションの場合、

招待されたユーザーは図7のようなメールを受け取ります


招待されたユーザーもLive Framework CTPの利用登録が完了している必要があります。
Mesh bar以外からの方法として、

アプリケーション開発時にはプロジェクトをデバッグ実行すると、
コードによる招待
Mesh-enabled Webアプリケーションの場合、
Live Framework .NET KitやSilverlight Kitを使用している場合、
' Invitation オブジェクトの作成
Dim invitation = New Invitation
Dim expiration = DateTimeOffset.UtcNow.AddDays(7) ' 招待の有効期限
invitation.Expires = expiration
' Member オブジェクトの作成
Dim newMember = New Member("[email protected]", RoleType.Full, False)
newMember.Resource.PendingInvitation = invitation
' メンバーの追加(招待)
meshObject.Members.Add(newMember)
招待はInvitationクラスとMemberクラスを使用します。Resource.
Invitationオブジェクトでは有効期限を設定し、
今回はここまでです。いかがでしたでしょうか。アプリケーションの共有は、