This article is sponsored by
Telerik RadControls for Silverlight. For similarly awesome content check out
Telerik XAMLflix, your step-by-step guide to Telerik Silverlight and WPF controls. Get access to video tutorials, written tutorials, and tons of code!
To contact me directly please visit my blog at http://michaelcrump.net/ or through twitter at http://twitter.com/mbcrump.
This article is Part 4 of the series “10 Laps around Silverlight 5.” If you have missed any other section then please see the Roadmap below.
To refresh your memory on what Silverlight is:
Microsoft Silverlight is an application framework for writing Rich Internet Applications. The run-time environment is available as a plug-in for most web browsers and works on a variety of operating systems including Windows, Mac and Linux.
To recap what we learned in the previous section:
- We briefly discussed what XNA is.
- We looked at the templates available for new XNA Silverlight 5 projects.
- We dissected the 3D XNA Template to learn more about it’s makeup.
- Pointed out where other sample projects for XNA were located on your hard disk.
In this article, I am going to discuss media features such as low-latency sound using features right out of XNA. We will also discuss Remote Control and Media Command (Keys) support using Silverlight 5. Please review the Roadmap for the series before going any further.
The Roadmap for this Series
I’ve included the Roadmap for the series below as you may want to visit other sections as you learn Silverlight 5. I picked the following features as I thought that you may find them useful in your day-to-day work. If you want a specific topic covered then please leave it in the comments below.
1) Introduction to SL5 – This post which provides a brief history of Silverlight and relevant links.
2) Binding- Ancestor Relative Source Binding and Implicit Data Templates.
3) Graphics –XNA 3D API and Improved Graphics Stack.
4) Media [This Post] - Low-Latency Sound using XNA and Remote Control and Media Command (Keys) Support.
5) Text - Text Tracking and Leading, Linked and Multi-column Text, OpenType Support, Pixel Snapped Text and TextOptions.
6) Operating System Integration Part 1 - P/Invoke, Multiple Windows and Unrestricted File System Access in Full Trust.
7) Operating System Integration Part 2 - Default Filename for SaveFileDialog, 64-bit browser support and Power Awareness.
8) Productivity and Performance - XAML Binding Debugging, Parser Performance Improvements and Multi-core JIT for improved start-up time.
9) Controls - Double and Triple click support, PivotViewer and ComboBox Type-Ahead.
10) Other items - In-Browser HTML, PostScript and Tasks for TPL.
Let’s Begin with Low-Latency Sound using XNA SoundEffect
A new addition to Silverlight 5 is the ability to play low-latency sounds using the XNA SoundEffect class. This is very useful for kiosk or even games that need to play a certain sound over and over. In Silverlight 5, this is much easier than before (where people used various MediaElement hacks). You can now simply borrow the SoundEffect / SoundEffectInstance class from XNA.
Start with a new Silverlight 5 Project
Launch Visual Studio 2010 and select File –> New Project. Then select Silverlight –> Silverlight Application –> Give it a name and hit OK.
On the New Silverlight Application Screen, you will see under “Options” that you may select which version of Silverlight that you want to use. We will select Silverlight 5 for this option. If you don’t see Silverlight 5 as an option then follow the guide here.
The first thing you are going to want to do is to find a .wav file on the net that is PCM-encoded. They are very easy to find with a quick Google search. I am not going to include one for copyright reasons.
Now, right-click your Silverlight 5 project and select “Add”, then “Existing Item.” You can also easily access this screen by hitting “Shift-Alt-A” together. Navigate to wherever you downloaded the .wav file and select the file.
At this point, make sure the .wav file has a build action set to “Content”, as shown below.
Once this is complete, we will need to make a minor adjustment to our MainPage.xaml file to include a button to play the file for this demo.
1: <Grid x:Name="LayoutRoot" Background="White">
2: <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="0,277,0,0" Name="btnPlaySound" VerticalAlignment="Top" Width="75" Click="btnPlaySound_Click" />
3: </Grid>
The only thing that we added to our MainPage.xaml file was a button inside of the Grid that has an event handler when the user clicks the button.
We can navigate over to our MainPage.xaml.cs file and add the following code snippet:
1: private void btnPlaySound_Click(object sender, RoutedEventArgs e)
2: {
3: var soundStream =
4: Application.GetResourceStream(
5: new Uri("stereol.wav", UriKind.RelativeOrAbsolute));
6:
7: var effect = SoundEffect.FromStream(soundStream.Stream);
8:
9: SoundEffectInstance engineInstance = effect.CreateInstance();
10:
11: engineInstance.IsLooped = true;
12: engineInstance.Pitch = -1.0f;
13: engineInstance.Volume = 0.75f;
14:
15: engineInstance.Play();
16: }
In this code snippet, we are using several new features. Let’s examine the code snippet line by line:
- Lines 3-5 creates our resource stream from the wav file that added earlier.
- Lines 7-9 is initializing the SoundEffectInstance class that is going to perform special effects for the .wav file.
- Lines 11-13 is creating a looped wav file that sets the pitch and the volume.
- Lines 15 simply plays the files.
Don’t forget to add the proper namespace and reference to your project.
1: using Microsoft.Xna.Framework.Audio;
If you load the application now, you will hear your .wav file being played over and over again. The pitch and volume has also been adjusted. Easy enough!
Let’s move onto Remote Control and media keys support.
Remote Control and Media Command (Keys) Support
One of the new improvements in Silverlight 5 is the ability to support Remote Control and Media Commands from various hardware manufactures. Below is a sample keyboard and remote control that has buttons for features such as (fast forward, stop, play, rewind, etc). Now we are able to make use of those buttons in Silverlight 5 with a few lines of code.
Let’s get started.
Launch Visual Studio 2010 and select File –> New Project. Then select Silverlight –> Silverlight Application –> Give it a name and hit OK.
On the New Silverlight Application Screen, you will see under “Options” that you may select which version of Silverlight that you want to use. We will select Silverlight 5 for this option. If you don’t see Silverlight 5 as an option then follow the guide here.
The first thing you are going to want to do is to find a .wmv file that you can use for this application. I decided to use the wildlife.wmv file available on every Windows 7 PC. Just like before, I am not going to include it due to copyright reasons.
Now, right-click your Silverlight 5 project and select “Add”, then “Existing Item.” You can also easily access this screen by hitting “Shift-Alt-A” together. Navigate to wherever you downloaded the .wmv file and select the file.
At this point, make sure the .wmv file has a build action set to “Content”, as shown below.
Once this is complete, we will need to make a few minor adjustment to our MainPage.xaml file to play a video.
1: <Grid x:Name="LayoutRoot" Background="White">
2: <MediaElement x:Name="videoPlayer"
3: Source="/Wildlife.wmv" />
4:
5: <TextBlock x:Name="txtMediaKey" Foreground="Red" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="5" FontSize="20" />
6:
7: <Button x:Name="FullScreen"
8: HorizontalAlignment="Left" VerticalAlignment="Bottom"
9: Content="Go Full Screen" Margin="5" Click="FullScreen_Click" />
10: </Grid>
We added the following items to our MainPage.xaml file:
- MediaElement control – This will play the video and give us the ability to stop/start/pause the video using the Media Controls on our keyboard/remote control.
- TextBlock control – To display which MediaCommand code is being executed. (Excellent for debugging)
- Button control – To toggle between FullScreen mode.
We can navigate over to our MainPage.xaml.cs file and add the following code snippet:
1: public MainPage()
2: {
3: InitializeComponent();
4: this.MediaCommand += new MediaCommandEventHandler(MainPage_MediaCommand);
5: }
6:
7: private void MainPage_MediaCommand(object sender, MediaCommandEventArgs e)
8: {
9:
10: txtMediaKey.Text = e.MediaCommand.ToString();
11:
12: switch (e.MediaCommand)
13: {
14: case System.Windows.Media.MediaCommand.Play:
15: videoPlayer.Play();
16: return;
17: case System.Windows.Media.MediaCommand.Pause:
18: videoPlayer.Pause();
19: return;
20: case System.Windows.Media.MediaCommand.Stop:
21: videoPlayer.Stop();
22: return;
23: case System.Windows.Media.MediaCommand.TogglePlayPause:
24: if (videoPlayer.CurrentState == MediaElementState.Paused ||
25: videoPlayer.CurrentState == MediaElementState.Stopped)
26: videoPlayer.Play();
27: else if (videoPlayer.CurrentState == MediaElementState.Playing)
28: if (videoPlayer.CanPause)
29: videoPlayer.Pause();
30: return;
31: case System.Windows.Media.MediaCommand.IncreaseVolume:
32: videoPlayer.Volume += 5;
33: return;
34: case System.Windows.Media.MediaCommand.DecreaseVolume:
35: videoPlayer.Volume -= 5;
36: return;
37: case System.Windows.Media.MediaCommand.ChannelUp:
38: // Channel up
39: return;
40: case System.Windows.Media.MediaCommand.ChannelDown:
41: // Channel down
42: return;
43: default:
44: return;
45: }
46: }
47:
48: private void FullScreen_Click(object sender, RoutedEventArgs e)
49: {
50: Application.Current.Host.Content.IsFullScreen = !Application.Current.Host.Content.IsFullScreen;
51: }
Let’s examine the code snippet line by line:
- Line 4 creates our MediaCommand event handler. This is going to hook up to our media commands case statement.
- Line 10 will simply display which MediaCommand the user has pressed into a TextBlock on the right hand side of the screen. This is useful for debugging applications that use the Media Features in Silverlight 5.
- Lines 12-44 is our switch statement that will trigger the respective action on the MediaElement control.
- Lines 48-51 will simply check to see if the screen is in FullScreen mode and toggle it accordingly.
Note: I didn’t list all of the MediaCommand enums that are available. You can review a complete list here.
If we run the application our video starts playing:
If we hit the “Play/Pause” media button on our keyboard (If your hardware supports it) then you will see the video is now paused and the word “TogglePlayPause” is located in the bottom right hand corner of our screen.
If you hit other media keys then the MediaElement will respond accordingly. You can even try out your WMC remote control if you have one available.
Please note: If you ever have an issue with the keys responding, then switch to FullScreen mode (by clicking the button) and try again. I’ve found several instances where the Silverlight application loses focus.
Notice how easy it was to add support for Media Keyboards and Remotes? Silverlight is already known for having a excellent media player and this just enhances it even more!
Conclusion
At this point, we have seen how you would use Low-Latency Sound using XNA and Remote Control and Media Command (Keys) Support in your Silverlight 5 Applications. We have also discussed a few other features in Silverlight 5. In the next part of the series, I am going to take a look at the new text improvements in Silverlight 5 including: Text Tracking and Leading, Linked and Multi-column Text, OpenType Support, Pixel Snapped Text and TextOptions. Again, thanks for reading and please come back for the next part.
To contact me directly please visit my blog at http://michaelcrump.net/ or through twitter at http://twitter.com/mbcrump.