/// <summary>
        /// Returns the best format from the list in this order of availability: WebM, Mp4 or Flash.
        /// Mp4 will be chosen if WebM is over 35% smaller.
        /// </summary>
        /// <param name="list">The list of videos to chose from.</param>
        /// <returns>The best format available.</returns>
        public static BestFormatInfo SelectBestFormat(MediaStreamInfoSet vstream, DownloadOptions options)
        {
            var MaxResolutionList = (from v in vstream.Audio.Cast <MediaStreamInfo>().Union(vstream.Video).Union(vstream.Muxed)
                                     where (options.MaxQuality == 0 || GetVideoHeight(v) <= options.MaxQuality)
                                     orderby GetVideoHeight(v) descending
                                     orderby GetVideoFrameRate(v) descending
                                     select v).ToList();

            MaxResolutionList = MaxResolutionList.Where(v => GetVideoHeight(v) == GetVideoHeight(MaxResolutionList.First())).ToList();
            //double Framerate = GetVideoFrameRate(MaxResolutionList.FirstOrDefault());
            //if (Framerate > 0)
            //    MaxResolutionList = MaxResolutionList.Where(v => GetVideoFrameRate(v) == Framerate).ToList();

            MediaStreamInfo BestVideo = (from v in MaxResolutionList
                                         // WebM VP9 encodes ~30% better. non-DASH is VP8 and isn't better than MP4.
                                         let Preference = (int)((GetVideoEncoding(v) == VideoEncoding.Vp9) ? v.Size * 1.3 : v.Size)
                                                          where options.PreferredFormat == SelectStreamFormat.Best ||
                                                          (options.PreferredFormat == SelectStreamFormat.MP4 && GetVideoEncoding(v) == VideoEncoding.H264) ||
                                                          (options.PreferredFormat == SelectStreamFormat.VP9 && GetVideoEncoding(v) == VideoEncoding.Vp9)
                                                          orderby Preference descending
                                                          select v).FirstOrDefault();

            if (BestVideo == null)
            {
                BestVideo = MaxResolutionList.FirstOrDefault();
            }
            if (BestVideo != null)
            {
                BestFormatInfo Result = new BestFormatInfo {
                    BestVideo = BestVideo,
                    BestAudio = SelectBestAudio(vstream, options)
                };
                return(Result);
            }
            else
            {
                return(null);
            }
        }
        private async Task StartDownloadAsync(DownloadItem downloadInfo)
        {
            downloadInfo.Status = DownloadStatus.Initializing;

            // Query the download URL for the right file.
            string             VideoId = null;
            Video              VInfo   = null;
            MediaStreamInfoSet VStream = null;

            if (YoutubeClient.TryParseVideoId(downloadInfo.Url, out VideoId))
            {
                try {
                    var T1 = youtube.GetVideoAsync(VideoId);
                    var T2 = youtube.GetVideoMediaStreamInfosAsync(VideoId);
                    await Task.WhenAll(new Task[] { T1, T2 });

                    VInfo   = T1.Result;
                    VStream = T2.Result;
                }
                catch {
                }
            }

            if (VStream == null)
            {
                downloadInfo.Status = DownloadStatus.Failed;
                RaiseCallback(downloadInfo);
                return;
            }

            // Get the highest resolution format.
            BestFormatInfo BestFile = DownloadManager.SelectBestFormat(VStream, downloadInfo.Options ?? Options);

            BestFile.Duration = VInfo.Duration;

            if (BestFile.BestVideo != null && (downloadInfo.Action == DownloadAction.Download || downloadInfo.Action == DownloadAction.DownloadVideo))
            {
                downloadInfo.Files.Add(new FileProgress()
                {
                    Type        = StreamType.Video,
                    Url         = BestFile.BestVideo.Url,
                    Destination = downloadInfo.DestinationNoExt + GetVideoExtension(DownloadManager.GetVideoEncoding(BestFile.BestVideo)),
                    Stream      = BestFile.BestVideo,
                    BytesTotal  = BestFile.BestVideo.Size
                });
            }

            if (BestFile.BestAudio != null && (downloadInfo.Action == DownloadAction.Download || downloadInfo.Action == DownloadAction.DownloadAudio))
            {
                downloadInfo.Files.Add(new FileProgress()
                {
                    Type        = StreamType.Audio,
                    Url         = BestFile.BestAudio.Url,
                    Destination = downloadInfo.DestinationNoExt + GetAudioExtension(BestFile.BestAudio.AudioEncoding),
                    Stream      = BestFile.BestAudio,
                    BytesTotal  = BestFile.BestAudio.Size
                });
            }

            // Add extension if Destination doesn't already include it.
            string Ext = DownloadManager.GetFinalExtension(BestFile.BestVideo, BestFile.BestAudio);

            if (!downloadInfo.Destination.ToLower().EndsWith(Ext))
            {
                downloadInfo.Destination += Ext;
            }

            await DownloadFilesAsync(downloadInfo).ConfigureAwait(false);
        }