Monday, December 3, 2007

Media on the Move

TV recordings, music, podcasts - with Windows Mobile 6 (WM6) you can pack it all up and take it with you on the road. Windows Media Player (WMP) is provided to handle a variety of media formats. The mobile player is very similar to the desktop player and is a suitable playback application.

I first started using WMP to take some podcasts on the road. I could sync the MP3 files to my device and enjoy them while traveling. However, this process required:

1) downloading the podcast on my PC,
2) syncing with my device,
3) listening to the podcast, and
4a) deleting the files I already played, or
4b) archiving the files on my PC if there was something I wanted to keep.

Windows Media Player is sufficient for this, but it's not really efficient. I wanted an application to streamline the whole process.

Fortunately, it's not necessary to write an entire player from the ground up. Microsoft has implemented Windows Media Player as a control that can be used in any application - WMP without the user interface. This allows anyone to write their own UI around the core media player.

I decided to use the WMP control from within a .NET CF application written in C#. Using Visual Studio, I created a C# project and added a COM reference for the WMP control. The COM control is listed as "Windows Media Player" and the path is "wmp.dll" in the \Windows\system32 directory. Because the interfaces for the mobile and desktop controls are identical, you can simply reference the desktop DLL and the Interop.WMPLib reference will be compatible with WMP on your mobile device.

Creating and using the media player simply requires:

WindowsMediaPlayerClass wmp = new WindowsMediaPlayerClass();
IWMPMedia media = wmp.newMedia(pathName);
wmp.controls.playItem(media);

It's that easy.

However, you will find that when you instantiate WindowsMediaPlayerClass on your mobile device your application will not shutdown properly. To confirm this all you need to do is create a new application and in the main Form's Load event call:

mWMP = new WindowsMediaPlayerClass();

Add a menu item that will call the Form's Close() method and run the application in the Windows Mobile emulator. Set a breakpoint after the application's Run loop exits in the Main() function (see Program.cs). After the Close() method is called, you'll see the run loop exits and you can step through the rest of the Main() function to see it exits cleanly, but the application will never shutdown. My guess is there is a thread created by the WMP control and WM6 is waiting for that thread to exit.

As a workaround, you can simply call:

TerminateProcess(0x42, 0);

at the end of Main(). This will force the process to shutdown. Provided you don't have any global objects that need to always shutdown cleanly, you can successfully terminate your application. The Visual Studio debugger will report that it has lost communication with the application, but your application won't run indefinitely on your mobile device.

Have you run into this same problem? Share your solution in a comment.

I'll share some of my other experiences with the WMP control in future posts.

No comments: