メディアのキャストMedia casting

この記事では、ユニバーサル Windows アプリからリモート デバイスにメディアをキャストする方法について説明します。This article shows you how to cast media to remote devices from a Universal Windows app.

MediaPlayerElement を使った組み込みのメディア キャスト機能Built-in media casting with MediaPlayerElement

ユニバーサル Windows アプリからメディアをキャストする方法としては、MediaPlayerElement コントロールの組み込みのキャスト機能を使うのが最も簡単です。The simplest way to cast media from a Universal Windows app is to use the built-in casting capability of the MediaPlayerElement control.

MediaPlayerElement コントロールで再生するビデオ ファイルをユーザーが開くことができるようにするには、以下の名前空間をプロジェクトに追加します。To allow the user to open a video file to be played in the MediaPlayerElement control, add the following namespaces to your project.

using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.Storage.Streams;
using Windows.Media.Core;

アプリの XAML ファイルに MediaPlayerElement を追加し、AreTransportControlsEnabled を true に設定します。In your app's XAML file, add a MediaPlayerElement and set AreTransportControlsEnabled to true.

<MediaPlayerElement Name="mediaPlayerElement"  MinHeight="100" MaxWidth="600" HorizontalAlignment="Stretch" AreTransportControlsEnabled="True"/>

ユーザーがファイルを選択するときに使うボタンを追加します。Add a button to let the user initiate picking a file.

<Button x:Name="openButton" Click="openButton_Click" Content="Open"/>

このボタンの Click イベント ハンドラーで FileOpenPicker の新しいインスタンスを作成し、ビデオ ファイルの種類を FileTypeFilter コレクションに追加して、開始位置をユーザーのビデオ ライブラリに設定します。In the Click event handler for the button, create a new instance of the FileOpenPicker, add video file types to the FileTypeFilter collection, and set the starting location to the user's videos library.

PickSingleFileAsync を呼び出して、ファイル ピッカー ダイアログを起動します。Call PickSingleFileAsync to launch the file picker dialog. このメソッドからは、ビデオ ファイルを表す StorageFile オブジェクトが返されます。When this method returns, the result is a StorageFile object representing the video file. ファイル選択操作をユーザーが取り消した場合は null が返されます。返されたファイルが null ではないことを確認してください。Check to make sure the file isn't null, which it will be if the user cancels the picking operation. ファイルの IRandomAccessStream を取得するには、そのファイルの OpenAsync メソッドを呼び出します。Call the file's OpenAsync method to get an IRandomAccessStream for the file. 最後に、CreateFromStorageFile を呼び出して選択したファイルから新しい MediaSource オブジェクトを作成し、そのオブジェクトを MediaPlayerElement オブジェクトの Source プロパティに割り当てて、そのビデオ ファイルをコントロールのビデオ ソースに設定します。Finally, create a new MediaSource object from the selected file by calling CreateFromStorageFile and assign it to the MediaPlayerElement object's Source property to make the video file the video source for the control.

private async void openButton_Click(object sender, RoutedEventArgs e)
{
    //Create a new picker
    FileOpenPicker filePicker = new FileOpenPicker();

    //Add filetype filters.  In this case wmv and mp4.
    filePicker.FileTypeFilter.Add(".wmv");
    filePicker.FileTypeFilter.Add(".mp4");

    //Set picker start location to the video library
    filePicker.SuggestedStartLocation = PickerLocationId.VideosLibrary;

    //Retrieve file from picker
    StorageFile file = await filePicker.PickSingleFileAsync();

    //If we got a file, load it into the media lement
    if (file != null)
    {
        mediaPlayerElement.Source = MediaSource.CreateFromStorageFile(file);
        mediaPlayerElement.MediaPlayer.Play();
    }
}

MediaPlayerElement にビデオを読み込んだら、ユーザーがトランスポート コントロールのキャスト ボタンを押すだけで、組み込みのダイアログを起動し、読み込まれているメディアのキャスト先となるデバイスを選択できます。Once the video is loaded in the MediaPlayerElement, the user can simply press the casting button on the transport controls to launch a built-in dialog that allows them to choose a device to which the loaded media will be cast.

mediaelement casting button

注意

Windows 10 バージョン 1607 以降、メディア項目の再生には、MediaPlayer クラスを使うことをお勧めします。Starting with Windows 10, version 1607, it is recommended that you use the MediaPlayer class to play media items. MediaPlayerElement は、XAML ページの MediaPlayer コンテンツをレンダリングするために使われる軽量の XAML コントロールです。The MediaPlayerElement is a lightweight XAML control that is used to render the content of a MediaPlayer in a XAML page. 下位互換性を確保するため、MediaElementコントロールも引き続きサポートされています。The MediaElement control continues to be supported for backwards compatibility. MediaPlayerMediaPlayerElement を使ってメディア コンテンツを再生する方法について詳しくは、「MediaPlayer を使ったオーディオとビデオの再生」をご覧ください。For more information on using MediaPlayer and MediaPlayerElement to play media content, see Play audio and video with MediaPlayer. MediaSource と関連の API を使ってメディア コンテンツを操作する方法について詳しくは、「メディア項目、プレイリスト、トラック」をご覧ください。For information on using MediaSource and related APIs to work with media content, see Media items, playlists, and tracks.

CastingDevicePicker を使ったメディアのキャストMedia casting with the CastingDevicePicker

メディアをデバイスにキャストするもう 1 つの方法は、CastingDevicePicker を使うことです。A second way to cast media to a device is to use the CastingDevicePicker. このクラスを使うには、プロジェクトに Windows.Media.Casting 名前空間を追加します。To use this class, include the Windows.Media.Casting namespace in your project.

using Windows.Media.Casting;

CastingDevicePicker オブジェクトのメンバー変数を宣言します。Declare a member variable for the CastingDevicePicker object.

CastingDevicePicker castingPicker;

対象のページが初期化されたタイミングで CastingDevicePicker の新しいインスタンスを作成します。さらに、ビデオをサポートするデバイスだけをキャスト先としてピッカーに一覧表示するために、FilterSupportsVideo プロパティに設定します。When you page is initialized, create a new instance of the casting picker and set the Filter to SupportsVideo property to indicate that the casting devices listed by the picker should support video. CastingDeviceSelected イベントのハンドラーを登録します。これは、ユーザーがキャスト先のデバイスを選んだときに発生するイベントです。Register a handler for the CastingDeviceSelected event, which is raised when the user picks a device for casting.

//Initialize our picker object
castingPicker = new CastingDevicePicker();

//Set the picker to filter to video capable casting devices
castingPicker.Filter.SupportsVideo = true;

//Hook up device selected event
castingPicker.CastingDeviceSelected += CastingPicker_CastingDeviceSelected;

ユーザーがピッカーを起動するためのボタンを XAML ファイルに追加します。In your XAML file, add a button to allow the user to launch the picker.

<Button x:Name="castPickerButton" Content="Cast Button" Click="castPickerButton_Click"/>

ボタンの Click イベント ハンドラーで TransformToVisual を呼び出し、別の要素を基準とした UI 要素の変換を取得します。In the Click event handler for the button, call TransformToVisual to get the transform of a UI element relative to another element. この例の変換は、アプリケーション ウィンドウの表示ルートを基準としたキャスト ピッカー ボタンの位置です。In this example, the transform is the position of the cast picker button relative to the visual root of the application window. CastingDevicePicker オブジェクトの Show メソッドを呼び出して、キャスト先の選択ダイアログを起動します。Call the Show method of the CastingDevicePicker object to launch the casting picker dialog. ユーザーによって押されたボタンから飛び出すようにダイアログを表示させるため、キャスト ピッカー ボタンの位置とサイズを指定します。Specify the location and dimensions of the cast picker button so that the system can make the dialog fly out from the button that the user pressed.

private void castPickerButton_Click(object sender, RoutedEventArgs e)
{
    //Retrieve the location of the casting button
    GeneralTransform transform = castPickerButton.TransformToVisual(Window.Current.Content as UIElement);
    Point pt = transform.TransformPoint(new Point(0, 0));

    //Show the picker above our casting button
    castingPicker.Show(new Rect(pt.X, pt.Y, castPickerButton.ActualWidth, castPickerButton.ActualHeight),
        Windows.UI.Popups.Placement.Above);
}

CastingDeviceSelected イベント ハンドラーで、イベント引数の SelectedCastingDevice プロパティ (ユーザーが選択したキャスト先デバイスを表す) の CreateCastingConnection メソッドを呼び出します。In the CastingDeviceSelected event handler, call the CreateCastingConnection method of the SelectedCastingDevice property of the event args, which represents the casting device selected by the user. ErrorOccurred イベントと StateChanged イベントのハンドラーを登録します。Register handlers for the ErrorOccurred and StateChanged events. 最後に、RequestStartCastingAsync を呼び出すとキャストが開始されます。キャストするメディアが MediaPlayerElement に関連付けられた MediaPlayer のコンテンツであることを指定するために、このメソッドの引数には、MediaPlayerElement コントロールの MediaPlayer オブジェクトの GetAsCastingSource メソッドの結果を渡します。Finally, call RequestStartCastingAsync to begin casting, passing in the result to the MediaPlayerElement control's MediaPlayer object's GetAsCastingSource method to specify that the media to be cast is the content of the MediaPlayer associated with the MediaPlayerElement.

注意

キャスト接続は UI スレッドで開始する必要があります。The casting connection must be initiated on the UI thread. CastingDeviceSelected は UI スレッドでは呼び出されないため、上に挙げた一連の呼び出しを、CoreDispatcher.RunAsync の呼び出しの中に置いて、UI スレッドで呼び出されるようにする必要があります。Since the CastingDeviceSelected is not called on the UI thread, you must place these calls inside a call to CoreDispatcher.RunAsync which causes them to be called on the UI thread.

private async void CastingPicker_CastingDeviceSelected(CastingDevicePicker sender, CastingDeviceSelectedEventArgs args)
{
    //Casting must occur from the UI thread.  This dispatches the casting calls to the UI thread.
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
    {
        //Create a casting conneciton from our selected casting device
        CastingConnection connection = args.SelectedCastingDevice.CreateCastingConnection();

        //Hook up the casting events
        connection.ErrorOccurred += Connection_ErrorOccurred;
        connection.StateChanged += Connection_StateChanged;

        //Cast the content loaded in the media element to the selected casting device
        await connection.RequestStartCastingAsync(mediaPlayerElement.MediaPlayer.GetAsCastingSource());
    });
}

ErrorOccurred イベントと StateChanged イベントのハンドラーでは、UI を更新して、現在のキャスト ステータスをユーザーに通知する必要があります。In the ErrorOccurred and StateChanged event handlers, you should update your UI to inform the user of the current casting status. これらのイベントについては、次のセクションで、カスタムのキャスト先デバイス ピッカーを作成する方法の中で詳しく説明します。These events are discussed in detail in the following section on creating a custom casting device picker.

private async void Connection_StateChanged(CastingConnection sender, object args)
{
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
    {
        ShowMessageToUser("Casting Connection State Changed: " + sender.State);
    });
}

private async void Connection_ErrorOccurred(CastingConnection sender, CastingConnectionErrorOccurredEventArgs args)
{
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
    {
        ShowMessageToUser("Casting Connection State Changed: " + sender.State);
    });
}

カスタム デバイス ピッカーを使ったメディアのキャストMedia casting with a custom device picker

次のセクションでは、独自のコードでキャスト先デバイスを列挙し、接続を開始することによって、キャスト先デバイス ピッカーの UI を作成する方法を説明します。The following section describes how to create your own casting device picker UI by enumerating the casting devices and initiating the connection from your code.

利用可能なキャスト先デバイスを列挙するには、Windows.Devices.Enumeration 名前空間をプロジェクトに追加します。To enumerate the available casting devices, include the Windows.Devices.Enumeration namespace in your project.

using Windows.Devices.Enumeration;

この例の基本的な UI を実装するために、以下のコントロールを XAML ページに追加します。Add the following controls to your XAML page to implement the rudimentary UI for this example:

  • 利用可能なキャスト先デバイスを探すデバイス ウォッチャーの起動ボタン。A button to start the device watcher that looks for available casting devices.
  • キャスト先を列挙する処理の進行状況をユーザーにフィードバックする ProgressRing コントロール。A ProgressRing control to provide feedback to the user that casting enumeration is ongoing.
  • 検出されたキャスト先デバイスを一覧表示する ListBoxA ListBox to list the discovered casting devices. キャスト先デバイス オブジェクトを直接コントロールに割り当てたうえで、さらに FriendlyName プロパティを表示できるようにコントロールの ItemTemplate を定義します。Define an ItemTemplate for the control so that we can assign the casting device objects directly to the control and still display the FriendlyName property.
  • キャスト先デバイスとの接続をユーザーが切断するためのボタン。A button to allow the user to disconnect the casting device.
