Coding4Fun Toolkit. The important thing is they both have these properties: ‘Value’ - the current fill amount of the bar, and ‘Maximum’ - the size of the bar. Make sure the ‘Maximum’ of the progress bar is set before the music starts playing:
progressBar.Maximum = BackgroundAudioPlayer.Instance.Track.Duration.TotalSeconds;
In order to have the bar keep track of the current position of the music track, a timer will need to be created. When the music starts, create a DispatchTimer and event handlers:
DispatcherTimer playTimer;
playTimer = new DispatcherTimer();
playTimer.Interval = TimeSpan.FromMilliseconds(1000); //one second
playTimer.Tick += new EventHandler(playTimer_Tick);
playTimer.Start();
I chose a second interval for the event to be called, as this is a reasonable time for music and it shouldn’t be too much of a strain on the phone. After every second the method ‘playTimer_Tick’ will be called. This is where we can update the progress bar:
public void playTimer_Tick(object sender, EventArgs e)
{
if (BackgroundAudioPlayer.Instance.PlayerState == PlayState.Playing)
{
progressBar.Value = BackgroundAudioPlayer.Instance.Position.TotalSeconds;
try
{
CurrentTime.Text = String.Format(@"{0:hh\:mm\:ss}",
BackgroundAudioPlayer.Instance.Position).Remove(8);
}
catch
{
CurrentTime.Text = String.Format(@"{0:hh\:mm\:ss}",
BackgroundAudioPlayer.Instance.Position);
}
}
}
The current time is a Text Block element as you can see in the bottom left of the screenshot. It’s nested in a try catch because I found the ‘Remove(8)’ function, which is necessary to remove the miliseconds from the time, can cause a rare exception when the string is less than 8 characters. If this happens, I just perform the same assignment without the function.
And that’s basically it to get the audio progress bar working. If you change track, I suggest having an event to change the Maximum value of the bar to the next track length, like this:
BackgroundAudioPlayer.Instance.PlayStateChanged += new EventHandler(audio_StateChanged);
public void audio_StateChanged(object sender, EventArgs e)
{
if (BackgroundAudioPlayer.Instance.PlayerState == PlayState.Playing)
{
progressBar.Maximum = BackgroundAudioPlayer.Instance.Track.Duration.TotalSeconds;
try
{
EndTime.Text = String.Format(@"{0:hh\:mm\:ss}",
BackgroundAudioPlayer.Instance.Track.Duration).Remove(8);
}
catch
{
EndTime.Text = String.Format(@"{0:hh\:mm\:ss}",
BackgroundAudioPlayer.Instance.Track.Duration);
}
}
}
Additionally, you can use the progress bar as a scrub bar so users can change the position of the track themselves…
You can use an event for when the user finishes changing the slider value to change the track position like this:
ManipulationCompleted="scrubChange" //In the slider XAML
private void scrubChange(object sender, RoutedEventArgs e)
{
if (BackgroundAudioPlayer.Instance.PlayerState == PlayState.Playing)
{
TimeSpan ts = new TimeSpan(0, 0, (int)progressBar.Value);
BackgroundAudioPlayer.Instance.Position = ts;
}
}
Then, most importantly, in the audio player agent code you need to add this for it to work:
protected override void OnUserAction(BackgroundAudioPlayer player, AudioTrack track, UserAction action, object param)
{
switch (action)
{
...
...
case UserAction.Seek:
player.Position = (TimeSpan)param;
break;
}
NotifyComplete();
}
That’s about it. You could use a boolean to stop the progress slider from updating while the user changes the position, but I’ll leave that to you. I hope this has been helpful to someone :)