Simple JavaScript Controls

Apr 3, 2010 at 2:17 PM
Edited Apr 4, 2010 at 4:04 AM
Hi,
I have a HTML page with an embedded Windows Media Player, but I'm looking to improve the user experience by switching to this SilverLight Video Player.

This is my first experience with SilverLight, but I was able to follow the installation instructions and get it to play one of our MMS live streams, as well as a WMV file.

With the old method using WMP, we have some simple HTML buttons for Play, Pause, Stop, and Full Screen. These use the "control.Play()", "control.Pause()", etc. JavaScript controls for the player, triggered by each button's "onClick" event.

I'm looking to do the same thing with this SilverLight Video Player, and have searched the better part of last week for a similar command. To be honest I'm suffering from information overload, as I know a bit of HTML and JavaScript, but that's about it.

I found a lot of information about the MediaElement control in SilverLight, and I'm pretty sure that's what I need to access. I've also tried Mr. Acheson's JavaScript API as listed in this discussion board, but I don't know how to leverage it for simple video control and to call a specific player to go full screen.

I'm sure this is extremely simple to do for many if you, but it's got me stumped. Any assistance would be GREATLY appreciated.

Thanks in advance for your help!  
 
Apr 3, 2010 at 2:41 PM
Edited Apr 3, 2010 at 2:47 PM

No problem! This is quick and easy to do with Silverlight.

All you need to do is get the MediaElement in your JavaScript code:-

// The ID attribute of the <object/> element in your HTML where you embed SL2VideoPlayer.
var objectID = "silverlightControlHost1";
// The Name attribute identifying the MediaElement in the XAML of the SIlverlight application -- in SL2VideoPlayer it's "mediaPlayer".
var mediaElementName = "mediaPlayer";
var host = document.getElementById(objectID);
var mediaElement = host.content.findName(mediaElementName);

You can then call the play and stop methods, etc, on the mediaElement object in your JavaScript code. You can also set the mediaSource property which is the URI of your media file or stream.

More info:

http://msdn.microsoft.com/en-us/library/bb980132(VS.95).aspx
http://msdn.microsoft.com/en-us/library/cc189078(VS.95).aspx

Here's some additional JS code I wrote a while back for SL2VideoPlayer, which may help give you a head start:

http://slvideoplayer.codeplex.com/Thread/View.aspx?ThreadId=71836

Apr 4, 2010 at 4:03 AM

Thank you very much!

This is exactly what I was looking for, unfortunately I'm still having a problem getting the buttons to work.  Here's the code I have so far, including the code you suggested above:

<html>
<head>
<title>Silverlight Control Test Page </title>

<script type="text/javascript">
// The ID attribute of the <object/> element in your HTML where you embed SL2VideoPlayer.
var objectID = "SLVIDEO";
// The Name attribute identifying the MediaElement in the XAML of the SIlverlight application -- in SL2VideoPlayer it's "mediaPlayer".
var mediaElementName = "mediaPlayer";
var host = document.getElementById(objectID);
var mediaElement = host.content.findName(mediaElementName);
</script>

</head>
<body>

<object id="SLVIDEO" data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="736" height="552">
<param name="source" value="Scripts/VideoPlayer.xap"/>
<param name="background" value="black" />
<param name="initParams" value="m=Test_Video.wmv" />
<param name="minruntimeversion" value="2.0.31005.0" />
<a href="http://go.microsoft.com/fwlink/?LinkId=124807" style="text-decoration: none;">
<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>
</a>
</object>

<br><br>
<input name="Playbtn" type="Button" value="Play Video" onClick="mediaElement.Play();">
&nbsp;&nbsp;&nbsp;
<input name="Pausebtn" type="Button" value="Pause Video" onClick="mediaElement.Pause();">
&nbsp;&nbsp;&nbsp;
<input name="Stopbtn" type="Button" value="Stop Playback" onClick="mediaElement.Stop();">
<br><br>

