Quickstart: Creating a Play To Receiver (XAML)
[ This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation ]
You can create a software Play To receiver that receives media streamed from a client computer and plays or displays the content as part of your app. This topic shows you how to create a Windows Store app that advertises itself on your local network as a Digital Media Renderer, receives video media from another computer, plays that video, and responds to additional commands from the client computer such as volume changes, playback location changes, and so on.
Prerequisites
Microsoft Visual Studio
Create a new project and enable access to Pictures
- Open Visual Studio and select New Project from the File menu. In the Visual C# or Visual Basic section, select Blank Application. Name the application PlayToReceiverSample and click OK.
- Open the package.appxmanifest file and select the Capabilities tab. Select the Home or Work Networking capability to enable your application to connect to other computers within your local network. Close and save the manifest file.
Add XAML UI
Open the MainPage.xaml file and add the following to the default Grid element.
<Button x:Name="StartReceiverButton" Content="Start Play To Receiver" Margin="283,26,0,703" Click="StartReceiverButton_Click" />
<Button x:Name="StopReceiverButton" Content="Stop Play To Receiver" Margin="907,26,0,703" Click="StopReceiverButton_Click" />
<MediaElement x:Name="VideoPlayer" Height="600" Width="800" Source="" />
<TextBlock x:Name="StatusTextBlock" Height="60" Width="800" Foreground="Green" Margin="283,689,283,19" />
Add button event handlers
The code in this step defines the event handlers for the start and stop buttons. During the event handler for the start button, the code creates an instance of the PlayToReceiver class that is the Play To receiver for the app. After the code creates the Play To receiver instance, it then associates event handlers with the Play To receiver events. These events are raised when an action is requested by the Play To client computer. These actions include receiving the source media, which raises the SourceChangeRequested event, and requests to pause, continue, or stop playing the media, change the volume level, mute, or un-mute the audio, change the media playback rate or change the playback location time. Each action has a respective event.
After the event handlers are added, the app sets the FriendlyName property of the Play To receiver that identifies the name of the Play To receiver as it is seen on the network, and the properties that show that this Play To receiver only supports video.
After the Play To receiver has been initialized, the app associates event handlers for the HTML5 video tag. These events are raised when an action occurs for the video tag that is included in the app. When these events occur, the event handler calls a notify method of the Play To receiver to inform the Play To client of the action. For example, when the media finishes playing, the ended event of the video tag is raised. During the event handler for the ended event, the code calls the NotifyEnded event of the Play To receiver to inform the client computer that the video has finished.
After both the Play To receiver and the video tag have been initialized, the code in the start button handler calls the StartAsync method to advertise the app as a Digital Media Renderer on the local network. The app also gets a reference to the active display window to prevent the screen from locking.
In the event handler for the stop button, the code calls the StopAsync button to stop advertizing the Play To receiver, releases the reference to the active display window, and removes the event handlers for the Play To receiver and video tag.
Open the MainPage.xaml.cs or MainPage.xaml.vb file and add the following code to the MainPage class.
Windows.Media.PlayTo.PlayToReceiver receiver;
Windows.System.Display.DisplayRequest display;
Windows.UI.Core.CoreDispatcher dispatcher;
bool seeking = false;
private async void StartReceiverButton_Click(object sender, RoutedEventArgs e)
{
try
{
dispatcher = Window.Current.CoreWindow.Dispatcher;
if (receiver == null)
{
receiver = new Windows.Media.PlayTo.PlayToReceiver();
}
// Add Play To Receiver events and properties
receiver.CurrentTimeChangeRequested += receiver_CurrentTimeChangeRequested;
receiver.MuteChangeRequested += receiver_MuteChangeRequested;
receiver.PauseRequested += receiver_PauseRequested;
receiver.PlaybackRateChangeRequested += receiver_PlaybackRateChangeRequested;
receiver.PlayRequested += receiver_PlayRequested;
receiver.SourceChangeRequested += receiver_SourceChangeRequested;
receiver.StopRequested += receiver_StopRequested;
receiver.TimeUpdateRequested += receiver_TimeUpdateRequested;
receiver.VolumeChangeRequested += receiver_VolumeChangeRequested;
receiver.FriendlyName = "Sample Play To Receiver";
receiver.SupportsAudio = false;
receiver.SupportsVideo = true;
receiver.SupportsImage = false;
// Add MediaElement events
VideoPlayer.CurrentStateChanged += VideoPlayer_CurrentStateChanged;
VideoPlayer.MediaEnded += VideoPlayer_MediaEnded;
VideoPlayer.MediaFailed += VideoPlayer_MediaFailed;
VideoPlayer.MediaOpened += VideoPlayer_MediaOpened;
VideoPlayer.RateChanged += VideoPlayer_RateChanged;
VideoPlayer.SeekCompleted += VideoPlayer_SeekCompleted;
VideoPlayer.VolumeChanged += VideoPlayer_VolumeChanged;
// Advertise the receiver on the local network and start receiving commands
await receiver.StartAsync();
// Prevent the screen from locking
if (display == null)
display = new Windows.System.Display.DisplayRequest();
display.RequestActive();
StatusTextBlock.Text = "'" + receiver.FriendlyName + "' started.";
}
catch
{
receiver = null;
StatusTextBlock.Text = "Failed to start receiver.";
}
}
private async void StopReceiverButton_Click(object sender, RoutedEventArgs e)
{
try
{
if (receiver != null)
{
await receiver.StopAsync();
if (display != null)
display.RequestRelease();
// Remove Play To Receiver events
receiver.CurrentTimeChangeRequested -= receiver_CurrentTimeChangeRequested;
receiver.MuteChangeRequested -= receiver_MuteChangeRequested;
receiver.PauseRequested -= receiver_PauseRequested;
receiver.PlaybackRateChangeRequested -= receiver_PlaybackRateChangeRequested;
receiver.PlayRequested -= receiver_PlayRequested;
receiver.SourceChangeRequested -= receiver_SourceChangeRequested;
receiver.StopRequested -= receiver_StopRequested;
receiver.TimeUpdateRequested -= receiver_TimeUpdateRequested;
receiver.VolumeChangeRequested -= receiver_VolumeChangeRequested;
// Remove MediaElement events
VideoPlayer.Pause();
VideoPlayer.CurrentStateChanged -= VideoPlayer_CurrentStateChanged;
VideoPlayer.MediaEnded -= VideoPlayer_MediaEnded;
VideoPlayer.MediaFailed -= VideoPlayer_MediaFailed;
VideoPlayer.MediaOpened -= VideoPlayer_MediaOpened;
VideoPlayer.RateChanged -= VideoPlayer_RateChanged;
VideoPlayer.SeekCompleted -= VideoPlayer_SeekCompleted;
VideoPlayer.VolumeChanged -= VideoPlayer_VolumeChanged;
StatusTextBlock.Text = "Stopped '" + receiver.FriendlyName + "'.";
}
}
catch
{
StatusTextBlock.Text = "Failed to stop '" + receiver.FriendlyName + "'.";
}
}
Private receiver As Windows.Media.PlayTo.PlayToReceiver
Private display As Windows.System.Display.DisplayRequest
Private seeking As Boolean = False
Private Async Sub StartReceiverButton_Click()
Try
If receiver Is Nothing Then
receiver = New Windows.Media.PlayTo.PlayToReceiver()
End If
' Add Play To Receiver events and properties
AddHandler receiver.CurrentTimeChangeRequested, AddressOf receiver_CurrentTimeChangeRequested
AddHandler receiver.MuteChangeRequested, AddressOf receiver_MuteChangeRequested
AddHandler receiver.PauseRequested, AddressOf receiver_PauseRequested
AddHandler receiver.PlaybackRateChangeRequested, AddressOf receiver_PlaybackRateChangeRequested
AddHandler receiver.PlayRequested, AddressOf receiver_PlayRequested
AddHandler receiver.SourceChangeRequested, AddressOf receiver_SourceChangeRequested
AddHandler receiver.StopRequested, AddressOf receiver_StopRequested
AddHandler receiver.TimeUpdateRequested, AddressOf receiver_TimeUpdateRequested
AddHandler receiver.VolumeChangeRequested, AddressOf receiver_VolumeChangeRequested
receiver.FriendlyName = "Sample Play To Receiver"
receiver.SupportsAudio = False
receiver.SupportsVideo = True
receiver.SupportsImage = False
' Add MediaElement events
AddHandler VideoPlayer.CurrentStateChanged, AddressOf VideoPlayer_CurrentStateChanged
AddHandler VideoPlayer.MediaEnded, AddressOf VideoPlayer_MediaEnded
AddHandler VideoPlayer.MediaFailed, AddressOf VideoPlayer_MediaFailed
AddHandler VideoPlayer.MediaOpened, AddressOf VideoPlayer_MediaOpened
AddHandler VideoPlayer.RateChanged, AddressOf VideoPlayer_RateChanged
AddHandler VideoPlayer.SeekCompleted, AddressOf VideoPlayer_SeekCompleted
AddHandler VideoPlayer.VolumeChanged, AddressOf VideoPlayer_VolumeChanged
' Advertise the receiver on the local network and start receiving commands
Await receiver.StartAsync()
' Prevent the screen from locking
If display Is Nothing Then
display = New Windows.System.Display.DisplayRequest()
display.RequestActive()
StatusTextBlock.Text = "'" & receiver.FriendlyName & "' started."
End If
Catch
receiver = Nothing
StatusTextBlock.Text = "Failed to start receiver. "
End Try
End Sub
Private Async Sub StopReceiverButton_Click()
Try
If receiver IsNot Nothing Then
Await receiver.StopAsync()
If display IsNot Nothing Then display.RequestRelease()
' Remove Play To Receiver events
RemoveHandler receiver.CurrentTimeChangeRequested, AddressOf receiver_CurrentTimeChangeRequested
RemoveHandler receiver.MuteChangeRequested, AddressOf receiver_MuteChangeRequested
RemoveHandler receiver.PauseRequested, AddressOf receiver_PauseRequested
RemoveHandler receiver.PlaybackRateChangeRequested, AddressOf receiver_PlaybackRateChangeRequested
RemoveHandler receiver.PlayRequested, AddressOf receiver_PlayRequested
RemoveHandler receiver.SourceChangeRequested, AddressOf receiver_SourceChangeRequested
RemoveHandler receiver.StopRequested, AddressOf receiver_StopRequested
RemoveHandler receiver.TimeUpdateRequested, AddressOf receiver_TimeUpdateRequested
RemoveHandler receiver.VolumeChangeRequested, AddressOf receiver_VolumeChangeRequested
' Remove MediaElement events
VideoPlayer.Pause()
RemoveHandler VideoPlayer.CurrentStateChanged, AddressOf VideoPlayer_CurrentStateChanged
RemoveHandler VideoPlayer.MediaEnded, AddressOf VideoPlayer_MediaEnded
RemoveHandler VideoPlayer.MediaFailed, AddressOf VideoPlayer_MediaFailed
RemoveHandler VideoPlayer.MediaOpened, AddressOf VideoPlayer_MediaOpened
RemoveHandler VideoPlayer.RateChanged, AddressOf VideoPlayer_RateChanged
RemoveHandler VideoPlayer.SeekCompleted, AddressOf VideoPlayer_SeekCompleted
RemoveHandler VideoPlayer.VolumeChanged, AddressOf VideoPlayer_VolumeChanged
StatusTextBlock.Text = "Stopped '" & receiver.FriendlyName & "'."
End If
Catch
StatusTextBlock.Text = "Failed to stop '" & receiver.FriendlyName & "'."
End Try
End Sub
Add Play To receiver event handlers
The code in this step adds the code for the Play To receiver event handlers. These event handlers are called in response to requests from the Play To client computer. For example, if the Play To client computer mutes or un-mutes the volume, then the MuteChangeRequested event is raised. In the associated event handler, the app mutes or un-mutes the local video tag in response to the request.
Add the following code to the MainPage.xaml.cs or MainPage.xaml.vb file and after the code from the previous step.
async void receiver_CurrentTimeChangeRequested(
Windows.Media.PlayTo.PlayToReceiver sender,
Windows.Media.PlayTo.CurrentTimeChangeRequestedEventArgs args)
{
await dispatcher.RunAsync(
Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
VideoPlayer.Position = args.Time;
receiver.NotifySeeking();
seeking = true;
});
}
async void receiver_MuteChangeRequested(
Windows.Media.PlayTo.PlayToReceiver sender,
Windows.Media.PlayTo.MuteChangeRequestedEventArgs args)
{
await dispatcher.RunAsync(
Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
VideoPlayer.IsMuted = args.Mute;
});
}
async void receiver_PauseRequested(
Windows.Media.PlayTo.PlayToReceiver sender,
object args)
{
await dispatcher.RunAsync(
Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
VideoPlayer.Pause();
});
}
async void receiver_PlaybackRateChangeRequested(
Windows.Media.PlayTo.PlayToReceiver sender,
Windows.Media.PlayTo.PlaybackRateChangeRequestedEventArgs args)
{
await dispatcher.RunAsync(
Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
VideoPlayer.PlaybackRate = args.Rate;
});
}
async void receiver_PlayRequested(
Windows.Media.PlayTo.PlayToReceiver sender,
object args)
{
await dispatcher.RunAsync(
Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
VideoPlayer.Play();
});
}
async void receiver_SourceChangeRequested(
Windows.Media.PlayTo.PlayToReceiver sender,
Windows.Media.PlayTo.SourceChangeRequestedEventArgs args)
{
if (args.Stream != null)
await dispatcher.RunAsync(
Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
var stream = args.Stream as Windows.Storage.Streams.IRandomAccessStream;
VideoPlayer.SetSource(stream, args.Stream.ContentType);
});
}
async void receiver_StopRequested(
Windows.Media.PlayTo.PlayToReceiver sender,
object args)
{
await dispatcher.RunAsync(
Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
VideoPlayer.Stop();
});
}
async void receiver_TimeUpdateRequested(
Windows.Media.PlayTo.PlayToReceiver sender,
object args)
{
await dispatcher.RunAsync(
Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
if (VideoPlayer.Position != null)
receiver.NotifyTimeUpdate(VideoPlayer.Position);
});
}
async void receiver_VolumeChangeRequested(
Windows.Media.PlayTo.PlayToReceiver sender,
Windows.Media.PlayTo.VolumeChangeRequestedEventArgs args)
{
await dispatcher.RunAsync(
Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
VideoPlayer.Volume = args.Volume;
});
}
Async Sub receiver_CurrentTimeChangeRequested(
sender As Windows.Media.PlayTo.PlayToReceiver,
args As Windows.Media.PlayTo.CurrentTimeChangeRequestedEventArgs)
Await Dispatcher.RunAsync(
Windows.UI.Core.CoreDispatcherPriority.Normal,
Sub()
VideoPlayer.Position = args.Time
receiver.NotifySeeking()
seeking = True
End Sub)
End Sub
Async Sub receiver_MuteChangeRequested(
sender As Windows.Media.PlayTo.PlayToReceiver,
args As Windows.Media.PlayTo.MuteChangeRequestedEventArgs)
Await Dispatcher.RunAsync(
Windows.UI.Core.CoreDispatcherPriority.Normal,
Sub()
VideoPlayer.IsMuted = args.Mute
End Sub)
End Sub
Async Sub receiver_PauseRequested(
sender As Windows.Media.PlayTo.PlayToReceiver,
args As Object)
Await Dispatcher.RunAsync(
Windows.UI.Core.CoreDispatcherPriority.Normal,
Sub()
VideoPlayer.Pause()
End Sub)
End Sub
Async Sub receiver_PlaybackRateChangeRequested(
sender As Windows.Media.PlayTo.PlayToReceiver,
args As Windows.Media.PlayTo.PlaybackRateChangeRequestedEventArgs)
Await Dispatcher.RunAsync(
Windows.UI.Core.CoreDispatcherPriority.Normal,
Sub()
VideoPlayer.PlaybackRate = args.Rate
End Sub)
End Sub
Async Sub receiver_PlayRequested(
sender As Windows.Media.PlayTo.PlayToReceiver,
args As Object)
Await Dispatcher.RunAsync(
Windows.UI.Core.CoreDispatcherPriority.Normal,
Sub()
VideoPlayer.Play()
End Sub)
End Sub
Async Sub receiver_SourceChangeRequested(
sender As Windows.Media.PlayTo.PlayToReceiver,
args As Windows.Media.PlayTo.SourceChangeRequestedEventArgs)
If args.Stream IsNot Nothing Then
Await Dispatcher.RunAsync(
Windows.UI.Core.CoreDispatcherPriority.Normal,
Sub()
Dim stream = TryCast(args.Stream, Windows.Storage.Streams.IRandomAccessStream)
VideoPlayer.SetSource(stream, args.Stream.ContentType)
End Sub)
End If
End Sub
Async Sub receiver_StopRequested(
sender As Windows.Media.PlayTo.PlayToReceiver,
args As Object)
Await Dispatcher.RunAsync(
Windows.UI.Core.CoreDispatcherPriority.Normal,
Sub()
VideoPlayer.Stop()
End Sub)
End Sub
Async Sub receiver_TimeUpdateRequested(
sender As Windows.Media.PlayTo.PlayToReceiver,
args As Object)
Await Dispatcher.RunAsync(
Windows.UI.Core.CoreDispatcherPriority.Normal,
Sub()
receiver.NotifyTimeUpdate(VideoPlayer.Position)
End Sub)
End Sub
Async Sub receiver_VolumeChangeRequested(
sender As Windows.Media.PlayTo.PlayToReceiver,
args As Windows.Media.PlayTo.VolumeChangeRequestedEventArgs)
Await Dispatcher.RunAsync(
Windows.UI.Core.CoreDispatcherPriority.Normal,
Sub()
VideoPlayer.Volume = args.Volume
End Sub)
End Sub
Add video player event handlers
The code in this step adds the code for the video player event handlers. These event handlers are called when events occur for the local video player. The event handlers then notify the client computer using the respective Play To receiver method.
Add the following code to the MainPage.xaml.cs or MainPage.xaml.vb file and after the code from the previous step.
void VideoPlayer_CurrentStateChanged(object sender, RoutedEventArgs e) { if (receiver != null) { switch (VideoPlayer.CurrentState) { case MediaElementState.Playing: receiver.NotifyPlaying(); break; case MediaElementState.Paused: receiver.NotifyPaused(); break; case MediaElementState.Stopped: receiver.NotifyStopped(); break; } } } void VideoPlayer_MediaFailed(object sender, ExceptionRoutedEventArgs e) { if (receiver != null) { receiver.NotifyError(); } } void VideoPlayer_MediaEnded(object sender, RoutedEventArgs e) { if (receiver != null) { receiver.NotifyEnded(); VideoPlayer.Stop(); } } void VideoPlayer_MediaOpened(object sender, RoutedEventArgs e) { if (receiver != null) { receiver.NotifyDurationChange(VideoPlayer.NaturalDuration.TimeSpan); receiver.NotifyLoadedMetadata(); } } void VideoPlayer_RateChanged(object sender, RateChangedRoutedEventArgs e) { if (receiver != null) receiver.NotifyRateChange(VideoPlayer.PlaybackRate); } void VideoPlayer_SeekCompleted(object sender, RoutedEventArgs e) { if (receiver != null) { if (!seeking) receiver.NotifySeeking(); receiver.NotifySeeked(); seeking = false; } } void VideoPlayer_VolumeChanged(object sender, RoutedEventArgs e) { if (receiver != null) receiver.NotifyVolumeChange(VideoPlayer.Volume, VideoPlayer.IsMuted); }
Sub VideoPlayer_CurrentStateChanged() If receiver IsNot Nothing Then Select Case VideoPlayer.CurrentState Case MediaElementState.Playing receiver.NotifyPlaying() Case MediaElementState.Paused receiver.NotifyPaused() Case MediaElementState.Stopped receiver.NotifyStopped() End Select End If End Sub Sub VideoPlayer_MediaFailed() If receiver IsNot Nothing Then receiver.NotifyError() End Sub Sub VideoPlayer_MediaEnded() If receiver IsNot Nothing Then receiver.NotifyEnded() VideoPlayer.Stop() End If End Sub Sub VideoPlayer_MediaOpened() If receiver IsNot Nothing Then receiver.NotifyDurationChange(VideoPlayer.NaturalDuration.TimeSpan) receiver.NotifyLoadedMetadata() End If End Sub Sub VideoPlayer_RateChanged() If receiver IsNot Nothing Then receiver.NotifyRateChange(VideoPlayer.PlaybackRate) End If End Sub Sub VideoPlayer_SeekCompleted() If receiver IsNot Nothing Then If Not seeking Then receiver.NotifySeeking() receiver.NotifySeeked() seeking = False End If End If End Sub Sub VideoPlayer_VolumeChanged() If receiver IsNot Nothing Then receiver.NotifyVolumeChange(VideoPlayer.Volume, VideoPlayer.IsMuted) End If End Sub
Save and close the MainPage.xaml.cs or MainPage.xaml.vb file
Run the app
- In Visual Studio, press F5 (debug) to run the app.
- Click the Start Play To Receiver button.
- If the Play To receiver successfully starts, open the Settings charm on another computer and select More PC Settings. In the More Settings window, select Devices.
- In the Devices section, click Add a device. Locate the Sample Play To Receiver Digital Media Renderer. If you changed the value of the FriendlyName property of the Play To receiver, then locate that name. Select the Play To receiver from the list to add it.
- On the client computer, play a video that can be streamed using Play To. While the media is playing, open the Devices charm and select your custom Play To receiver as the target for the streamed video.
Summary
In this quickstart, you created an app that advertises itself as a Digital Media Renderer and plays content streamed from a Play To client.
Related topics
Streaming media to devices using Play To
Samples