/// <summary>
        /// Selects which video will be played next.
        /// </summary>
        /// <param name="queuePos">The video position to select. 0 for current, 1 for next.</param>
        /// <param name="maintainCurrent">True to keep the next video and only select alternate options, false to change next video.</param>
        /// <param name="attempts">The number of attemps already made, to avoid infinite loop.</param>
        /// <returns>Whether the file is downloading.</returns>
        private async Task <bool> SelectNextVideoAsync(int queuePos, bool maintainCurrent, int attempts)
        {
            bool IsDownloading = false;

            if (attempts > 3)
            {
                nextVideo = null;
                return(false);
            }

            timerChangeConditions.Stop();

            // Get video conditions
            GetConditionsEventArgs e = new GetConditionsEventArgs(FilterSettings);

            e.QueuePos = queuePos;
            Application.Current.Dispatcher.Invoke(() => GetConditions?.Invoke(this, e));

            // Select random video matching conditions.
            List <Media> Result = PlayerAccess.SelectVideo(FilterSettings.Update(playedVideos, Settings.SavedFile.AutoDownload), 3, maintainCurrent ? nextVideo : null);

            lastSearchResultCount = FilterSettings.TotalFound;

            // If no video is found, try again while increasing tolerance
            if (Result == null)
            {
                e = new GetConditionsEventArgs(FilterSettings);
                e.IncreaseTolerance = true;
                Application.Current.Dispatcher.Invoke(() => GetConditions?.Invoke(this, e));
                Result = PlayerAccess.SelectVideo(FilterSettings.Update(null, Settings.SavedFile.AutoDownload), 3, maintainCurrent ? nextVideo : null);
                FilterSettings.TotalFound = lastSearchResultCount;
            }

            if (Result != null)
            {
                if (nextVideo != null)
                {
                    CancelNextDownload(nextVideo);
                }
                NextVideoOptions = new ObservableCollection <Media>(Result);
                nextVideo        = Result.FirstOrDefault();
                IsDownloading    = await PrepareNextVideoAsync(queuePos, attempts).ConfigureAwait(false);
            }

            timerChangeConditions.Stop();
            Application.Current.Dispatcher.Invoke(() => PlaylistChanged?.Invoke(this, new EventArgs()));

            return(IsDownloading);
        }