Quickstart: Creating a Play To Receiver (HTML)

[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

  1. Open Visual Studio and select New Project from the File menu. In the Javascript section, select Blank Application. Name the application PlayToReceiverSample and click OK.
  2. 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 HTML UI

Open the Default.html file and add the following HTML to the <body> section.

<table>
    <tr>
        <td><button id="startReceiverButton">Start Play To Receiver</button></td>
        <td style="text-align:right"><button id="stopReceiverButton">Stop Play To Receiver</button></td>
    </tr>
    <tr>
        <td colspan="2"><video id="videoPlayer" width="800" height="600" /></td>
    </tr>
    <tr>
        <td colspan="2"><div id="statusDiv" /></td>
    </tr>
</table>

Add initialization code

The code in this step associates the buttons on the page with their respective event handlers. There are two buttons in the app. A start button to advertise the Play To receiver on the local network, and a stop button to stop advertising the Play To receiver.

Open the js folder. Open the Default.js file and add the following code in place of the default onactivated function.

app.onactivated = function (args) {
    if (args.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {
        if (args.detail.previousExecutionState !== Windows.ApplicationModel.Activation.ApplicationExecutionState.terminated) {
            startReceiverButton.addEventListener("click", startReceiverButton_Click);
            stopReceiverButton.addEventListener("click", stopReceiverButton_Click);
        } else {
            // TODO: This application has been reactivated from suspension. 
            // Restore application state here.
        }
        args.setPromise(WinJS.UI.processAll());
    }
};

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.

Add the following code to the Default.js file and after the code from the previous step.

var receiver;
var display;
var videoPlayer;

function startReceiverButton_Click() {
    try {
        if (receiver == null) {
            receiver = new Windows.Media.PlayTo.PlayToReceiver();
        }

        // Add Play To Receiver events and properties
        receiver.addEventListener("currenttimechangerequested", receiver_CurrentTimeChangeRequested);
        receiver.addEventListener("mutechangerequested", receiver_MuteChangeRequested);
        receiver.addEventListener("pauserequested", receiver_PauseRequested);
        receiver.addEventListener("playbackratechangerequested", receiver_PlaybackRateChangeRequested);
        receiver.addEventListener("playrequested", receiver_PlayRequested);
        receiver.addEventListener("sourcechangerequested", receiver_SourceChangeRequested);
        receiver.addEventListener("stoprequested", receiver_StopRequested);
        receiver.addEventListener("timeupdaterequested", receiver_TimeUpdateRequested);
        receiver.addEventListener("volumechangerequested", receiver_VolumeChangeRequested);

        receiver.friendlyName = "Sample Play To Receiver";
        receiver.supportsAudio = false;
        receiver.supportsVideo = true;
        receiver.supportsImage = false;

        // Add MediaElement events
        videoPlayer = document.getElementById("videoPlayer");
        videoPlayer.addEventListener("durationchange",videoPlayer_DurationChange); 
        videoPlayer.addEventListener("ended", videoPlayer_Ended); 
        videoPlayer.addEventListener("error", videoPlayer_Error);
        videoPlayer.addEventListener("loadedmetadata", videoPlayer_LoadedMetadata); 
        videoPlayer.addEventListener("pause", videoPlayer_Pause); 
        videoPlayer.addEventListener("playing", videoPlayer_Playing); 
        videoPlayer.addEventListener("ratechange", videoPlayer_RateChange); 
        videoPlayer.addEventListener("seeked", videoPlayer_Seeked); 
        videoPlayer.addEventListener("seeking", videoPlayer_Seeking); 
        videoPlayer.addEventListener("volumechange", videoPlayer_VolumeChange); 

        // Advertise the receiver on the local network and start receiving commands
        receiver.startAsync().done(function () {
            // Prevent the screen from locking
            if (display == null) {
                display = new Windows.System.Display.DisplayRequest();
            }
            display.requestActive();

            statusDiv.innerHTML = "'" + receiver.friendlyName + "' started.";
        });


    }
    catch(e) {
        receiver = null;
        statusDiv.innerHTML = "Failed to start receiver.";
    }
}

function stopReceiverButton_Click(e) {
    try {
        if (receiver != null) {
            receiver.stopAsync().done(function() {
                if (display != null)
                    display.requestRelease();

                // Remove Play To Receiver events
                receiver.removeEventListener("currenttimechangerequested", receiver_CurrentTimeChangeRequested);
                receiver.removeEventListener("mutechangerequested", receiver_MuteChangeRequested);
                receiver.removeEventListener("pauserequested", receiver_PauseRequested);
                receiver.removeEventListener("playbackratechangerequested", receiver_PlaybackRateChangeRequested);
                receiver.removeEventListener("playrequested", receiver_PlayRequested);
                receiver.removeEventListener("sourcechangerequested", receiver_SourceChangeRequested);
                receiver.removeEventListener("stoprequested", receiver_StopRequested);
                receiver.removeEventListener("timeupdaterequested", receiver_TimeUpdateRequested);
                receiver.removeEventListener("volumechangerequested", receiver_VolumeChangeRequested);

                //  Remove MediaElement events
                videoPlayer = document.getElementById("videoPlayer");
                if (videoPlayer.readyState != 0) {
                    videoPlayer.pause();
                    videoPlayer.currentTime = 0;
                }

                videoPlayer.removeEventListener("durationchange",videoPlayer_DurationChange); 
                videoPlayer.removeEventListener("ended", videoPlayer_Ended); 
                videoPlayer.removeEventListener("error", videoPlayer_Error);
                videoPlayer.removeEventListener("loadedmetadata", videoPlayer_LoadedMetadata); 
                videoPlayer.removeEventListener("pause", videoPlayer_Pause); 
                videoPlayer.removeEventListener("playing", videoPlayer_Playing); 
                videoPlayer.removeEventListener("ratechange", videoPlayer_RateChange); 
                videoPlayer.removeEventListener("seeked", videoPlayer_Seeked); 
                videoPlayer.removeEventListener("seeking", videoPlayer_Seeking); 
                videoPlayer.removeEventListener("volumechange", videoPlayer_VolumeChange); 

                statusDiv.innerHTML = "Stopped receiver.";
            });
        }
    }
    catch (e) {
        statusDiv.innerHTML = "Failed to stop '" + receiver.FriendlyName + "'.";
    }
}

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 Default.js file and after the code from the previous step.

function receiver_CurrentTimeChangeRequested(args) {
    if (videoPlayer.currentTime !== 0 || args.time !== 0) {
        videoPlayer.currentTime = args.time / 1000;
    }
}

function receiver_MuteChangeRequested(args) {
    videoPlayer.muted = args.mute;
}

function receiver_PauseRequested() {
    videoPlayer.pause();
}


function receiver_PlaybackRateChangeRequested(args) {
    videoPlayer.playbackRate = args.rate;
}

function receiver_PlayRequested() {
    videoPlayer.play();
}

function receiver_SourceChangeRequested(args) {
    if (args.stream != null) {
        var mediaStream = MSApp.createBlobFromRandomAccessStream(args.stream.contentType, args.stream);
        videoPlayer.src = URL.createObjectURL(mediaStream, false);
    }
}

function receiver_StopRequested() {
    if (videoPlayer.readyState != 0) {
        videoPlayer.pause();
        videoPlayer.currentTime = 0;
    }
}

function receiver_TimeUpdateRequested() {
    receiver.notifyTimeUpdate(videoPlayer.currentTime * 1000);
}

function receiver_VolumeChangeRequested(args) {
    videoPlayer.volume = args.volume;
}

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.

  1. Add the following code to the Default.js file and after the code from the previous step.

        function videoPlayer_DurationChange() {
            if (videoPlayer.duration !== Infinity)
            {
                receiver.notifyDurationChange(videoPlayer.duration * 1000);
            }
        }
    
        function videoPlayer_LoadedMetadata () { 
            receiver.notifyLoadedMetadata(); 
        }
    
        function videoPlayer_Ended () { 
            receiver.notifyEnded(); 
        }
    
        function videoPlayer_Error() {
            receiver.notifyError();
            receiver.notifyStopped();
        }
    
        function videoPlayer_Pause () { 
            receiver.notifyPaused(); 
        }
    
        function videoPlayer_Playing () { 
            receiver.notifyPlaying(); 
        }
    
        function videoPlayer_RateChange () { 
            receiver.notifyRateChange(videoPlayer.playbackRate); 
        }
    
        function videoPlayer_Seeked () { 
            receiver.notifySeeked(); 
        }
    
        function videoPlayer_Seeking () { 
            receiver.notifySeeking(); 
        }
    
        function videoPlayer_VolumeChange() {
            receiver.notifyVolumeChange(videoPlayer.volume, videoPlayer.muted);
        }
    
  2. Save and close the Default.js file

Run the app

  1. In Visual Studio, press F5 (debug) to run the app.
  2. Click the Start Play To Receiver button.
  3. 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.
  4. 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.
  5. 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.

Streaming media to devices using Play To

Samples

Play To sample

PlayToReceiver sample

Media Server sample