/// <summary>
 /// Called when [playback completed].
 /// </summary>
 /// <param name="player">The player.</param>
 /// <param name="items">The items.</param>
 internal void OnPlaybackCompleted(BaseMediaPlayer player, List<BaseItemDto> items)
 {
     EventHelper.QueueEventIfNotNull(PlaybackCompleted, this, new PlaybackStopEventArgs
     {
         Items = items,
         Player = player
     }, _logger);
 }
 /// <summary>
 /// Called when [playback started].
 /// </summary>
 /// <param name="player">The player.</param>
 /// <param name="options">The options.</param>
 /// <param name="playerConfiguration">The player configuration.</param>
 private void OnPlaybackStarted(BaseMediaPlayer player, PlayOptions options, PlayerConfiguration playerConfiguration)
 {
     EventHelper.QueueEventIfNotNull(PlaybackStarted, this, new PlaybackEventArgs
     {
         Options = options,
         Player = player,
         PlayerConfiguration = playerConfiguration
     }, _logger);
 }
        /// <summary>
        /// Plays the specified player.
        /// </summary>
        /// <param name="player">The player.</param>
        /// <param name="options">The options.</param>
        /// <param name="playerConfiguration">The player configuration.</param>
        /// <returns>Task.</returns>
        private async Task Play(BaseMediaPlayer player, PlayOptions options, PlayerConfiguration playerConfiguration)
        {
            if (options.Shuffle)
            {
                options.Items = options.Items.Shuffle().ToList();
            }

            var firstItem = options.Items[0];

            if (options.StartPositionTicks == 0 && player.SupportsMultiFilePlayback && firstItem.IsVideo && firstItem.LocationType == LocationType.FileSystem)
            {
                try
                {
                    var intros = await App.Instance.ApiClient.GetIntrosAsync(firstItem.Id, App.Instance.CurrentUser.Id);

                    options.Items.InsertRange(0, intros.Select(GetPlayableItem));
                }
                catch (HttpException ex)
                {
                    _logger.ErrorException("Error retrieving intros", ex);
                }
            }

            await player.Play(options, playerConfiguration);

            OnPlaybackStarted(player, options, playerConfiguration);
        }
        /// <summary>
        /// Resets the button visibilities.
        /// </summary>
        /// <param name="player">The player.</param>
        private void ResetButtonVisibilities(BaseMediaPlayer player)
        {
            Dispatcher.Invoke(() =>
            {
                PlayButton.Visibility = player != null && player.PlayState == PlayState.Paused ? Visibility.Visible : Visibility.Collapsed;
                PauseButton.Visibility = player != null && player.CanPause && player.PlayState == PlayState.Playing ? Visibility.Visible : Visibility.Collapsed;

                StopButton.Visibility = player != null ? Visibility.Visible : Visibility.Collapsed;
                MuteButton.Visibility = player != null && player.CanMute ? Visibility.Visible : Visibility.Collapsed;
                VolumeUpButton.Visibility = player != null && player.CanControlVolume ? Visibility.Visible : Visibility.Collapsed;
                VolumeDownButton.Visibility = player != null && player.CanControlVolume ? Visibility.Visible : Visibility.Collapsed;

                var isSeekabke = player != null && player.CanSeek && player.CurrentMedia != null;
                SeekGrid.Visibility = isSeekabke ? Visibility.Visible : Visibility.Collapsed;

                var canSeekChapters = isSeekabke && player.CurrentMedia.Chapters != null && player.CurrentMedia.Chapters.Count > 1;

                NextChapterButton.Visibility = canSeekChapters ? Visibility.Visible : Visibility.Collapsed;
                PreviousChapterButton.Visibility = canSeekChapters ? Visibility.Visible : Visibility.Collapsed;
            });
        }