/// <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); }