In this article, I will provide a walkthrough to "Play Background Audio" in Mango or a Windows 7.1 phone. This article is fully based on the Beta version and you will see how to play local media.
Step 1: Firstly, let us create a Windows Phone Application. To create it, open Visual Studio and select Windows Phone Application from the installed templates.
Since Background Audio playing is a feature of 7.1 version, do not forget to select Windows Phone 7.1 as the Target Version.
Step 2:
The next step we need to do is to add a project for Audio Playback Agent. So, right-click the solution and add a new project and from installed templates select Windows Phone Audio Playback Agent project type.
After adding this project, you will have two projects in the Solution Explorer. One is an Audio Playback Agent and another is the Phone Application.
Step 3:
Since both the projects have been created, now add a few music files to play. To do this right-click on AudioPlaybackAgent project and create a new folder. Give desired name to this folder. In this case, I am naming the newly created folder Music.
Right-click on the Music folder and add existing items. Add music files to this folder.
After adding Music files select all the Music files, right-click and open Properties:
In the Properies windows you need to change Copy to Output Directory property to Copy if newer:
Step 4:
By now, music resources are added. Now you need to create a representation class for the songs track. Right-click on AudioPlaybackAgent project and add a class. Give a desired name.
Track.cs
- using System;
- namespace AudioPlaybackAgent1
- {
- public class Track
- {
- public Uri Source
- {
- get;
- set;
- }
- public string Artist
- {
- get;
- set;
- }
- public string Title
- {
- get;
- set;
- }
- public string Album
- {
- get;
- set;
- }
- public Track(Uri source, string artist, string title, string album)
- {
- Source = source;
- Artist = artist;
- Title = title;
- Album = album;
- }
- }
- }
Step 5: Let us add required functionalities or modify default functionalities to perform various operations on an Audio file.
Returning List of Songs
Firstly, you need to return a list of songs. To return a list of songs use
GetSongs() in the AudioPlayer.cs class:
The above function is returning a list of Tracks.
To track the record number add a class level global variable. Let us say we have added:
Playing Song
Now we need to add a function to play a song. Create a function called
Play.
As Input parameter pass a BackGroundAudioPlayer object.
Create a Track to play. As a parameter you need to pass the source of the track, title, artist and album name.
After creation of the Track call the Play () method on the BackgroundAudioPlayer object.
Playing Next Song
To play the next song we need to track the current track record and increase it by 1. Once it is equal to the total number of songs in the list reinitialize it to 0.
Playing Previous Song
To play the previous song we need to track the current track record and decrease it by 1. Once it is less than 0 then reinitialize it to the maximum number of songs in the list.
Handling User actions
We need to handle user actions like Play, Stop, and Pause etc. For that we need to modify the overridden function on UserAction. Add the following switch case in the on UserAction method.
Handling Play state changes
To handle Play state changes add the following switch case in the OnPlayStateChanged() overridden method.
Finally, after adding all the required functions and making all modifications to the AudioPlayer.cs class it would look like below:
AudioPlayer.cs
- using System;
- using Microsoft.Phone.BackgroundAudio;
- using System.Collections.Generic;
- namespace AudioPlaybackAgent1
- {
- public class AudioPlayer: AudioPlayerAgent
- {
- static int CurrentTrackPlaying = 0;
-
-
-
-
-
-
-
-
-
-
- protected override void OnPlayStateChanged(BackgroundAudioPlayer player, AudioTrack track, PlayState playState) {
- base.OnPlayStateChanged(player, track, playState);
-
- switch (playState)
- {
- case PlayState.TrackEnded:
- PlayNext(player);
- break;
- }
- NotifyComplete();
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- protected override void OnUserAction(BackgroundAudioPlayer player, AudioTrack track, UserAction action,
- object param)
- {
- base.OnUserAction(player, track, action, param);
- switch (action)
- {
- case UserAction.Play:
- Play(player);
- break;
- case UserAction.Pause:
- player.Pause();
- break;
- case UserAction.Stop:
- player.Stop();
- break;
- case UserAction.FastForward:
- player.FastForward();
- break;
- case UserAction.Rewind:
- player.Rewind();
- break;
- case UserAction.SkipPrevious:
- PlayBack(player);
- break;
- case UserAction.SkipNext:
- PlayNext(player);
- break;
- case UserAction.Seek:
- player.Position = (TimeSpan) param;
- break;
- }
-
- NotifyComplete();
- }
-
-
-
-
-
-
-
-
-
-
-
- protected override void OnError(BackgroundAudioPlayer player, AudioTrack track, Exception error, bool isFatal)
- {
- base.OnError(player, track, error, isFatal);
-
- NotifyComplete();
- }
-
-
-
- protected override void OnCancel()
- {
- base.OnCancel();
- NotifyComplete();
- }
- private List < Track > GetSongs()
- {
- List < Track > lstSongs = new List < Track > ()
- {
- new Track(new Uri("TujheBhulaDia.mp3", UriKind.Relative),
- "Ranveer Kapoor and Priyanka Chopra",
- "Tumhe Bhula Dia",
- "Anajana Anjani"),
- new Track(new Uri("AasPassKhuda.mp3", UriKind.Relative),
- "Ranveer Kapoor and Priyanka Chopra",
- "Aas Paass Khuda",
- "Anajana Anjani"),
- new Track(new Uri("AnajanAnajni.mp3", UriKind.Relative),
- "Ranveer Kapoor and Priyanka Chopra",
- "Anajana Anjani",
- "Anajana Anjani")
- };
- return lstSongs;
- }
- private void Play(BackgroundAudioPlayer player)
- {
- var songs = GetSongs();
- var currentTrack = songs[CurrentTrackPlaying];
- player.Track = new AudioTrack(currentTrack.Source,
- currentTrack.Title,
- currentTrack.Artist,
- currentTrack.Album,
- null);
- player.Play();
- }
- private void PlayNext(BackgroundAudioPlayer player)
- {
- var songsCount = GetSongs().Count;
- if (++CurrentTrackPlaying >= songsCount)
- {
- CurrentTrackPlaying = 0;
- }
- Play(player);
- }
- private void PlayBack(BackgroundAudioPlayer player)
- {
- var songsCount = GetSongs().Count;
- if (--CurrentTrackPlaying < 0)
- {
- CurrentTrackPlaying = songsCount - 1;
- }
- Play(player);
- }
- }
- }
Step 6:
Add a reference for the
AudioPlaybackAgent1 project in the Phone Application project. For that right-click on Phone Application project and select
Add Reference. In the dialog box choose the
Projects tab and choose
AudioPlaybackAgent1.
Step 7:
To play audio we have done all modification and added codes to
AudioPlayBackAgent1 project. Now you need to create a UI in the Phone application project.
Create UI
Add three buttons for Play, Previous and Next
Add a Text block to display Track information
MainPage.xaml
After modifying the above code the user interface would look like:
We need to handle click events. Firstly, add the following namespaces:
And a click event for three buttons would be fairly straight forward.
We need only to call SkipNext and SkipPrevious methods on instance of BackgroundAudioPlayer.
Handling Background player Play State changed event
First you need to register an event in the constructor of MainPage class. This event would check if playing track is not null then would display information in the text block.
Handling user Navigation
Since audio would be playing in the background so when user will navigate should be displayed with meaningful information. For that you need to override OnNavigatedTo virtual method.
After adding all required events eventually MainPage.xaml.cs will be as below:
MainPage.xaml.cs
- using System;
- using System.Windows;
- using Microsoft.Phone.Controls;
- using System.Windows.Navigation;
- using Microsoft.Phone.BackgroundAudio;
- namespace PhoneApp1
- {
- public partial class MainPage: PhoneApplicationPage
- {
- public MainPage()
- {
- InitializeComponent();
- BackgroundAudioPlayer.Instance.PlayStateChanged += new EventHandler(Instance_PlayStateChanged);
- prevButton.Click += new RoutedEventHandler(prevButton_Click);
- nextButton.Click += new RoutedEventHandler(nextButton_Click);
- playButton.Click += new RoutedEventHandler(playButton_Click);
- }
- void Instance_PlayStateChanged(object sender, EventArgs e)
- {
- AudioTrack tracks = BackgroundAudioPlayer.Instance.Track;
- if (tracks != null)
- {
- txtCurrentTrack.Text = tracks.Title + " by " + tracks.Artist;
- }
- }
- void playButton_Click(object sender, RoutedEventArgs e)
- {
- if (PlayState.Playing == BackgroundAudioPlayer.Instance.PlayerState)
- {
- BackgroundAudioPlayer.Instance.Pause();
- playButton.Content = "play";
- } else {
- BackgroundAudioPlayer.Instance.Play();
- playButton.Content = "pause";
- }
- }
- void nextButton_Click(object sender, RoutedEventArgs e)
- {
- BackgroundAudioPlayer.Instance.SkipNext();
- }
- void prevButton_Click(object sender, RoutedEventArgs e)
- {
- BackgroundAudioPlayer.Instance.SkipPrevious();
- }
- protected override void OnNavigatedTo(NavigationEventArgs e)
- {
- if (PlayState.Playing == BackgroundAudioPlayer.Instance.PlayerState)
- {
- playButton.Content = "pause";
- txtCurrentTrack.Text = BackgroundAudioPlayer.Instance.Track.Title +
- " by " +
- BackgroundAudioPlayer.Instance.Track.Artist;
- } else
- {
- playButton.Content = "play";
- txtCurrentTrack.Text = "";
- }
- }
- }
- }
Step 8: BackGroundAudioPlayer can only play a song from a remote URL or file in Isolated Storage. For that you need to add a function in App.Xaml.cs.
Adding music File to Isolated Storage
In the above function the points to be noted are:
Files name are exactly the same as you added in previous steps.
The folder name is exactly the same.
The sequence of File names in string array files is exactly the same as you are returning from GetSongs() method.
Call this function in constructor of App class.
App.xaml.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Net;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Documents;
- using System.Windows.Input;
- using System.Windows.Media;
- using System.Windows.Media.Animation;
- using System.Windows.Navigation;
- using System.Windows.Shapes;
- using Microsoft.Phone.Controls;
- using Microsoft.Phone.Shell;
- using System.IO.IsolatedStorage;
- using System.Windows.Resources;
-
-
- namespace PhoneApp1
- {
- public partial class App : Application
- {
-
-
-
-
- public PhoneApplicationFrame RootFrame { get; private set; }
-
-
-
- public App()
- {
-
- UnhandledException += Application_UnhandledException;
-
-
- InitializeComponent();
-
-
- InitializePhoneApplication();
-
-
- if (System.Diagnostics.Debugger.IsAttached)
- {
-
- Application.Current.Host.Settings.EnableFrameRateCounter = true;
-
-
-
-
-
-
-
-
-
-
-
-
- PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;
- }
- CopyToIsolatedStorage();
-
- }
-
-
-
- private void Application_Launching(object sender, LaunchingEventArgs e)
- {
- }
-
-
-
- private void Application_Activated(object sender, ActivatedEventArgs e)
- {
- }
-
-
-
- private void Application_Deactivated(object sender, DeactivatedEventArgs e)
- {
- }
-
-
- private void Application_Closing(object sender, ClosingEventArgs e)
- {
- }
-
-
- private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
- {
- if (System.Diagnostics.Debugger.IsAttached)
- {
-
- System.Diagnostics.Debugger.Break();
- }
- }
-
-
- private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
- {
- if (System.Diagnostics.Debugger.IsAttached)
- {
-
- System.Diagnostics.Debugger.Break();
- }
- }
-
- private void CopyToIsolatedStorage()
- {
- using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
- {
- string[] files = new string[] { "TujheBhulaDia.mp3", "AasPassKhuda.mp3", "AnajanAnajni.mp3" };
-
- foreach (var _fileName in files)
- {
- if (!storage.FileExists(_fileName))
- {
- string _filePath = "Music/" + _fileName;
- StreamResourceInfo resource = Application.GetResourceStream(new Uri(_filePath, UriKind.Relative));
-
- using (IsolatedStorageFileStream file = storage.CreateFile(_fileName))
- {
- int chunkSize = 4096;
- byte[] bytes = new byte[chunkSize];
- int byteCount;
- while ((byteCount = resource.Stream.Read(bytes, 0, chunkSize)) > 0)
- {
- file.Write(bytes, 0, byteCount);
- }
- }
- }
- }
- }
- }
-
- #region Phone application initialization
-
-
- private bool phoneApplicationInitialized = false;
-
-
- private void InitializePhoneApplication()
- {
- if (phoneApplicationInitialized)
- return;
-
-
-
- RootFrame = new PhoneApplicationFrame();
- RootFrame.Navigated += CompleteInitializePhoneApplication;
-
-
- RootFrame.NavigationFailed += RootFrame_NavigationFailed;
-
-
- phoneApplicationInitialized = true;
- }
-
- private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)
- {
-
- if (RootVisual != RootFrame)
- RootVisual = RootFrame;
-
-
- RootFrame.Navigated -= CompleteInitializePhoneApplication;
- }
-
- #endregion
- }
- }
Step 9:
Now you have created a background music player. Press F5 to run the application.
Read more articles on Microsoft Phone Development: