Monday, June 13, 2011

Windows Phone Mango background audio streaming

Mango provides two different agent classes that your application can use to play audio in the background : AudioPlayerAgent and AudioStreamingAgent. Based on their names It’s easy to believe the first is used to play local files while the second is used to stream audio from the web.
In reality, these class names are somewhat misleading. AudioPlayerAgent is actually designed to play URI-based audio in the background, whether locally or remote. What that means is that you can supply either a local path pointing to a media file in isolated storage, or the URL of a remote media file. The catch is, the media file must have a supported audio format, which is either MP3 or WAV.
So in your foreground application or in the agent, you can create an audio track like so :
   1: var track = new AudioTrack(
   2:                 new Uri("/mySong.mp3", UriKind.Relative),
   3:                 "myTitle", "myArtist", "myAlbum", null);

OR :




   1: var track = new AudioTrack(
   2:     new Uri("http://www.techfox.net/songs/Back_to_shore.mp3",  UriKind.Absolute),
   3:     "myTitle", "myArtist", "myAlbum", null);

Then you can load and play the media file regardless of location :





   1: BackgroundAudioPlayer.Instance.Track = localTrack;
   2: BackgroundAudioPlayer.Instance.Play();
You can actually mix and match between local files in isolated storage, and remote files in a same playlist :




   1: List<AudioTrack> playList = new List<AudioTrack> 
   2: { localTrack, remoteTrack };
The background player will play all these files in the same manner.

For local files, make sure the audio files added to your project are copied into isolated storage before trying to set the track on the background player. MSDN provides an example for doing that, which can be called at application startup. I’ve tweaked it so it reads the playlist songs from a xml file, and copies only the local meia files to isolated storage :



   1: void CopySongsToIsoStorage(string projectDirName)
   2: {
   3:     XDocument data = XDocument.Load("Songs/Playlist.xml");
   4:     var songFiles = data.Descendants("song").Select(s => s.Attribute("source").Value);
   5:  
   6:     using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
   7:     {
   8:         foreach (var song in songFiles)
   9:         {
  10:             if (song.StartsWith("http"))
  11:                 continue;
  12:  
  13:             if (!storage.FileExists(song))
  14:             {
  15:                 string _filePath = projectDirName +  "/" + song;
  16:                 StreamResourceInfo resource = Application.GetResourceStream(new Uri(_filePath, UriKind.Relative));
  17:  
  18:                 using (IsolatedStorageFileStream file = storage.CreateFile(song))
  19:                 {
  20:                     int chunkSize = 4096;
  21:                     byte[] bytes = new byte[chunkSize];
  22:                     int byteCount;
  23:  
  24:                     while ((byteCount = resource.Stream.Read(bytes, 0, chunkSize)) > 0)
  25:                     {
  26:                         file.Write(bytes, 0, byteCount);
  27:                     }
  28:                 }
  29:             }
  30:         }
  31:     }
  32: }

Here’s the sample xml playlist : 


   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <playlist>
   3:   <song source="Back_to_shore.mp3"
   4:         title="Back to shore"
   5:         artist ="Sound of Tarifa"
   6:         album="Exquisite" />
   7:   <song source="http://www.techfox.net/songs/Better_believe.mp3"
   8:         title="Better believe"
   9:         artist ="Sound of Tarifa"
  10:         album="Exquisite" />
  11:   <song source="Wind_riders.mp3"
  12:         title="Wind riders"
  13:         artist ="Sound of Tarifa"
  14:         album="Exquisite" />
  15: </playlist>



So to recap, the AudioPlayerAgent has more capabilities than can be guessed from the name. Use it in your apps for common scenarios of playing mp3 or WMA local or remote audio files in the background.



Cheers!

3 comments:

  1. Mobile devices offer a convenient way to the play audio files you own. You can also use these devices to stream audio files from websites and portals if you have a Windows Mobile operating system and a mobile wireless access service. With streaming audio, you do not have to create additional hard drive space for on your mobile device. Thanks a lot.

    TV Streaming

    ReplyDelete
  2. Hi Yacine. Fantastic blog ;-) I have a question about this. With Microsoft.Xna.Framework.Media.MediaPlayer class I can play tracks in the playlists of Zune. But i can't to do it in "Dormant" state. And i want to do this. I can use BackgroundAudioPlayer, but i need a URL. How I can get a URL from a track from the playlist?.

    Thanks. Jorge (Vigo-Spain)

    ReplyDelete