-->
Save your seat for Streaming Media NYC this May. Register Now!

Creating and Embedding a Customized Player

Welcome back. In Part I, we looked at the basic formatting and embedding of the player -- also looking at methods to assign external buttons for controlling basic functions of the player. We'll dig a little deeper in Part II of this tutorial to examine more involved functions such as the volume control, the video clock, and the bandwidth display functions.

Before We Get Started
Again, the full version of the player (Real) is located here.If you haven’t done so already, please download a full version of the code and graphics here.And lastly, the RealPlayer Embedded SDK can be found here.

Outline
The following is a basic outline of the pieces of this embedded player.

  1. Formatting and Framework
  2. Media Player ActiveX Control
  3. Media Player Full, Play, Pause, and Stop Controls
  4. Media Player Volume Control
  5. Media Player Clock and Bandwidth Properties
  6. Media Player Clip Information Properties
  7. Transition to the Windows Media Player
We’ll analyze items 4 and 5 in this tutorial. The final items will be discussed in Part III.

Code Comments
Before you dig into the code for the volume control, video clock, and bandwidth display functions, it's important to elaborate on the use of DHTML. All of these functions require dynamically changing an element. The volume control uses separate DIVs to represent status bars. The background colors are changed to a red or black, representing an increase or decrease, respectively. The video clock and bandwidth displays are continuously being changed -- every two hundred milliseconds.

All of these changes use DHTML. Relevant examples are listed below.

To change the background color of a DIV in the volume control, Javascript is utilized to update its style sheet property. Here’s an example:

divMyDivName.style.backgroundColor="purple";

Like the media player, these elements use a dot notation to access their properties, methods, and events.

In order to update the video clock and bandwidth displays, we update the innerText property. Here’s another example:

divMyDivName.innerText="new text";

There are a myriad of effects and options with DHTML, allowing for functionality and dynamic content far beyond what we’ve seen here.

Now we’ll get right into it.

Volume Control
We demonstrated creating the volume control in Part I. Here we look at linking it to the actual player object.

For reference, the volume control DIV code in Part I looks like this:

There are two parts to consider when creating a volume control:

  • Setting the volume of the player.
  • Updating the status of the volume indicator.
These two completely separate operations need to be synchronized to render a properly functioning volume control.

There are eight volume bar DIVs. Note their naming convention: Each is named divVolumeBarX, with the X representing its position (1 through 8).

The RealPlayer method we will be accessing is SetVolume(intVolume). The intVolume parameter may be a value between 0 and 100. The first time we access this method is through the applicationLoad() function, which is called when the document fully loads through the body onLoad() event.

Notice the volume setting is equal to 50 (or 50% of the maximum volume). This corresponds to the four DIVs highlighted as the player loads. We can either decrease or increase one volume bar’s amount at a time after setting this initial volume. In order to convert from the 0 – 100 convention, we will divide 100 by 8. The dividend, 12.5, is the amount to change for each volume bar. For example: If, after the application loads, we decrease the volume bars by one, we will pass 37.5 to the SetVolume() method.

The actual set volume function is as follows:

This takes care of the first part of a volume control and we must now link it with the actual decrease and increase buttons, as well as the corresponding DIVs.

While creating the global variables, one was named intVolueBarState – set equal to 4. This variable keeps track of the current position of the volume bars. Next, we need to create a function to either increase or decrease volume depending on what button the user clicks. This function is called volumeChange(strChangeDir). strChangeDir is understood as either "increase" or "decrease".

The following is the volumeChange() function, which will be examined below.

The basic logic of the volumeChange function is as follows:

  1. See if the user has either clicked increase or decrease.
  2. Make sure that we haven’t reached the lower or upper limits (between 0 and 8)
  3. Set the background color of the corresponding DIV to either red or black depending on an increase or decrease, respectively.
  4. Add or subtract from intVolumeBarState depending on increase or decrease, respectively.
  5. Set the player volume to the current intVolumeBarState.
