devxlogo

Untapped Silverlight Powers: Create Your Own Media Player

Untapped Silverlight Powers: Create Your Own Media Player

My previous article on Silverlight demonstrated how to use the MediaElement control to playback media files. This bare-bones control simply plays back a media file?it does not have visual controls allowing you to pause or advance the media (although you can do this programmatically). This article will show you how to build a Silverlight application that reassembles the YouTube player, allowing you to visually control the playback of the media.

Designing the User Interface
Using Expression Blend 2, create a new Silverlight project and name it MediaPlayer. Add a Windows Media file (.wmv) file to the project; right-click on the project name and select Add Existing Item?. Name it WindowsMedia.wmv.

Figure 1 shows the organization and hierarchy of the various controls. Each of the control(s) outlined in red corresponds to the controls highlighted in Figure 2.


Figure 1. Major Components: The major components of the media player.
?
Figure 2. Major Components: The hierarchy of the controls.

The most delicate part of the media player is the slider, which is used to indicate the progress of the media playback. The slider (canvasProgress) consists of two Rectangle controls and an Ellipse control. The first Rectangle control (rectProgressWell) represents the entire duration of the movie. This control also forms the path that the marker (ellMarker, an Ellipse control) can slide on. The second Rectangle control (rectDownloadProgress) is used to indicate the percentage of the media downloaded from the remote server.

Listing 1 shows the full XAML code for the media player.

Wiring Up All the Controls
With the UI created and ready for coding, it’s now time to wire up all the controls so that they will function as one. First, define the following events handlers:

  • DownloadProgressChanged(): Should be invoked continuously when the MediaElement control downloads the media from the remote server. It’s used to update the red progress bar, which indicates the progress of the download.
  • EllMarkerMouseDown(): Invoked when the user clicks on the marker using the left mouse button.
  • EllMarkerMouseUp(): Invoked when the user releases the left mouse button.
  • MediaPlayerMouseMove(): Invoked when the mouse moves across the Silverlight page.
  • MediaPlayerMouseLeave(): Invoked when the mouse leaves the Silverlight page.
  • MediaEnded(): Invoked when the media has finished playing. The media will be reset to its starting position (so is the marker).
  • PlayPauseButtonUp(): Invoked when the user clicks on the Play/Pause button.

Now, assign the various event handlers to the various controls as shown in Listing 2.

After the event handlers are assigned, it’s time to define the event handlers themselves. Double-click on the Page.xaml.js file located under the Page.xaml item in the Project window.

First, declare the following global variables at the top of the Page.xaml.js file:

//---global variables---var playing = false;var markerClicked = false;var duration=0;var intervalID;//---all the major elements on the page---var ellMarker;var MediaElement1;var textblock;var rectProgressWell;var rectDownloadProgress;//----------------------------------

When the page loads, get a reference to all the major controls on the page (see Listing 3).

Before you define the various event handlers, you need to define two helper functions: ConvertToTimeSpan() and DisplayCurrentPlayBack().

The ConvertToTimeSpan() function converts value in seconds to the TimeSpan format of hh:mm:ss. For example, 61 seconds converts to 00:01:01. You need this function because the MediaElement control’s Position property only accepts values of type TimeSpan. The ConvertToTimeSpan() function is defined as shown in Listing 4.

The DisplayCurrentPlayBack() function is used to display the current status of the media playback. It displays the elapsed time versus the total time of the media. For example, if the media (total duration two minutes) is into its thirtieth second, then the DisplayCurrentPlayBack() function will display 00:00:30 / 00:02:00. In addition, the DisplayCurrentPlayBack() function is also responsible for synchronizing the marker as the media is played. To ensure that the status of the playback is updated constantly, call the DisplayCurrentPlayBack() function repeatedly using the setInterval() JavaScript function (more on this later). The DisplayCurrentPlayBack() function is defined as follows:

