Last month when I gave a talk before the NYC .NET Developer's Group on Windows Phone 7 programming, somebody asked if it were possible for a phone application to play MP3 or WMA files. I said that it was possible to play song files from the user's music library — in fact, I show how in Chapter 18 of Programming Windows Phone 7 — but I didn't see a way to play compressed audio files otherwise. (Playing PCM files is a subject of an article I'm currently working on for the February 2011 issue of MSDN Magazine.)
I was wrong. It is possible for a Windows Phone 7 application to access and play MP3 or WMA files that are stored as either content in the application or referenced over the internet. Such a file becomes an instance of the Song class that you instantiate with the Song.FromUri method. The URI references the file.
Song is an XNA class but you can use it in a Silverlight program. You'll need a reference to the Microsoft.Xna.Framework DLL — ignore the warning message; you are, after all a trained perfessional and you know what you're doing — and you'll want a using directive for the Microsoft.Xna.Framework.Media namespace.
In XNA, you can include an MP3 or WMA file in the program by adding it to the application's Content project, and then access it using the normal ContentManager object available through the Content property of the Game derivative. Call the generic Load method with a type of Song:
Song song = this.Content.Load<Song>("filename-without-extension");
In Silverlight for Windows Phone, just add the file in the application project, perhaps in a directory. By default, the Build Action in the file's properties should be Content, and that's what you should leave it as. You can then access the file using Song.FromUri method with a Uri object that references the filename and directory with a UriKind.Relative argument:
Song song = Song.FromUri("name", new Uri("dir/filename", UriKind.Relative));
The first argument becomes the Name property of the Song object. You can also access a music file over the internet in the same way but without the UriKind.Relative argument.
Song.FromUri returns an object of type Song that you then just pass to the static MediaPlayer.Play method.
The downloadable Silverlight PlaySong project (3.6 megs due to a WMA file in the project) demonstrates this technique with an MP3 file of a 1939 recording of the last movement of the Brahms Violin Concerto available on the Internet Archive site and a WMA file stored as content. This WMA file is a short electronic-music composition I originally recorded in 1977. The opening screen of the program looks like this:
You select one or the other, the file is loaded, and it starts playing. The button at the bottom lets you pause and resume.
To compile and run this program, you'll need the Windows Phone 7 development tools installed, of course. You can run the program in the emulator, and the music plays through your PC's speakers. But if you're deploying to an actual phone from Visual Studio, the Zune software can't be running, apparently because it wants total control of media. You'll need to exit Zune and run the WPDTPTConnect32 or 64 program instead so Visual Studio can communicate with the phone.
As with any Silverlight program that plays sounds or music through the XNA framework, your program must include code that calls FrameworkDispatcher.Update at approximately the same rate as the video display refresh, which is about 30 frames per second on the phone. This is commonly done in a separate class (called XnaFrameworkDispatcherService in this project) that is instantiated from the App.xaml file.
Programming Windows Phone 7
Free thousand-page ebook now available!