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