//---shows the current playback -- marker and position---function DisplayCurrentPlayBack(){    //---find duration of movie---    if (duration==0)       duration = Math.round(MediaElement1.NaturalDuration.Seconds * 100) /                   100;     //---find current position---    var position = MediaElement1.Position.Seconds;    //---move the marker---    ellMarker["Canvas.Left"] = Math.round((position / duration) *                                rectProgressWell.width);    //---format - elapsed time/total time---    var str =  ConvertToTimeSpan(position) + "/" +                ConvertToTimeSpan(duration);    textblock.Text = str;}

Defining the Event Handlers
The DownloadProgressChanged event handler is fired continuously while the MediaElement control downloads the media from the remote server. In this event handler, you first obtain the progress value (from 0 to 1) and then display the downloaded percentage on the TextBlock control. In addition, you also adjust the width of the rectProgressWell control so that as the media is downloaded, its width will also be expanded.

//---fired while the movie is being downloaded---function DownloadProgressChanged(sender, eventArgs){   //---get the progress value from 0 to 1---   var progress = MediaElement1.DownloadProgress;   //---display the download in percentage---   textblock.Text = Math.round(progress*100).toString() + "%";   //---adjust the width of the progress bar---   var progressWidth = progress * rectProgressWell.width;   rectDownloadProgress.width = Math.round(progressWidth);}

The EllMarkerDown event handler is fired when the user clicks on the marker (the Ellipse control). Here, you set the markerClicked variable to true to indicate that the marker has been clicked:

//---marker is clicked---function EllMarkerMouseDown(sender, eventArgs){    markerClicked=true;}

When the user releases the mouse button, it fires the EllMarkerMouseUp event handler. Here, you first need to check if the user releases the button on the main canvas itself, or on the marker. If the marker was previously clicked, you now need to move the marker to the current location of the mouse and set the media to the new position. The new position of the movie is determined by multiplying the duration of the media and the ratio of the position of the marker with respect to the width of the progress well (Listing 5).

The MediaPlayerMouseMove event handler is fired continuously when the mouse moves over the page. You need to determine if the marker is clicked when the mouse is moving. If it is, that means that the user is moving the marker. In this case, you need to reposition the marker (Listing 6).

The MediaPlayerMouseLeave event handler is fired when the mouse leaves the Silverlight page. In this case, you will set the markerClicked variable to false:

//---mouse leaves the entire Silverlight media player controlfunction MediaPlayerMouseLeave(sender, eventArgs){    markerClicked=false;}

The MediaEnded event handler is fired when the media has finished playing. In this case, you have to make the Play button visible again and hide the Pause button. In addition, you have to move the marker to the beginning and reset the media to the beginning:

//---movie has finished playing---function MediaEnded(sender, eventArgs){    var btnPlay = sender.findName("canvasPlay");    var btnPause = sender.findName("canvasPause");    playing = false;    clearInterval(intervalID);    //---clear the progress updating---    btnPlay.opacity = 1;          //---show the Play button---    btnPause.opacity = 0;         //---hide the Pause button---    //---move the marker to the beginning---    ellMarker["Canvas.Left"] = -2;    MediaElement1.Position="00:00:00"; //---reset the movie position---}

The PlayPauseButtonUp button is fired when the user clicks on the Play/Pause buttons and releases the mouse. When the media has started playing, you use the setInterval() JavaScript function to display the media progress every half second:

Figure 3. Picture This: The functional media player.

function PlayPauseButtonUp(sender, eventArgs){     var btnPlay = sender.findName("canvasPlay");   var btnPause = sender.findName("canvasPause");   //---if currently playing and now going to pause---   if (playing==true) {         MediaElement1.pause();      //---pause the movie---      clearInterval(intervalID);  //---stop updating the marker---      playing = false;      btnPlay.opacity = 1;        //---show the Play button---      btnPause.opacity = 0;       //---hide the Pause button---   }    else   {      MediaElement1.play();       //---play the movie---      playing = true;      btnPlay.opacity = 0;        //---hide the Play button---      btnPause.opacity = 1;       //---show the Pause button---      //---update the progress of the movie---      intervalID = window.setInterval("DisplayCurrentPlayBack()", 500);   }}

That’s it! Press F5 in Expression Blend 2 and you should now be able to use the new media player (see Figure 3)!

devxblackblue

About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.

About Our Journalist