<input name="FullScrnbtn" type="Button" value="Maximize Screen" onClick="mediaElement.FullScreen();">

</body>
</html>

Please forgive my syntax ignorance and coding simplicity; I'm not a programmer by profession.  When I try the "Play" button on the page I'm getting an error stating "mediaElement is null or not an object".  I'm guessing I misinterpreted how to use your mediaElement variable.  What am I doing wrong?

Thank you again in advance for your help!

 

Apr 4, 2010 at 8:16 AM

You're almost there!

It's extremely useful to consider the order in which things load on a page. :)

Take a close look at the last few lines of the setupPlayer function in my sample code. As you can see, I repeatedly attempt to get the MediaElement object until it succeeds.

The main problem is, you simpy put the JavaScript in the HEAD element. That means it runs before the BODY element has even loaded, so you're trying to interact with the SIlverlight before it has even loaded -- it doesn't exist yet. First, I would suggest using the onload event of the BODY element to execute the JavaScript, that way it doesn't execute until after the page has loaded. Secondly, if you adopt this approach, you should have some retries as I do in my sample code. This is because the MediaElement within the SIlverlight won't exist until the Silverlight application has initialised and started running. The loaded event of the web page just means the XAP file has loaded,

Let me know how that goes!

Apr 4, 2010 at 6:33 PM

Ah okay, yeah that makes complete sense.  Given that I only need the MediaElement when the buttons are pressed, I thought I'd just turn it into a function, and it works!  Here's what I have now:

 

<html>
<head>
<title>Silverlight Control Test Page </title>

<script type="text/javascript">

////objectID = The ID attribute of the <object/> element in your HTML where you embed SL2VideoPlayer.
function PlaySL(objectID)
{
// //mediaElementName = The Name attribute identifying the MediaElement in the XAML of the SIlverlight application -- in SL2VideoPlayer it's "mediaPlayer".
var mediaElementName = "mediaPlayer";
var host = document.getElementById(objectID);
host.content.findName(mediaElementName).Play();
}

////objectID = The ID attribute of the <object/> element in your HTML where you embed SL2VideoPlayer.
function PauseSL(objectID)
{
// //mediaElementName = The Name attribute identifying the MediaElement in the XAML of the SIlverlight application -- in SL2VideoPlayer it's "mediaPlayer".
var mediaElementName = "mediaPlayer";
var host = document.getElementById(objectID);
host.content.findName(mediaElementName).Pause();
}

////objectID = The ID attribute of the <object/> element in your HTML where you embed SL2VideoPlayer.
function StopSL(objectID)
{
// //mediaElementName = The Name attribute identifying the MediaElement in the XAML of the SIlverlight application -- in SL2VideoPlayer it's "mediaPlayer".
var mediaElementName = "mediaPlayer";
var host = document.getElementById(objectID);
host.content.findName(mediaElementName).Stop();
}

////objectID = The ID attribute of the <object/> element in your HTML where you embed SL2VideoPlayer.
function MaximizeSL(objectID)
{
// //mediaElementName = The Name attribute identifying the MediaElement in the XAML of the SIlverlight application -- in SL2VideoPlayer it's "mediaPlayer".
var mediaElementName = "mediaPlayer";
var host = document.getElementById(objectID);
host.content.findName(mediaElementName).FullScreen();
}

</script>

</head>
<body>

<object id="SLVIDEO" data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="736" height="552">
<param name="source" value="Scripts/VideoPlayer.xap"/>
<param name="background" value="black" />
<param name="initParams" value="m=Test_Video.wmv" />
<param name="minruntimeversion" value="2.0.31005.0" />
<a href="http://go.microsoft.com/fwlink/?LinkId=124807" style="text-decoration: none;">
<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>
</a>
</object>

