John Doe
John Doe

Reputation: 1

UWP slider won't move during playback

I have a slider on a page that shows the playback progress of an audio. It is not moving, however. Also, it cannot be moved by dragging, it always stays on 0.I am using the slider's PointerPressed and PointerReleased events to do that.

Strangely, if i put a breakpoint on the slider.Maximum = mediaPlayer.PlaybackSession.NaturalDuration.TotalSeconds; in the PlayMedia method, after hitting it and resuming, the slider works fine!!!

Below is some of the relevant code.

<Slider x:Name="slider" Width="Auto" Height="30" Margin="10,0,10,0" VerticalAlignment="Center" />


public sealed partial class MoreRuqya : Page
{
    private bool bMediaStop = false;
    private MediaPlayer mediaPlayer = new MediaPlayer();
    private int playIndex = 0;  //media index
    private DispatcherTimer timer = new DispatcherTimer();
    private DownloadFile _download = new DownloadFile();

    private void Page_Loaded(object sender, RoutedEventArgs e)
    {
        if (App.lstMoreRuqya == null)
        {
            App.lstMoreRuqya = DataLoader.LoadMoreRuqya();
        }

        var result = from rq in App.lstMoreRuqya group rq by rq.Category into grp orderby grp.Key select grp;

        cvsMoreRuqya.Source = result;

        mediaPlayer.MediaEnded += MediaPlayer_MediaEnded;
        mediaPlayer.BufferingStarted += MediaPlayer_BufferingStarted;
        mediaPlayer.BufferingEnded += MediaPlayer_BufferingEnded;

        //*************needed for PointerPressed & PointerReleased events to trigger**********************
        slider.AddHandler(PointerPressedEvent, new PointerEventHandler(Slider_PointerPressed), true);
        slider.AddHandler(PointerReleasedEvent, new PointerEventHandler(slider_PointerReleased), true);
        //************************************************************************************************

        _download.Status += _download_Status;

        if (mediaPlayer.PlaybackSession.PlaybackState == MediaPlaybackState.Playing)
        {
            Play.Symbol = Symbol.Pause;
        }
        else
        {
            Play.Symbol = Symbol.Play;
        }

        InitializeTimer();
    }

    private void MediaPlayer_BufferingStarted(MediaPlayer sender, object args)
    {
        lblMediaInfo.Text = "Buffering...";
    }

    private void MediaPlayer_BufferingEnded(MediaPlayer sender, object args)
    {
        slider.Maximum = mediaPlayer.PlaybackSession.NaturalDuration.TotalSeconds;
    }

    private void MediaPlayer_MediaEnded(MediaPlayer sender, object args)
    {
        PlayNext();
    }

    private void btnPlay_Click(object sender, RoutedEventArgs e)
    {
        //filter list for only selected items
        var selected = from rq in App.lstMoreRuqya where rq.isSelected == true select rq;
        App.lstSelectedMoreRuqya = selected.ToList();

        if (Play.Symbol.Equals(Symbol.Play))
        {
            if (mediaPlayer.PlaybackSession.PlaybackState == MediaPlaybackState.Paused & !bMediaStop)
            {
                mediaPlayer.Play();
            }
            else
            {
                bMediaStop = false;
                PlayMedia(playIndex);
            }

            Play.Symbol = Symbol.Pause;

            timer.Start();
        }
        else if (Play.Symbol.Equals(Symbol.Pause))
        {
            mediaPlayer.Pause();

            Play.Symbol = Symbol.Play;

            timer.Stop();
        }
    }

    private void PlayMedia(int index)
    {
        //if past last item in playlist & last item has been repeated
        if (index > App.lstSelectedMoreRuqya.Count || App.lstSelectedMoreRuqya.Count == 0)
        {
            Play.Symbol = Symbol.Play;

            return;
        }

        string uri = App.lstSelectedMoreRuqya[playIndex].urlPath;

        mediaPlayer.Source = MediaSource.CreateFromUri(new Uri(uri));
        mediaPlayer.AutoPlay = true;

        slider.Maximum = mediaPlayer.PlaybackSession.NaturalDuration.TotalSeconds;
    }

    private void timer_Tick(object sender, object e)
    {
        if (mediaPlayer.PlaybackSession.PlaybackState == MediaPlaybackState.None)
        {
            lblMediaInfo.Text = "";
        }

        if (mediaPlayer.PlaybackSession.PlaybackState == MediaPlaybackState.Playing)
        {
            slider.Value = Convert.ToDouble(mediaPlayer.PlaybackSession.Position.Seconds);
            lblMediaInfo.Text = App.lstSelectedMoreRuqya[playIndex].RuqyaName + " (" + FormatDuration(mediaPlayer.PlaybackSession.Position) + "/" + FormatDuration(mediaPlayer.PlaybackSession.NaturalDuration) + ")";
        }
    }

    private void InitializeTimer()
    {
        timer.Interval = TimeSpan.FromMilliseconds(1000);
        timer.Tick += timer_Tick;

        timer.Start();
    }

    private void Slider_PointerPressed(object sender, PointerRoutedEventArgs e)
    {
        timer.Stop();
    }

    private void slider_PointerReleased(object sender, PointerRoutedEventArgs e)
    {
        mediaPlayer.PlaybackSession.Position = TimeSpan.FromSeconds(slider.Value);
        timer.Start();
    }
}

Upvotes: 0

Views: 441

Answers (1)

Sunteen Wu
Sunteen Wu

Reputation: 10627

Also, it cannot be moved by dragging, it always stays on 0

It is caused by the following code line,

slider.Maximum = mediaPlayer.PlaybackSession.NaturalDuration.TotalSeconds;

getting the maximum value of slider to 0, so that you cannot set value for the slider more than 0. You can add System.Diagnostics.Debug.WriteLine(slider.Maximum); to test about it. The reason for why NaturalDuration.TotalSeconds get the 0 result should be the PlaybackSession of the MediaPlayer is not completed opened.

The better way to resolve this is to get the duration of MediaSource after the source OpenOperationCompleted. For example:

private void PlayMedia(int index)
{ 
    MediaSource mediasource = MediaSource.CreateFromUri(new Uri("ms-appx:///Assets/test.mp3")); 
    mediasource.OpenOperationCompleted += Mediasource_OpenOperationCompleted;
    mediaPlayer.Source = mediasource;
    mediaPlayer.AutoPlay = true; 
    //slider.Maximum = mediaPlayer.PlaybackSession.NaturalDuration.Seconds;
    //System.Diagnostics.Debug.WriteLine(slider.Maximum);
} 

private async void Mediasource_OpenOperationCompleted(MediaSource sender, MediaSourceOpenOperationCompletedEventArgs args)
{       
    var _duration = sender.Duration.GetValueOrDefault();
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
    {           
        slider.Minimum = 0;
        slider.Maximum = _duration.TotalSeconds;
        slider.StepFrequency = 1;
    });
}

More details please reference Use MediaTimelineController to synchronize content across multiple players. This section contains a slider sample.

Upvotes: 2

Related Questions