/// <summary> /// Downloads audio and saves it to the provided audioPath folder /// </summary> /// <param name="id">id of the youtube video</param> /// <param name="audioPath">Path where file should be saved without extension at the end</param> /// <returns></returns> public async Task DownloadAudioAsync(string id, string audioPath) { MediaStreamInfoSet streamInfoSet = await client.GetVideoMediaStreamInfosAsync(id); var audioInfo = streamInfoSet.Audio.WithHighestBitrate(); await client.DownloadMediaStreamAsync(audioInfo, audioPath); }
public static async Task DownloadMusic(string url, FileInfo desinationFile) { if (desinationFile.Exists) { Console.WriteLine($"\t{desinationFile.Name} already downloaded. Skipping..."); return; } Console.Write($"\t-Downloading {desinationFile.Name}..."); //Get video var vidId = YoutubeClient.ParseVideoId(url); var streamInfo = await _client.GetVideoMediaStreamInfosAsync(vidId); var stream = streamInfo.Audio.WithHighestBitrate(); var ext = stream.Container.GetFileExtension(); var videoDownloadFile = Path.ChangeExtension(Path.GetTempFileName(), ext); await _client.DownloadMediaStreamAsync(stream, videoDownloadFile); //Write video to file Console.Write($"Done. Converting to mp3..."); //Extract mp3 from video var result = await Conversion.Convert(videoDownloadFile, desinationFile.FullName) .Start(); Console.WriteLine($"Done"); }
public async Task <string> Download(string url, Action <int> progressCallback, string newPath, bool onlyMusic) { string result = null; var streamInfoSet = await client.GetVideoMediaStreamInfosAsync(url); MediaStreamInfo stream = null; if (onlyMusic) { stream = streamInfoSet.Audio.WithHighestBitrate(); } else { stream = streamInfoSet.Muxed.WithHighestVideoQuality(); } var fileExtension = stream.Container.GetFileExtension(); result = newPath + "." + fileExtension; var fileStream = File.Create(result); var progress = new DownladProgress(progressCallback); await client.DownloadMediaStreamAsync(stream, fileStream, progress); return(result); }
/// <inheritdoc /> public async Task DownloadAndProcessMediaStreamsAsync(IReadOnlyList <MediaStreamInfo> mediaStreamInfos, string filePath, string format, IProgress <double> progress = null, CancellationToken cancellationToken = default(CancellationToken)) { mediaStreamInfos.GuardNotNull(nameof(mediaStreamInfos)); filePath.GuardNotNull(nameof(filePath)); format.GuardNotNull(nameof(format)); // Determine if transcoding is required for at least one of the streams var transcode = mediaStreamInfos.Any(s => IsTranscodingRequired(s.Container, format)); // Set up progress-related stuff var progressMixer = progress != null ? new ProgressMixer(progress) : null; var downloadProgressPortion = transcode ? 0.15 : 0.99; var ffmpegProgressPortion = 1 - downloadProgressPortion; var totalContentLength = mediaStreamInfos.Sum(s => s.Size); // Keep track of the downloaded streams var streamFilePaths = new List <string>(); try { // Download all streams foreach (var streamInfo in mediaStreamInfos) { // 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 / totalContentLength); // Download stream await _youtubeClient.DownloadMediaStreamAsync(streamInfo, streamFilePath, streamDownloadProgress, cancellationToken); } // Set up process progress handler var ffmpegProgress = progressMixer?.Split(ffmpegProgressPortion); // Process streams (mux/transcode/etc) await _ffmpeg.ProcessAsync(streamFilePaths, filePath, format, transcode, 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) { FileEx.TryDelete(streamFilePath); } } }