<br><br>
<input name="Playbtn" type="Button" value="Play Video" onClick="PlaySL('SLVIDEO');">
&nbsp;&nbsp;&nbsp;
<input name="Pausebtn" type="Button" value="Pause Video" onClick="PauseSL('SLVIDEO');">
&nbsp;&nbsp;&nbsp;
<input name="Stopbtn" type="Button" value="Stop Playback" onClick="StopSL('SLVIDEO');">
<br><br>

<input name="FullScrnbtn" type="Button" value="Maximize Screen" onClick="MaximizeSL('SLVIDEO');">

</body>
</html>

The good news is that the play, pause, and stop buttons work now!  Woo hoo!  However, I have two new challenges and a question:

  1. I noticed that the play button on the bottom-left of the player (as well as the large transparent play button) do not disappear when the video is playing. I assume I'm controling the video playback but not the SL Video Player visual elements?  Any ideas?
  2. My full screen button isn't working, but I'm guessing that I'm not using the correct call to the MediaElement.  Wat am I doing wrong here?  I know its possible since the player itself has that functionality.
  3. I'm pulling in the ObjectID of my player in the button functions (so that I could use the functions for other players as well), but would like to make it only one function where I could send not only the ObjectiD but the command as well (Play, Pause, Stop, Full Screen). Seems like it should be possible but I haven't been able to get it to work.

Thank you again for your help with this coding adventure of mine. :)

 

Apr 4, 2010 at 9:43 PM

Nice work! You have it working, and that's the main thing. Well done. :)

[The worst that could happen is that the host and mediaElement objects won't exist if the user interacts too early. You could avoid this by checking to see whether the objects exist before referencing them, which is obviously best practice. The only other suggestion I'd make is that you only need to get the MediaElement once, to avoid the slight performance overhead of getting it each time the user interacts.]

The answer to all three of your last questions is essentially the same. You're clearly already on the right track, judging by what you've said. Take a look at the simple XAML and C# code behind SL2VideoPlayer. That'll explain it much better than I could here. If you can, step through it to see what happens when you click play on the player in the usual way. In essence, there are one or two other things to work with other than the MediaElement to do all of this. You could handle them in JavaScript, just like you are with the MediaElement. The best way of all would be to tweak the C# code slightly, to do exactly what you want it to do.

 

Apr 5, 2010 at 2:36 PM
Edited Apr 5, 2010 at 2:37 PM

Eek... Going into the programming code is a little daunting for me, as I don't even know what the XAML and CS files actually do in SilverLight (although to me it looks like the XAML deals with the "look" and the CS deals with the "function" of SilverLight). Anyway, this isn't the place for a crash course anyway; I'm not going to waste your time in a forum like this on SilverLight 101.

That said, I looked at your API over and over and found the way to hide the controls. Unfortunately to my surprise, that didn't include the large centered "Play" button I was trying to hide.  That led me to do a lot of digging in the source code on this site, and I found several things in the Page.xaml.cs file. Given your points about taking up memory for each MediaElement, I'm now checking to see if it's set already (although frankly I'm not sure if my null code doing anything relevent).  I was also able to condense my functions into one, with a variable going into the function letting it know what the user wants to do. So, here's where I am now. :)

<html>
<head>
<title>Silverlight Control Test Page </title>

<script type="text/javascript">