<Button x:Name="startWatcherButton" Content="Watcher Button" Click="startWatcherButton_Click"/>
<ProgressRing x:Name="watcherProgressRing" IsActive="False"/>
<ListBox x:Name="castingDevicesListBox" MaxWidth="300" HorizontalAlignment="Left" SelectionChanged="castingDevicesListBox_SelectionChanged">
    <!--Listbox content is bound to the FriendlyName field of our casting devices-->
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=FriendlyName}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
<Button x:Name="disconnectButton" Content="Disconnect" Click="disconnectButton_Click" Visibility="Collapsed"/>

分離コードには、DeviceWatcherCastingConnection のメンバー変数を宣言します。In your code behind, declare member variables for the DeviceWatcher and the CastingConnection.

DeviceWatcher deviceWatcher;
CastingConnection castingConnection;

startWatcherButtonClick ハンドラーでまず行うのは UI の更新です。デバイスの列挙中はボタンを無効にし、プログレス リングをアクティブにします。In the Click handler for the startWatcherButton, first update the UI by disabling the button and making the progress ring active while device enumeration is ongoing. キャスト先デバイスのリスト ボックスをクリアします。Clear the list box of casting devices.

次に、DeviceInformation.CreateWatcher を呼び出してデバイス ウォッチャーを作成します。Next, create a device watcher by calling DeviceInformation.CreateWatcher. このメソッドを使うと、さまざまな種類のデバイスを監視することができます。This method can be used to watch for many different types of devices. ビデオ キャストに対応しているデバイスを監視対象として指定するには、CastingDevice.GetDeviceSelector から返されるデバイスのセレクター文字列を使います。Specify that you want to watch for devices that support video casting by using the device selector string returned by CastingDevice.GetDeviceSelector.

最後に、AddedRemovedEnumerationCompletedStopped の各イベントのハンドラーを登録します。Finally, register event handlers for the Added, Removed, EnumerationCompleted, and Stopped events.

private void startWatcherButton_Click(object sender, RoutedEventArgs e)
{
    startWatcherButton.IsEnabled = false;
    watcherProgressRing.IsActive = true;

    castingDevicesListBox.Items.Clear();

    //Create our watcher and have it find casting devices capable of video casting
    deviceWatcher = DeviceInformation.CreateWatcher(CastingDevice.GetDeviceSelector(CastingPlaybackTypes.Video));

    //Register for watcher events
    deviceWatcher.Added += DeviceWatcher_Added;
    deviceWatcher.Removed += DeviceWatcher_Removed;
    deviceWatcher.EnumerationCompleted += DeviceWatcher_EnumerationCompleted;
    deviceWatcher.Stopped += DeviceWatcher_Stopped;

    //Start the watcher
    deviceWatcher.Start();
}

Added は、ウォッチャーで新しいデバイスが検出されたときに発生するイベントです。The Added event is raised when a new device is discovered by the watcher. このイベントのハンドラーで CastingDevice.FromIdAsync を呼び出して新しい CastingDevice オブジェクトを作成します。このメソッドの引数には、検出されたキャスト先デバイスの ID を指定します。ID は、ハンドラーに渡された DeviceInformation オブジェクトに格納されています。In the handler for this event, create a new CastingDevice object by calling CastingDevice.FromIdAsync and passing in the ID of the discovered casting device, which is contained in the DeviceInformation object passed into the handler.

この CastingDevice をキャスト先デバイスの ListBox に追加して、ユーザーが選択できるようにします。Add the CastingDevice to the casting device ListBox so that the user can select it. リスト ボックスの項目テキストには、XAML で定義した ItemTemplate により、FriendlyName プロパティが使われます。Because of the ItemTemplate defined in the XAML, the FriendlyName property will be used as the item text for in the list box. このイベント ハンドラーは UI スレッドで呼び出されないため、UI の更新は、CoreDispatcher.RunAsync の呼び出しの中で行う必要があります。Because this event handler is not called on the UI thread, you must update the UI from within a call to CoreDispatcher.RunAsync.

