Example #1
0
 public async Task StartScan(List <VideoListItem> selection, CancellationToken cancel)
 {
     await selection.ForEachAsync(5, cancel, async item => {
         Media VideoData = PlayerAccess.GetVideoById(item.MediaId.Value);
         if (VideoData != null && !item.IsBusy)
         {
             try {
                 // Query the server for media info.
                 SetStatus(item, VideoListItemStatusEnum.DownloadingInfo);
                 VideoInfo VInfo = await DownloadManager.GetDownloadInfoAsync(VideoData.DownloadUrl);
                 if (VInfo != null)
                 {
                     // Get the highest resolution format.
                     BestFormatInfo VideoFormat = DownloadBusiness.SelectBestFormat(VInfo.Streams);
                     if (VideoFormat == null || VideoFormat.BestVideo == null)
                     {
                         SetStatus(item, VideoListItemStatusEnum.Failed);
                     }
                     else
                     {
                         SetStatus(item, await IsHigherQualityAvailable(VideoFormat, Settings.NaturalGroundingFolder + VideoData.FileName));
                     }
                     if (VideoFormat != null && !string.IsNullOrEmpty(VideoFormat.StatusText))
                     {
                         SetStatus(item, item.Status, item.StatusText + string.Format(" ({0})", VideoFormat.StatusText));
                     }
                 }
                 else
                 {
                     SetStatus(item, VideoListItemStatusEnum.InvalidUrl);
                 }
             }
             catch {
                 SetStatus(item, VideoListItemStatusEnum.Failed);
             }
         }
     });
 }
Example #2
0
        public VideoListItemStatusEnum IsHigherQualityAvailableInternal(BestFormatInfo serverFile, string localFile, FFmpegProcess InfoReader)
        {
            string LocalFileExt = Path.GetExtension(localFile).ToLower();

            // If local file is FLV and there's another format available, it should be downloaded.
            if (LocalFileExt == ".flv" && serverFile.BestVideo.Container != Container.Flv)
            {
                return(VideoListItemStatusEnum.HigherQualityAvailable);
            }

            // Original VCD files and files of unrecognized extensions should not be replaced.
            if (!DownloadManager.DownloadedExtensions.Contains(LocalFileExt) || InfoReader?.VideoStream?.Format == "mpeg1video")
            {
                serverFile.StatusText = "Not from YouTube";
                return(VideoListItemStatusEnum.OK);
            }

            // For server file size, estimate 4% extra for audio. Estimate 30% advantage for VP9 format. non-DASH WebM is VP8 and doesn't have that bonus.
            long ServerFileSize = (long)(serverFile.BestVideo.Size * 1.04);

            if (DownloadManager.GetVideoEncoding(serverFile.BestVideo) == VideoEncoding.Vp9)
            {
                ServerFileSize = (long)(ServerFileSize * 1.3);
            }
            long LocalFileSize = new FileInfo(localFile).Length;

            if (InfoReader?.VideoStream?.Format == "vp9")
            {
                LocalFileSize = (long)(LocalFileSize * 1.3);
            }

            // If server resolution is better, download unless local file is bigger.
            int LocalFileHeight = InfoReader?.VideoStream?.Height ?? 0;

            if (DownloadManager.GetVideoHeight(serverFile.BestVideo) > LocalFileHeight)
            {
                if (ServerFileSize > LocalFileSize)
                {
                    return(VideoListItemStatusEnum.HigherQualityAvailable);
                }
                else if (ServerFileSize != 0)
                {
                    return(VideoListItemStatusEnum.OK);
                }
            }
            else if (DownloadManager.GetVideoHeight(serverFile.BestVideo) < LocalFileHeight)
            {
                // If local resolution is higher, keep.
                return(VideoListItemStatusEnum.OK);
            }

            // Choose whether to download only audio, only video, or both.
            bool DownloadVideo = false;
            bool DownloadAudio = false;

            // Is estimated server file size is at least 15% larger than local file (for same resolution), download.
            if (ServerFileSize > LocalFileSize * 1.15)
            {
                DownloadVideo = true;
            }
            // If PreferredFormat is set to a format, download that format.
            else if (Manager != null)
            {
                if (Manager.Options.PreferredFormat == SelectStreamFormat.MP4 && InfoReader.VideoStream?.Format == "vp9" && (DownloadManager.GetVideoEncoding(serverFile.BestVideo) == VideoEncoding.H264 || DownloadManager.GetVideoEncoding(serverFile.BestVideo) == VideoEncoding.H263))
                {
                    DownloadVideo = true;
                }
                else if (Manager.Options.PreferredFormat == SelectStreamFormat.VP9 && InfoReader.VideoStream?.Format == "h264" && (DownloadManager.GetVideoEncoding(serverFile.BestVideo) == VideoEncoding.Vp9 || DownloadManager.GetVideoEncoding(serverFile.BestVideo) == VideoEncoding.Vp8))
                {
                    DownloadVideo = true;
                }
            }

            if (InfoReader.AudioStream == null)
            {
                DownloadAudio = true;
            }
            // Can only upgrade is video length is same.
            else if (Math.Abs((InfoReader.FileDuration - serverFile.Duration).TotalSeconds) < 1)
            {
                // download audio and merge with local video.
                string        LocalAudio  = InfoReader.AudioStream.Format;
                AudioEncoding RemoteAudio = serverFile.BestAudio?.AudioEncoding ?? AudioEncoding.Aac;
                if (InfoReader.AudioStream.Bitrate == 0 && LocalAudio == "opus" || LocalAudio == "vorbis")
                {
                    InfoReader.AudioStream.Bitrate = 160; // FFmpeg doesn't return bitrate of Opus and Vorbis audios, but it's 160.
                }
                if (InfoReader.AudioStream.Bitrate == 0)
                {
                    InfoReader.AudioStream.Bitrate = GetAudioBitrateMuxe(localFile);
                }
                int  LocalAudioBitRate  = InfoReader.AudioStream.Bitrate;
                long ServerAudioBitRate = serverFile.BestAudio != null ? serverFile.BestAudio.Bitrate / 1024 : 0;
                // MediaInfo returns no bitrate for MKV containers with AAC audio.
                InfoReader.AudioStream.Bitrate = 160;
                if (LocalAudioBitRate > 0 || LocalFileExt != ".mkv")
                {
                    if ((LocalAudioBitRate == 0 || LocalAudioBitRate < ServerAudioBitRate * .8))
                    {
                        DownloadAudio = true;
                    }
                }
                if ((LocalAudio == "opus" && RemoteAudio == AudioEncoding.Vorbis) || (LocalAudio == "vorbis" && RemoteAudio == AudioEncoding.Opus))
                {
                    DownloadAudio = true;
                }
            }
            else
            {
                DownloadAudio = DownloadVideo;
            }

            if (DownloadVideo && DownloadAudio)
            {
                return(VideoListItemStatusEnum.HigherQualityAvailable);
            }
            else if (DownloadVideo)
            {
                return(VideoListItemStatusEnum.BetterVideoAvailable);
            }
            else if (DownloadAudio)
            {
                return(VideoListItemStatusEnum.BetterAudioAvailable);
            }

            return(VideoListItemStatusEnum.OK);
        }
 public static BestFormatInfo SelectBestFormat(MediaStreamInfoSet vinfo)
 {
     return(DownloadManager.SelectBestFormat(vinfo, Settings.SavedFile.Download));
 }