Slider progress bar with MediaElement Windows Phone 8.1

934 views Asked by At

I am working within a Windows Phone 8.1 (non SilverLight) application. I have a MediaElement AudioPlayer that plays audio files. I also have a Slider AudioPlayerSeek that I want 'hooked' to the MediaElement, so that it moves as the audio is playing.

I have gone through this tutorial word for word, but still can't get it to work. When I play my audio (clicking on an item in a ListView), the audio plays, but the Slider doesn't move!

private DispatcherTimer _timer;
private bool _sliderpressed = false;

// Constructor
public MainPage()
{
    InitializeComponent();
    NavigationCacheMode = NavigationCacheMode.Required;
    AudioPlayerSeek.ValueChanged += AudioPlayerSeek_ValueChanged;
    InitializeAudioRecording();
    DataContext = App.ViewModel;
}

// Called when I select my Audio file in the ListView
private async void Selector_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    // Cast to XAML ListView
    var listView = sender as ListView;

    // Verify we have ListView
    if (listView == null) { return; }

    var listVmItem = listView.SelectedItem as RecordFileVm;

    if (listVmItem != null)
    {
        var file2 = await _finalStorageFolder.GetFileAsync(listVmItem.FileName);
        var stream = (await file2.OpenReadAsync()).AsStream().AsRandomAccessStream();
        AudioPlayer.SetSource(stream, file2.ContentType);
        TimeSpan recordingTime = AudioPlayer.NaturalDuration.TimeSpan;
        AudioPlayerSeek.Maximum = recordingTime.TotalSeconds;
        AudioPlayerSeek.SmallChange = 1;
        AudioPlayerSeek.LargeChange = Math.Min(10, recordingTime.Seconds / 10);
        AudioPlayer.MediaOpened += AudioPlayer_MediaOpened;
        AudioPlayer.CurrentStateChanged += AudioPlayer_CurrentStateChanged;
        AudioPlayer.Play();
    }

    // Clear selection
    listView.SelectedItem = null;
}

private double SliderFrequency(TimeSpan timevalue)
{
    double stepfrequency = -1;

    double absvalue = (int)Math.Round(timevalue.TotalSeconds, MidpointRounding.AwayFromZero);

    stepfrequency = (int)(Math.Round(absvalue / 100));

    if (timevalue.TotalMinutes >= 10 && timevalue.TotalMinutes < 30)
    {
        stepfrequency = 10;
    }
    else if (timevalue.TotalMinutes >= 30 && timevalue.TotalMinutes < 60)
    {
        stepfrequency = 30;
    }
    else if (timevalue.TotalHours >= 1)
    {
        stepfrequency = 60;
    }

    if (stepfrequency == 0) stepfrequency += 1;

    if (stepfrequency == 1)
    {
        stepfrequency = absvalue / 100;
    }

    return stepfrequency;
}

void AudioPlayerSeek_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
{
    if (!_sliderpressed)
    {
        AudioPlayer.Position = TimeSpan.FromSeconds(e.NewValue);
    }
}

private void SetupTimer()
{
    _timer = new DispatcherTimer();
    _timer.Interval = TimeSpan.FromSeconds(AudioPlayerSeek.StepFrequency);
    StartTimer();
}

private void _timer_Tick(object sender, object e)
{
    if (!_sliderpressed)
    {
        AudioPlayerSeek.Value = AudioPlayer.Position.TotalSeconds;
    }
}

private void StartTimer()
{
    _timer.Tick += _timer_Tick;
    _timer.Start();
}

I believe that is the relevant code. Can someone please tell me how I can synchronize my slider so that it moves with the playing media (audio).

Thank you.

1

There are 1 answers

2
Jon On BEST ANSWER

You are setting things up in the wrong order. Try changing it to this:

 if (listVmItem != null)
{
    var file2 = await _finalStorageFolder.GetFileAsync(listVmItem.FileName);
    var stream = (await file2.OpenReadAsync()).AsStream().AsRandomAccessStream();
    AudioPlayer.MediaOpened += AudioPlayer_MediaOpened;
    AudioPlayer.CurrentStateChanged += AudioPlayer_CurrentStateChanged;
    AudioPlayer.SetSource(stream, file2.ContentType);
    AudioPlayer.Play();
}

and move these calls to the MediaOpened handler:

    TimeSpan recordingTime = AudioPlayer.NaturalDuration.TimeSpan;
    AudioPlayerSeek.Maximum = recordingTime.TotalSeconds;
    AudioPlayerSeek.SmallChange = 1;
    AudioPlayerSeek.LargeChange = Math.Min(10, recordingTime.Seconds / 10);