private async void DeviceWatcher_Added(DeviceWatcher sender, DeviceInformation args)
{
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
    {
        //Add each discovered device to our listbox
        CastingDevice addedDevice = await CastingDevice.FromIdAsync(args.Id);
        castingDevicesListBox.Items.Add(addedDevice);
    });
}

キャスト先デバイスがもう存在しないことをウォッチャーが検出すると、Removed イベントが発生します。The Removed event is raised when the watcher detects that a casting device is no longer present. ハンドラーに渡された Added オブジェクトの ID プロパティと、リスト ボックスの Items コレクションに含まれている各 Added の ID とを比較します。Compare the ID property of the Added object passed into the handler to the ID of each Added in the list box's Items collection. ID が一致する場合は、そのオブジェクトをコレクションから削除します。If the ID matches, remove that object from the collection. UI が更新中であるため、先ほどと同様、この呼び出しは RunAsync の呼び出しの中で行う必要があります。Again, because the UI is being updated, this call must be made from within a RunAsync call.

private async void DeviceWatcher_Removed(DeviceWatcher sender, DeviceInformationUpdate args)
{
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
    {
        foreach (CastingDevice currentDevice in castingDevicesListBox.Items)
        {
            if (currentDevice.Id == args.Id)
            {
                castingDevicesListBox.Items.Remove(currentDevice);
            }
        }
    });
}

ウォッチャーがデバイスの検出を完了すると、EnumerationCompleted イベントが発生します。The EnumerationCompleted event is raised when the watcher has finished detecting devices. このイベントのハンドラーで UI を更新して、デバイスの列挙処理が完了したことをユーザーに知らせ、Stop を呼び出してデバイス ウォッチャーを停止します。In the handler for this event, update the UI to let the user know that device enumeration has completed and stop the device watcher by calling Stop.

private async void DeviceWatcher_EnumerationCompleted(DeviceWatcher sender, object args)
{
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
    {
        //If enumeration completes, update UI and transition watcher to the stopped state
        ShowMessageToUser("Watcher completed enumeration of devices");
        deviceWatcher.Stop();
    });
}

デバイス ウォッチャーの停止処理が完了すると Stopped イベントが発生します。The Stopped event is raised when the device watcher has finished stopping. このイベントのハンドラーで ProgressRing コントロールを停止したうえで、デバイス列挙処理をユーザーが再開できるように startWatcherButton を再び有効にします。In the handler for this event, stop the ProgressRing control and reenable the startWatcherButton so that the user can restart the device enumeration process.

private async void DeviceWatcher_Stopped(DeviceWatcher sender, object args)
{
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
    {
        //Update UX when the watcher stops
        startWatcherButton.IsEnabled = true;
        watcherProgressRing.IsActive = false;
    });
}

リスト ボックスからいずれかのキャスト先デバイスをユーザーが選択すると、SelectionChanged イベントが発生します。When the user selects one of the casting devices from the list box, the SelectionChanged event is raised. このハンドラーの中でキャスト接続を作成し、キャストを開始することになります。It is within this handler that the casting connection will be created and casting will be started.

まず、デバイスの列挙処理がメディアのキャスト処理に干渉しないよう、デバイス ウォッチャーが停止していることを確認します。First, make sure the device watcher is stopped so that device enumeration doesn't interfere with media casting. キャスト接続を作成するには、ユーザーが選択した CastingDevice オブジェクトの CreateCastingConnection を呼び出します。Create a casting connection by calling CreateCastingConnection on the CastingDevice object selected by the user. StateChanged イベントおよび ErrorOccurred イベントに対応するイベント ハンドラーを追加します。Add event handlers for the StateChanged and ErrorOccurred events.

メディアのキャストを開始するには、RequestStartCastingAsync を呼び出します。その際、引数には、MediaPlayerGetAsCastingSource メソッドを呼び出して取得したキャスト ソースを指定します。Start media casting by calling RequestStartCastingAsync, passing in the casting source returned by calling the MediaPlayer method GetAsCastingSource. 最後に、メディアのキャストをユーザーが停止するための切断ボタンを表示状態にします。Finally, make the disconnect button visible to allow the user to stop media casting.

private async void castingDevicesListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (castingDevicesListBox.SelectedItem != null)
    {
        //When a device is selected, first thing we do is stop the watcher so it's search doesn't conflict with streaming
        if (deviceWatcher.Status != DeviceWatcherStatus.Stopped)
        {
            deviceWatcher.Stop();
        }

        //Create a new casting connection to the device that's been selected
        castingConnection = ((CastingDevice)castingDevicesListBox.SelectedItem).CreateCastingConnection();

        //Register for events
        castingConnection.ErrorOccurred += Connection_ErrorOccurred;
        castingConnection.StateChanged += Connection_StateChanged;

        //Cast the loaded video to the selected casting device.
        await castingConnection.RequestStartCastingAsync(mediaPlayerElement.MediaPlayer.GetAsCastingSource());
        disconnectButton.Visibility = Visibility.Visible;
    }
}

StateChanged ハンドラーで実行する操作は、キャスト接続の新しい状態によって異なります。In the state changed handler, the action you take depends on the new state of the casting connection:

  • 状態が Connected または Rendering である場合は、ProgressRing コントロールを非アクティブにし、切断ボタンを表示します。If the state is Connected or Rendering, make sure the ProgressRing control is inactive and the disconnect button is visible.
  • 状態が Disconnected である場合は、現在のキャスト先デバイスの選択をリスト ボックスで解除し、ProgressRing コントロールを非アクティブにして、切断ボタンを非表示にします。If the state is Disconnected, unselect the current casting device in the list box, make the ProgressRing control inactive, and hide the disconnect button.
  • 状態が Connecting である場合は、ProgressRing コントロールをアクティブにして、切断ボタンを非表示にします。If the state is Connecting, make the ProgressRing control active and hide the disconnect button.
  • 状態が Disconnecting である場合は、ProgressRing コントロールをアクティブにして、切断ボタンを非表示にします。If the state is Disconnecting, make the ProgressRing control active and hide the disconnect button.
private async void Connection_StateChanged(CastingConnection sender, object args)
{
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
    {
        //Update the UX based on the casting state
        if (sender.State == CastingConnectionState.Connected || sender.State == CastingConnectionState.Rendering)
        {
            disconnectButton.Visibility = Visibility.Visible;
            watcherProgressRing.IsActive = false;
        }
        else if (sender.State == CastingConnectionState.Disconnected)
        {
            disconnectButton.Visibility = Visibility.Collapsed;
            castingDevicesListBox.SelectedItem = null;
            watcherProgressRing.IsActive = false;
        }
        else if (sender.State == CastingConnectionState.Connecting)
        {
            disconnectButton.Visibility = Visibility.Collapsed;
            ShowMessageToUser("Connecting");
            watcherProgressRing.IsActive = true;
        }
        else
        {
            //Disconnecting is the remaining state
            disconnectButton.Visibility = Visibility.Collapsed;
            watcherProgressRing.IsActive = true;
        }
    });
}

ErrorOccurred イベントのハンドラーでは、UI を更新してキャスト エラーの発生をユーザーに知らせると共に、リスト ボックスで現在の CastingDevice オブジェクトの選択を解除します。In the handler for the ErrorOccurred event, update your UI to let the user know that a casting error occurred and unselect the current CastingDevice object in the list box.

private async void Connection_ErrorOccurred(CastingConnection sender, CastingConnectionErrorOccurredEventArgs args)
{
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
    {
        //Clear the selection in the listbox on an error
        ShowMessageToUser("Casting Error: " + args.Message);
        castingDevicesListBox.SelectedItem = null;
    });
}

最後に、切断ボタンのハンドラーを実装します。Finally, implement the handler for the disconnect button. メディアのキャストを停止してキャスト先デバイスから切断するために、CastingConnection オブジェクトの DisconnectAsync メソッドを呼び出します。Stop media casting and disconnect from the casting device by calling the CastingConnection object's DisconnectAsync method. この呼び出しは、CoreDispatcher.RunAsync を呼び出して UI スレッドにディスパッチする必要があります。This call must be dispatched to the UI thread by calling CoreDispatcher.RunAsync.

private async void disconnectButton_Click(object sender, RoutedEventArgs e)
{
    if (castingConnection != null)
    {
        //When disconnect is clicked, the casting conneciton is disconnected.  The video should return locally to the media element.
        await castingConnection.DisconnectAsync();
    }
}