コード例 #1
0
        private async Task QueryAsync()
        {
            QueryButton.IsEnabled    = false;
            DownloadButton.IsEnabled = false;
            downloadInfo             = await DownloadManager.GetDownloadInfoAsync(video.DownloadUrl);

            if (downloadInfo != null)
            {
                TitleTextBox.Text = downloadInfo.Info.Title;
                options           = new DownloadOptions()
                {
                    PreferredFormat       = (SelectStreamFormat)PreferredFormatCombo.SelectedIndex,
                    PreferredAudio        = (SelectStreamFormat)PreferredAudioCombo.SelectedIndex,
                    MaxQuality            = (int)MaxDownloadQualityCombo.SelectedValue,
                    SimultaneousDownloads = 2
                };
                BestFormatInfo StreamInfo = DownloadManager.SelectBestFormat(downloadInfo.Streams, options);
                DownloadVideoText.Text = GetStreamDescription(StreamInfo.BestVideo);
                DownloadAudioText.Text = GetStreamDescription(StreamInfo.BestAudio);
                bestFormat             = StreamInfo;
                StreamOption_Click(null, null);
            }
            else
            {
                TitleTextBox.Text = "Invalid URL";
            }
            QueryButton.IsEnabled = true;
        }
コード例 #2
0
        /// <summary>
        /// Returns whether the local file should be replaced by the YouTube version.
        /// </summary>
        /// <param name="serverFile">The information of the available server file.</param>
        /// <param name="localFile">A path to the local file.</param>
        /// <returns>True if the local file should be replaced.</returns>
        public async Task <VideoListItemStatusEnum> IsHigherQualityAvailable(BestFormatInfo serverFile, string localFile)
        {
            // If there is no local file, it should be downloaded.
            if (!File.Exists(localFile))
            {
                return(VideoListItemStatusEnum.HigherQualityAvailable);
            }

            // Read local file info.
            string        LocalFileExt = Path.GetExtension(localFile).ToLower();
            FFmpegProcess InfoReader   = await Task.Run(() => MediaInfo.GetFileInfo(localFile));

            LastInfoReader = InfoReader;

            VideoListItemStatusEnum Result = IsHigherQualityAvailableInternal(serverFile, localFile, InfoReader);

            if (Result == VideoListItemStatusEnum.OK)
            {
                // Check if video has right container.
                string VFormat = InfoReader.VideoStream?.Format;
                string AFormat = InfoReader.AudioStream?.Format;
                VFormat = VFormat?.ToLower();
                AFormat = AFormat?.ToLower();
                if (VFormat == "h264" && (AFormat == null || AFormat == "aac") && LocalFileExt != ".mp4")
                {
                    return(VideoListItemStatusEnum.WrongContainer);
                }
                else if (VFormat == "webm" && (AFormat == null || AFormat == "opus" || AFormat == "vorbis") && LocalFileExt != ".webm")
                {
                    return(VideoListItemStatusEnum.WrongContainer);
                }
                else
                {
                    return(VideoListItemStatusEnum.OK);
                }
            }
            else
            {
                return(Result);
            }
        }
コード例 #3
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);
             }
         }
     });
 }
コード例 #4
0
        private async void QueryButton_Click(object sender, RoutedEventArgs e)
        {
            GridInfo.Visibility      = Visibility.Visible;
            ErrorText.Visibility     = Visibility.Hidden;
            QueryButton.IsEnabled    = false;
            DownloadButton.IsEnabled = false;
            VideoUrl           = DownloadUrl.Text;
            TitleText.Text     = "";
            VideoText.Text     = "";
            AudioText.Text     = "";
            ContainerText.Text = "";
            Info = await DownloadManager.GetDownloadInfoAsync(VideoUrl);

            if (Info != null)
            {
                TitleText.Text      = Info.Info.Title;
                TitleText.ToolTip   = Info.Info.Title;
                GridInfo.Visibility = Visibility.Visible;
                Options             = new DownloadOptions()
                {
                    PreferredFormat       = (SelectStreamFormat)PreferredFormatCombo.SelectedIndex,
                    PreferredAudio        = (SelectStreamFormat)PreferredAudioCombo.SelectedIndex,
                    MaxQuality            = (int)MaxDownloadQualityCombo.SelectedValue,
                    SimultaneousDownloads = 2
                };
                BestFormatInfo StreamInfo = DownloadManager.SelectBestFormat(Info.Streams, Options);
                VideoText.Text           = GetStreamDescription(StreamInfo.BestVideo);
                AudioText.Text           = GetStreamDescription(StreamInfo.BestAudio);
                ContainerText.Text       = DownloadManager.GetFinalExtension(StreamInfo.BestVideo, StreamInfo.BestAudio);
                DownloadButton.IsEnabled = true;
            }
            else
            {
                GridInfo.Visibility  = Visibility.Hidden;
                ErrorText.Visibility = Visibility.Visible;
            }
            QueryButton.IsEnabled = true;
        }
コード例 #5
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);
        }