////objectID = The ID attribute of the <object/> element in your HTML where you embed SL2VideoPlayer.
function ControlSL(objectID,Funct)
{
	if (mediaElementName == null)
		{
		// //mediaElementName = The Name attribute identifying the MediaElement in the XAML of the Silverlight application -- in SL2VideoPlayer it's "mediaPlayer".
		var mediaElementName = "mediaPlayer";
		}
	if (controlsElementName == null)
		{
		// //controlsElementName = The Name attribute identifying the visible Player Controls in the Silverlight application -- in SL2VideoPlayer it's "controlsContainer".
		var controlsElementName = "controlsContainer";
		}	
	if (playElementName == null)
		{
		// //playElementName = The Name attribute identifying the large centered Play button control in the Silverlight application -- in SL2VideoPlayer it's "PlayIcon".
		var playElementName = "PlayIcon";
		}
	if (fullscreenElementName == null)
		{
		// //fullscreenElementName = The Name attribute identifying the fullscreen function in the Silverlight application -- in SL2VideoPlayer it's "IsFullScreen".
		var fullscreenElementName = "IsFullScreen";
		}
		
var host = document.getElementById(objectID);
host.content.findName(playElementName).Visibility = "Collapsed";
	
	if (Funct == "Play")
		{
		host.content.findName(mediaElementName).Play();
		host.content.findName(controlsElementName).Visibility = "Collapsed";
		}	
	else if (Funct == "Pause")
		{
		host.content.findName(mediaElementName).Pause();
		host.content.findName(controlsElementName).Visibility = "Visible";
		}
	else if (Funct == "Stop")
		{
		host.content.findName(mediaElementName).Stop();
		host.content.findName(controlsElementName).Visibility = "Visible";
		}
	else if (Funct == "Maximize")
		{
		host.content.findName(fullscreenElementName) = "True";
		}
}

</script>

</head>
<body>

<br><br>

<div align="center">

<object id="SLVIDEO" data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="736" height="552">
<param name="source" value="Scripts/VideoPlayer.xap"/>
<param name="background" value="black" />
<param name="initParams" value="m=Test_Video.wmv" />
<param name="minruntimeversion" value="2.0.31005.0" />
<a href="http://go.microsoft.com/fwlink/?LinkId=124807" style="text-decoration: none;">
<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>
</a>
</object>

<br><br>
<br><br>

<input name="Playbtn" type="Button" value="Play Video" onClick="ControlSL('SLVIDEO','Play');">
&nbsp;&nbsp;&nbsp;
<input name="Pausebtn" type="Button" value="Pause Video" onClick="ControlSL('SLVIDEO','Pause');">
&nbsp;&nbsp;&nbsp;
<input name="Stopbtn" type="Button" value="Stop Playback" onClick="ControlSL('SLVIDEO','Stop');">
<br><br>

<input name="FullScrnbtn" type="Button" value="Maximize Screen" onClick="ControlSL('SLVIDEO','Maximize');">

</div>

</body>
</html>
I'm extremely jazzed that I have the play, pause, and stop button working in a single function, along with the center "Play" button and botom controls going away.
However, I still have two issues. First, I thought I found the Full Screen control ("IsFullScreen = True") but I can't seem to get it to work yet. Also, the small play icon is showing while the video is playing instead of the pause icon being loaded. That's not a big deal, but I haven't found anything relating to that icon swap in the code at all.
I'm sooo close!
Apr 5, 2010 at 2:51 PM

Good work, that JavaScript code is coming along nicely!

As you rightly observe, the functionality you want is more about working with other components of the SL2VideoPlayer, rather than just the MediaElement.

Apr 5, 2010 at 3:02 PM

Ah okay.  So is the "IsFullScreen" the correct component?  That's the closest one I could find.

Apr 5, 2010 at 3:05 PM

I don't have the code in front of me, I'm on my phone! But if you can find the full screen button in the XAML or the full screen method in the C# that's what you'll want to be workign with.

Apr 5, 2010 at 4:45 PM

Well after searching, I found this in the Page.xaml.cs:

if (App.Current.Host.Content.IsFullScreen == true)
            {
                double targetWidth = (double)App.Current.Host.Content.ActualWidth;
                double targetHeight = (double)App.Current.Host.Content.ActualHeight;

                this.Width = targetWidth;
                this.Height = targetHeight;

                mediaPlayer.Width = targetWidth;
                mediaPlayer.Height = targetHeight;
            }

So, I thought I could set "host.content.findName(fullscreenElementName)" to "true" in my code above, but it's not forcing the player to go full screen.

I also found this in the mediaControl.xaml.cs file:

private void OnFullScreenClick()
        {
            if (FullScreenClicked != null)
            {
                FullScreenClicked(this, null);
            }
        }

