PlayToを使って、リモートでメディアを再生

Windows 8のWinRT APIが提供するUI部品には、MediaElementという部品があります。音ファイルや動画ファイル、写真ファイルを表示する部品です。

XAMLでメディアを再生するには、

    <MediaElement x:Name="mediaElem" Souce="ファイルのURI"/>

と書けば、簡単に再生可能です。この部品は、単にメディアファイルを再生するだけではなく、https://msdn.microsoft.com/ja-jp/library/windows/apps/windows.media.playto.aspx に書いてあるように、

「リモート再生を使用すると、ユーザーは自分のコンピューターのオーディオ、ビデオ、またはイメージを、簡単にホーム ネットワークのデバイスにストリーム転送できます。たとえば、アプリケーションでビデオを再生しているユーザーは、そのビデオを自分のテレビにストリームできるため、室内のすべてのユーザーがそのビデオを見ることができます。」

なんていう素敵な機能がついているんです。これを使わない手はありません。XAMLのページに<MediaElement../>タグを書いて、そのコードビハインドのC#コードのページのクラスに、

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            var prayToManager = PlayToManager.GetForCurrentView();
            prayToManager.SourceRequested += new TypedEventHandler<PlayToManager, PlayToSourceRequestedEventArgs>(prayToManager_SourceRequested);
            base.OnNavigatedTo(e);
        }

を追加します。OnNavigatedToメソッドは、このページにナビゲートされて表示されるときにコールされるメソッドです。PlayToManagerというクラスは、Windows.Media.PlayTo名前空間に属する、リモート再生にかかわるライブラリです。上のコードでは、カレントのビューに付随しているPlayToManagerインスタンスを取得して、リモート再生要求があった時にコールされるハンドラ、playToManager_SourceRequestedメソッドを登録しています。

このページが表示されている状態で、デバイスチャームからリモートディスプレイを指定すると、prayToManager_SourceRequestedメソッドがコールされます。このメソッドでやることの基本は、以下の通り。

        async void prayToManager_SourceRequested(PlayToManager sender, PlayToSourceRequestedEventArgs args)
        {
            await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
            {
                var deferal = args.SourceRequest.GetDeferral();
                args.SourceRequest.SetSource(mediaElem.PlayToSource);
                deferal.Complete();
            });
        }

これで、要求があった時にMediaElementで表示されているメディアがリモート再生されるっていうすんぽうです。…あ、Playと書くべきところがPrayになっている…ま、Windows 8 ストアアプリの普及を願っている心が思わず出てしまったということでご勘弁。

この機能を使ったとてもシンプルなアプリを一個ストアに申請してみました。https://apps.microsoft.com/windows/app/00bc3a21-cd8b-427f-be1d-b7f792551327 額縁プレーヤーというアプリです。

MediaElement自体は、動画再生時のPauseとか再生位置指定とかのUIが無いので、https://playerframework.codeplex.com/ から公開されている、Microsoft Player Frameworkを使っています。このフレームワークでは、MediaElementを拡張した、MediaPlayerっつうクラスが提供されているので、MediaElementの代わりにこのクラスを使います。XAML上で置き換えれば、この投稿で紹介したコードはそのまま使えるので、試してみてください。