In the function above, we are able to determine the name of the DIV due to our chosen naming convention. We can construct the proper name based on intVolumeBarState. For example, if intVolumeBarState is equal to four, and we want to decrease the volume, we first subtract one from intVolumeBarState and then construct the name as "divVolumeBar" + "intVolumeBarState" = "divVolumeBar3". We then assign the background color of this DIV equal to black.

The last part of the volume control equation links the increase and decrease images to this function. This is performed through the onClick event as follows:

That’s it. We now have a fully functional volume control.

Video Clock
The Video Clock function is the most difficult of all functions in our custom player application. It is all based, however, on the objMediaPlayer.GetPosition() method. This method queries the media player when it is called and returns a value in milliseconds.

The actual DIV appears as follows:

We will be updating the innerText property of this DIV.

The base premises of our videoClock() function is as follows:

  1. Query the media player for milliseconds elapsed.
  2. Convert from milliseconds into an hours:minutes:seconds format.
  3. Update the text in the clock DIV to reflect the new value.
  4. Loop.
The loop is vital. Without it, we would query the player once and the clock wouldn’t truly be a clock. We need to make the function calls itself over and over again with no additional input from the user.

The first requirement is starting the function. We could start it in the applicationLoad() function, however this would be a bit inefficient as there’s no point to displaying a video clock until the media is playing. Therefore, the clock will start when the user clicks play, and stop when the user clicks stop. This allows us to free up that thread and reduce a bit of overhead when unnecessary.

We'll now look back at our videoPlay() and videoStop() functions -- pieces ignored during the first part of the series.

We created a global variable called idVideoClockTimer. In videoPlay() --within the functions above-- we assign the window.setInterval() function to this variable. We call the function through a variable assignment to clear this interval during videoStop(), thereby freeing up the thread. The window.setInterval() function in videoPlay() recursively calls the function intervalCalls() every 200 milliseconds. This is the loop part of the equation allowing for constant refreshing of the video clock text, and as demonstrated later, the bandwidth display functions.

The intervalCalls() function is as follows:

We’ve created a separate function for updating both the video clock and bandwidth display recursively. This is more efficient than creating a separate thread for each item to be updated.

The following is the videoClock() function:

To reiterate, the above function queries the media player for the milliseconds elapsed, converts that number into hh:mm:ss format, and then updates the divVideoClock text.

Bandwidth Display
The difficult part is now over. As long as you firmly grasp the concept of updating the text of a DIV recursively, the rest is easy. The bandwidth display is very similar to the video clock in the way it is updated, but without as much logic -- as we don’t need to perform as difficult a conversion.

The DIVs that display the Current and Average bandwidths look like this:

Again, just like the video clock, we will be updating the innerText property of divCurBandwidth and divAvgBandwidth.

The two RealPlayer methods we will call are GetBandwidthCurrent(), and GetBandwidthAverage() for the current and average bandwidths, respectively. Both of these methods return a value in bits per second.

For our purposes, we want to display kilobits per second, so we will need to do some basic conversion. The basic logic of the getBandwidth() function is as follows:

  1. Make sure the video is playing.
  2. Query media player for the current and average bandwidths.
  3. Convert from bits per second to kilobits per second by dividing by 1024.
  4. Form bandwidth string (intCurBandwidth + "kbps")
  5. Update respective DIVs
  6. Loop
Remember: The loop portion of this function takes place though the window.setInterval() function, not the getBandwidth() function. Here’s the corresponding code for the above logic.

And that’s it. Difficulty only arose when we wanted to instantiate the loop. Once we had this coded, however, all other real-time properties can be displayed with relative ease.

For Next Time
We'll finish this series in Part III, discussing the clip info display and making the transition to Windows Media.

Contributor Marco Bianco is CTO at OverDrive Media.OverDrive Media is a full service streaming media development house delivering world-class streaming media solutions. Our core competency is streaming media Web development. We deliver streaming media integration to existing sites, build complete Web solutions that leverage streaming media or manage streaming media projects as part of a larger team. A partial list of our services includes project conception and consulting, professional graphic design, database design and programming, custom Web application development, audio and video encoding and MacroMedia Flash.

Streaming Covers
Free
for qualified subscribers
Subscribe Now Current Issue Past Issues