...but I have NO idea what that's doing or how I would even leverage the "OnFullScreenClick()" or "FullScreenClicked" functions in my script.

Apr 12, 2010 at 8:47 PM

I'm back at it again after working on some other things.

I found this:

                // Toggle fullscreen
                Application.Current.Host.Content.IsFullScreen = !Application.Current.Host.Content.IsFullScreen;

So I tried to leverage it in JavaScript like this, but the control name "IsFullScreen" came back with an error:

////objectID = The ID attribute of the <object/> element in your HTML where you embed SL2VideoPlayer.
function ControlSL(objectID,Funct)
{

	if (fullscreenElementName == null)
		{
		// //fullscreenElementName = The Name attribute identifying the fullscreen function in the Silverlight application -- in SL2VideoPlayer it's "IsFullScreen".
		var fullscreenElementName = "IsFullScreen";
		}
		
var host = document.getElementById(objectID);
	
	if (Funct == "Maximize")
		{
		host.content.findName(fullscreenElementName) = !host.content.findName(fullscreenElementName);
		}
}

It seems like I'm very close to the correct code, but I can't seem to trigger it to run. When I do an alert on "host.content.findName(fullscreenElementName)" while the player is embedded on the page (not full screen), I get "null".

That makes me concerned that I'm trying to set a variable that's just meant for reading (e.g., if the player is full screen or not). In other words, I know I can't make the car drive by forcing the speedometer to move. I'm still looking for the accelerator. :)
 

Apr 13, 2010 at 8:33 AM

Yes, you're close. You've identified the right C# field, IsFullScreen.

However, you won't find that in host.content, that's not how it works.

E.g. There's a component defined in the mediaControl XAML with the name btnFullScreen, which is more like the direction you need to be heading in *if* it's even possible in SL2VideoPlayer to do what you want without adding a couple of extra lines of code in the project yourself. It's a ToggleButton control, so you could see if you can get at the properties/methods of that using JavaScript and see what happens.

Have you downloaded Visual Studio and had a look at the SL2VideoPlayer code in there? Without it you're working in the dark a bit. Intellisense is an easy way to see which methods, properties, events etc are available for an object without referring to documentation. Best of all, you can do what you need to do more easily with a small amount of C# code.

 

Jan 6, 2011 at 1:44 AM

I'm getting an "Invalid pointer" javascript error when I try to execute this javascript in a link onclick handler:

document.getElementById('mediaplayer1').content.findName('mediaPlayer').Play();


My player definition:
<object id="mediaplayer1" data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="484" height="280">

            <param name="source" value="/global/windowsembedded/renderingassets/silverlight/VideoPlayer.xap"/>

            <param name="background" value="white" />            <param name="windowless" value="true" />           

<param name="initParams" value="m=mms://msnvidweb.wmod.msecnd.net/a10026/e1/ds/us/CMG_US/CMG_Microsoft/53a13593-ad65-4956-afb2-6e968b9eccdc.wmv,thumbnail=http://localhost/global/windowsembedded/en-us/publishingimages/test/fpoimage.png,autohide=true" />

            <param name="minruntimeversion" value="2.0.31005.0" />           

            <a href="http://go.microsoft.com/fwlink/?LinkId=124807" style="text-decoration: none;">

              <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>

            </a>         

</object>

The code is definitely executing *after* page load, since it requires a user initiated click.  the player will play if I just click on it, so silverlight is loaded...  what else?

Thanks,

Sheryl

Jan 6, 2011 at 1:46 AM

p.s. I'm getting an object for the "document.getElementById('mediaplayer1') call, but it can't seem to find the "content" element, I think....

Jan 24, 2011 at 5:02 PM

In case this helps anybody, I wrote a very simple JavaScript library to make it easy to work with the MediaElement in a Silverlight application using pure JavaScript:

http://silverlightmedia.codeplex.com/