Пример #1
0
        /// <inheritdoc />
        public async Task DownloadVideoAsync(string videoId, string filePath, string format, ConversionPreset preset,
                                             IProgress <double>?progress = null, CancellationToken cancellationToken = default)
        {
            var streamManifest = await _youtube.Videos.Streams.GetManifestAsync(videoId);

            await DownloadVideoAsync(streamManifest, filePath, format, preset, progress, cancellationToken);
        }
Пример #2
0
        /// <inheritdoc />
        public async Task DownloadAndProcessMediaStreamsAsync(IReadOnlyList <IStreamInfo> streamInfos,
                                                              string filePath, string format, ConversionPreset preset,
                                                              IProgress <double>?progress = null, CancellationToken cancellationToken = default)
        {
            // Determine if transcoding is required for at least one of the streams
            var avoidTranscoding = !streamInfos.Any(s => IsTranscodingRequired(s.Container, format));

            // Set up progress-related stuff
            var progressMixer           = progress != null ? new ProgressMixer(progress) : null;
            var downloadProgressPortion = avoidTranscoding ? 0.99 : 0.15;
            var ffmpegProgressPortion   = 1 - downloadProgressPortion;
            var totalContentLength      = streamInfos.Sum(s => s.Size.TotalBytes);

            // Keep track of the downloaded streams
            var streamFilePaths = new List <string>();

            try
            {
                // Download all streams
                foreach (var streamInfo in streamInfos)
                {
                    // Generate file path
                    var streamIndex    = streamFilePaths.Count + 1;
                    var streamFilePath = $"{filePath}.stream-{streamIndex}.tmp";

                    // Add file path to list
                    streamFilePaths.Add(streamFilePath);

                    // Set up download progress handler
                    var streamDownloadProgress =
                        progressMixer?.Split(downloadProgressPortion * streamInfo.Size.TotalBytes / totalContentLength);

                    // Download stream
                    await _youtube.Videos.Streams.DownloadAsync(streamInfo, streamFilePath, streamDownloadProgress, cancellationToken);
                }

                // Set up process progress handler
                var ffmpegProgress = progressMixer?.Split(ffmpegProgressPortion);

                // Process streams (mux/transcode/etc)
                await _ffmpeg.ConvertAsync(filePath, streamFilePaths, format, preset, avoidTranscoding, ffmpegProgress, cancellationToken);

                // Report completion in case there are rounding issues in progress reporting
                progress?.Report(1);
            }
            finally
            {
                // Delete all stream files
                foreach (var streamFilePath in streamFilePaths)
                {
                    File.Delete(streamFilePath);
                }
            }
        }
Пример #3
0
        /// <inheritdoc />
        public async Task DownloadVideoAsync(StreamManifest streamManifest, string filePath, string format, ConversionPreset preset,
                                             IProgress <double>?progress = null, CancellationToken cancellationToken = default)
        {
            var streamInfos = GetBestMediaStreamInfos(streamManifest, format).ToArray();

            await DownloadAndProcessMediaStreamsAsync(streamInfos, filePath, format, preset, progress, cancellationToken);
        }