/// <summary> /// Get Audio Stream /// </summary> /// <param name="streamManifest">manifest bases on video bitray/quality</param> /// <param name="messageText">text which user input, need for exception</param> /// <returns></returns> private async Task <IAudioStreamInfo> GetAudioStreamInfo(StreamManifest streamManifest, string messageText) { IAudioStreamInfo streamInfo = (IAudioStreamInfo)streamManifest .GetAudioOnly() .WithHighestBitrate(); if (streamInfo == null || streamInfo.Size.TotalMegaBytes > 50) { var failMessage = streamManifest.GetAudioOnly().Any() ? ValidationMessages.FileSizeExceedLimitMessage : ValidationMessages.Mp4DoesNotExistsMessage; await SendTextMessage(failMessage); _logger.LogInformation($"Stream info for {messageText} was empty and error for user is {failMessage}"); return(null); } return(streamInfo); }
private async Task <Stream> GetAudioStreamAsync(Video video) { StreamManifest manifest = await GetManifestAsync(video); IStreamInfo streamInfo = manifest.GetAudioOnly().WithHighestBitrate(); System.Console.WriteLine(streamInfo.Bitrate); return(await youtube.Videos.Streams.GetAsync(streamInfo)); }
static async Task DownloadAudioOnly(YoutubeClient youtube, StreamManifest streamManifest, string title, string path) { var highAudioQuality = streamManifest.GetAudioOnly().WithHighestBitrate(); if (highAudioQuality != null) { string newPath = $"{path}/a{title}.{highAudioQuality.Container}"; await youtube.Videos.Streams.DownloadAsync(highAudioQuality, newPath); } }
private static IEnumerable <IStreamInfo> GetBestMediaStreamInfos( StreamManifest streamManifest, ConversionFormat format) { // Fail if there are no available streams if (!streamManifest.Streams.Any()) { throw new ArgumentException("There are no streams available.", nameof(streamManifest)); } // Use single muxed stream if adaptive streams are not available if (!streamManifest.GetAudioOnly().Any() || !streamManifest.GetVideoOnly().Any()) { // Priority: video quality -> transcoding yield return(streamManifest .GetMuxed() .OrderByDescending(s => s.VideoQuality) .ThenByDescending(s => !IsTranscodingRequired(s.Container, format)) .First()); yield break; } // Include audio stream // Priority: transcoding -> bitrate yield return(streamManifest .GetAudioOnly() .OrderByDescending(s => !IsTranscodingRequired(s.Container, format)) .ThenByDescending(s => s.Bitrate) .First()); // Include video stream if (!format.IsAudioOnly) { // Priority: video quality -> framerate -> transcoding yield return(streamManifest .GetVideoOnly() .OrderByDescending(s => s.VideoQuality) .ThenByDescending(s => s.Framerate) .ThenByDescending(s => !IsTranscodingRequired(s.Container, format)) .First()); } }
private static async Task DownloadPlaylist(string folder, string id) { //Playlist playlist = await Client.Playlists.GetAsync(id); await foreach (Video video in Client.Playlists.GetVideosAsync(new PlaylistId(id))) { Console.WriteLine(video.Title); StreamManifest streamManifest = await Client.Videos.Streams.GetManifestAsync(video.Id); IStreamInfo streamInfo = streamManifest.GetAudioOnly().Where(stream => stream.Container == Container.Mp4).WithHighestBitrate(); await Client.Videos.Streams.DownloadAsync(streamInfo, Path.Combine(folder, SanitizeFilename(video.Title) + ".mp3")); } }
public async Task SaveAudioToDiskAsync(string link, Playlist playList) { string source = Path.Combine(Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName, @"music\"); playList.PlaylistName += @"\"; //playlistname is the foldername YoutubeClient youtube = new YoutubeClient(); Video video = await youtube.Videos.GetAsync(link); string legalTitle = string.Join("", video.Title.Split(Path.GetInvalidFileNameChars())); // Removes all possible illegal filename characetrs from the title StreamManifest streamManifest = await youtube.Videos.Streams.GetManifestAsync(link); IStreamInfo streamInfo = streamManifest.GetAudioOnly().WithHighestBitrate(); if (streamInfo != null) { // Download the stream to file string fileName = $"{source + playList.PlaylistName + legalTitle}"; await youtube.Videos.Streams.DownloadAsync(streamInfo, fileName + ".mp4"); //downloaden van mp4 FFMpegConverter ffMpeg = new FFMpegConverter(); ffMpeg.ConvertMedia(fileName + ".mp4", fileName + ".mp3", "mp3"); //converteren van mp4 naar mp3 File.Delete(fileName + ".mp4"); Song newSong = new Song(fileName + ".mp3"); //aanmaken van songobject newSong.ArtistName = video.Author; //zetten van de filetags newSong.SongTitle = video.Title; newSong.AlbumTitle = null; newSong.AlbumTrack = 0; newSong.MaxAlbumTrack = 0; newSong.Year = 0; newSong.BPM = 0; /* downloaden van thumbnail*/ using (WebClient client = new WebClient()) { client.DownloadFile(video.Thumbnails.HighResUrl, fileName + ".jpg"); } newSong.setAlbumArt(fileName + ".jpg"); //zetten van albumart metadata File.Delete(fileName + ".jpg"); //deleten van thumbnail image file newSong.saveFileTag(); //opslaan van filetags playList.addSong(newSong); //toevoegen aan database DbManager db = new DbManager(); db.addSongToDatabase(newSong); } }
private static void SelectMediaStreamInfoSet(StreamManifest streamManifest, Settings settings, SettingDownload settingDownload, out AudioOnlyStreamInfo audioStreamInfo, out VideoOnlyStreamInfo videoStreamInfo) { //Todo make a better selection process //by largest container bitrate audioStreamInfo = streamManifest .GetAudioOnly() .Where(s => s.Container == Container.Mp4) .OrderByDescending(s => s.Bitrate) .First(); videoStreamInfo = streamManifest .GetVideoOnly() .Where(s => s.Container == Container.Mp4) .OrderByDescending(s => s.VideoQuality) .ThenByDescending(s => s.Framerate) .First(); if (settingDownload.MediaType == MediaType.Audio) { audioStreamInfo = streamManifest .GetAudioOnly() .OrderByDescending(s => s.Bitrate) .First(); } if (settingDownload.MediaType == MediaType.Video) { videoStreamInfo = streamManifest .GetVideoOnly() .Where(s => s.Container == Container.Mp4) .OrderByDescending(s => s.VideoQuality) .ThenByDescending(s => s.Framerate) .First(); } }
public async Task DownloadHightQualityAsync(VideoQuality quality, string saveFile) { System.Windows.MessageBox.Show("Укажите путь к файлу FFMPEG.EXE"); OpenFileDialog openFile = new OpenFileDialog(); openFile.Filter = "EXE file(*.exe)|*.exe"; openFile.ShowDialog(); textBoxStatus.Text = "Начинаю загрузку видео! Это может быть долго, ожидайте!"; var streamInfo = streamManifest.GetVideoOnly().Where(s => s.VideoQuality == quality).WithHighestVideoQuality(); var streamInfo1 = streamManifest.GetAudioOnly().WithHighestBitrate(); if (streamInfo != null) { await youtube.Videos.Streams.DownloadAsync(streamInfo, $"{saveFile}.mp4"); } if (streamInfo != null) { await youtube.Videos.Streams.DownloadAsync(streamInfo1, $"{saveFile}.mp3"); } string args = $"/c {openFile.FileName} -i \"{saveFile}.mp4\" -i \"{saveFile}.mp3\" -shortest {saveFile}_{quality.ToString()}.mp4"; ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.CreateNoWindow = false; startInfo.FileName = "cmd.exe"; startInfo.WorkingDirectory = saveFile + ".mp4"; startInfo.Arguments = args; using (Process exeProcess = Process.Start(startInfo)) { exeProcess.WaitForExit(); } File.Delete(saveFile + ".mp4"); File.Delete(saveFile + ".mp3"); textBoxStatus.Text = $"Видео успешно скачано, путь к файлу - > {saveFile}_{quality.ToString()}.mp4"; }
private static async Task HandleRequest(JukeboxConnection connection, JukeboxRequest request) { connection.CurrentRequest = request; IVoiceState voiceState = (IVoiceState)request.User; YoutubeClient youtube = new(); // Try to look up the video's manifest from YouTube StreamManifest streamManifest = await youtube.Videos.Streams.GetManifestAsync(request.VideoId); if (streamManifest != null) { // Get a reference to the audio-only stream from YouTube for the specified video IStreamInfo streamInfo = streamManifest.GetAudioOnly().WithHighestBitrate(); if (streamInfo != null) { // Ensure that the bot is connected to the requesting user's channel await EnsureConnectedToUsersChannel(connection, voiceState); // Create a new stream object to send audio to the Discord channel using AudioOutStream audioOutStream = connection.AudioClient.CreatePCMStream(AudioApplication.Music); // Start ffmpeg.exe and prepare to start capturing the output using Process ffmpeg = CreateFfmpeg(); Task ffmpegOutputTask = ffmpeg.StandardOutput.BaseStream.CopyToAsync(audioOutStream); // Transfer the audio data from YouTube to the ffmpeg input stream await youtube.Videos.Streams.CopyToAsync(streamInfo, ffmpeg.StandardInput.BaseStream); ffmpeg.StandardInput.BaseStream.Close(); // Wait until all output has been captured from ffmpeg and sent to Discord ffmpegOutputTask.Wait(); // By this point the song has finished playing await connection.AudioClient.SetSpeakingAsync(false); connection.LastActivity = DateTime.Now; connection.CurrentRequest = null; } } }
public async Task <string> DownloadYouTubeVideo(string youTubeVideoId, string downloadDirectory = "Music/") { //Get the video Video videoData = await ytClient.Videos.GetAsync(youTubeVideoId); try { if (cancellationToken.IsCancellationRequested) { return(null); } //Get the audio stream info StreamManifest steamManifest = await ytClient.Videos.Streams.GetManifestAsync(youTubeVideoId); IStreamInfo audioSteam = steamManifest.GetAudioOnly().WithHighestBitrate(); string downloadLocation = $"{musicDirectory}{videoData.Title.RemoveIllegalChars()}.{audioSteam.Container.Name}"; Logger.Debug("Downloading YouTube video {@VideoTitle}({@VideoID}) to {@DownloadLocation}", videoData.Title, videoData.Id.Value, downloadLocation); await ytClient.Videos.Streams.DownloadAsync(audioSteam, downloadLocation, null, cancellationToken); return(!File.Exists(downloadLocation) ? null : downloadLocation); } catch (OperationCanceledException) { //User cancelled return(null); } catch (Exception ex) { Logger.Error("An error occured while download a YouTube video! {@Exception}", ex); return(null); } }
public static List <MediaStreamList> PopulateListGrouped(StreamManifest mediaStreamInfos) { var mixedStreams = new MediaStreamList(); var mixed = mediaStreamInfos.GetMuxed().ToList(); mixedStreams.Heading = "Mixed Downloads"; foreach (var item in mixed) { mixedStreams.Add(item); } var videoStreams = new MediaStreamList(); var videoS = mediaStreamInfos.GetVideoOnly().ToList(); videoStreams.Heading = "Video Only Downloads"; foreach (var item in videoS) { videoStreams.Add(item); } var audioStreams = new MediaStreamList(); var audio = mediaStreamInfos.GetAudioOnly().ToList(); audioStreams.Heading = "Audio Only Downloads"; foreach (var item in audio) { audioStreams.Add(item); } var list = new List <MediaStreamList> { mixedStreams, videoStreams, audioStreams }; return(list); }
public async Task SaveAudioExternal(string Location, string link) { YoutubeClient youtube = new YoutubeClient(); Location += @"\"; Video video = await youtube.Videos.GetAsync(link); string legalTitle = string.Join("", video.Title.Split(Path.GetInvalidFileNameChars())); // Removes all possible illegal filename characetrs from the title StreamManifest streamManifest = await youtube.Videos.Streams.GetManifestAsync(link); IStreamInfo streamInfo = streamManifest.GetAudioOnly().WithHighestBitrate(); if (streamInfo != null) { // Download the stream to file string fileName = $"{Location + legalTitle}"; await youtube.Videos.Streams.DownloadAsync(streamInfo, fileName + ".mp4"); FFMpegConverter ffMpeg = new FFMpegConverter(); ffMpeg.ConvertMedia(fileName + ".mp4", fileName + ".mp3", "mp3"); //convert mp4 to mp3 File.Delete(fileName + ".mp4"); //delete mp4 file } }
public async Task <string> DownloadYouTubeVideo(string youTubeVideoId, string downloadDirectory = "Music/") { //Get the video Video videoData = await ytClient.Videos.GetAsync(youTubeVideoId); try { //Get the audio stream info StreamManifest steamManifest = await ytClient.Videos.Streams.GetManifestAsync(youTubeVideoId); IStreamInfo audioSteam = steamManifest.GetAudioOnly().WithHighestBitrate(); string downloadLocation = $"{musicDirectory}{videoData.Title.RemoveIllegalChars()}.{audioSteam.Container.Name}"; await ytClient.Videos.Streams.DownloadAsync(audioSteam, downloadLocation, null, cancellationToken); Logger.Log($"Downloaded song to {downloadLocation}", LogVerbosity.Debug); return(!File.Exists(downloadLocation) ? null : downloadLocation); } catch (OperationCanceledException) { //User cancelled return(null); } catch (Exception ex) { #if DEBUG Logger.Log(ex.ToString(), LogVerbosity.Error); #else Logger.Log(ex.Message, LogVerbosity.Error); #endif return(null); } }
public async Task Play(ICoreHandler handler, Message message, string param) { Video vid = (await client.Search.GetVideosAsync(param)).FirstOrDefault(); if (vid != null) { if (vid.Duration <= TimeSpan.FromMinutes(10)) { StreamManifest streamManifest = await client.Videos.Streams.GetManifestAsync(vid.Id); AudioOnlyStreamInfo audio = streamManifest.GetAudioOnly().FirstOrDefault(); if (audio != null) { MemoryStream stream = new MemoryStream(); await client.Videos.Streams.CopyToAsync(audio, stream); Debug(audio.AudioCodec); unsafe { AVPacket *pkt = ffmpeg.av_packet_alloc(); AVCodec * codec = ffmpeg.avcodec_find_decoder_by_name(audio.AudioCodec); if (codec == null) { Error($"Codec {audio.AudioCodec} not found."); return; } AVCodecParserContext *parser = ffmpeg.av_parser_init((int)codec->id); if (parser == null) { Error("Could not allocate audio codec context."); return; } AVCodecContext *context = ffmpeg.avcodec_alloc_context3(codec); if (context == null) { Error("Could not allocate audio codec context."); return; } if (ffmpeg.avcodec_open2(context, codec, null) < 0) { Error("Could not open audio codec context."); return; } AVFrame *decoded_frame = null; while (stream.Length - stream.Position > 0) { if (decoded_frame == null) { decoded_frame = ffmpeg.av_frame_alloc(); } byte[] buffer = new byte[pkt->size]; stream.Read(buffer, 0, buffer.Length); IntPtr unmanagedPointer = Marshal.AllocHGlobal(buffer.Length); Marshal.Copy(buffer, 0, unmanagedPointer, buffer.Length); ffmpeg.av_parser_parse2(parser, context, &pkt->data, &pkt->size, (byte *)unmanagedPointer, buffer.Length, ffmpeg.AV_NOPTS_VALUE, ffmpeg.AV_NOPTS_VALUE, 0); int ret = ffmpeg.avcodec_send_packet(context, pkt); while (ret > 0) { ret = ffmpeg.avcodec_receive_frame(context, decoded_frame); int data_size = ffmpeg.av_get_bytes_per_sample(context->sample_fmt); int current = 0; for (int i = 0; i < decoded_frame->nb_samples; i++) { for (uint ch = 0; ch < context->channels; ch++) { Marshal.Copy((IntPtr)decoded_frame->data[ch] + (data_size * i), buffer, current, data_size); current += data_size; } } message.TransferSound(buffer); } Marshal.FreeHGlobal(unmanagedPointer); } } } } else { Warn("Video too long."); } } else { Warn("No video by that term."); } /*DiscordGuildTextChannel Channel = client.GetChannel(e.Message.ChannelId).Result as DiscordGuildTextChannel; * Snowflake GuildId = Channel.GuildId; * DiscordGuild Guild = await client.GetGuild(GuildId); * Snowflake ChannelId = e.Message.ChannelId; * DiscordVoiceState voiceState = e.Shard.Cache.GetVoiceState(GuildId, e.Message.Author.Id); * if (voiceState == null) { * return; * } else { * if (!SharedObjectStorage.VoiceModuleObjects.Keys.Contains(voiceState.ChannelId.Value)) { * VoiceModule music = new VoiceModule(e.Shard, voiceState.ChannelId.Value); * SharedObjectStorage.VoiceModuleObjects.Add(voiceState.ChannelId.Value, music); * if (Tempnamelist.Count <= 2) { * Tempnamelist.Add($"Temp{i++}"); * } * string filename = Tempnamelist[0]; * Tempnamelist.RemoveAt(0); * voice = new YoutubeVoiceProvider(); * voice.DoQuery(query); * client.CreateMessage(e.Message.ChannelId, "" + String.Join("\n", voice.Result)); * this.GuildId = ((await client.GetChannel(e.Message.ChannelId)) as DiscordGuildTextChannel).GuildId; * UserId = e.Message.Author.Id; * e.Shard.Gateway.OnMessageCreated += Gateway_OnMessageCreated1; * stopsignal.WaitOne(); * e.Shard.Gateway.OnMessageCreated -= Gateway_OnMessageCreated1; * voice.DownloadToFileByQuery($"Temp/{filename}").Wait(); * if (new FileInfo($"Temp/{filename}").Length <= 100) { return; } * client.CreateMessage(e.Message.ChannelId, "Playing: " + voice.CurrentSelection); * Converter c = new FFmpegConverter(); * c.TempfileClosed += TempfileClosed; * music.Transfer(new FileInfo($"Temp/{filename}"), c, playCancellationTokenSource); * } * }*/ }
public async Task DownloadTrack(MusixSongResult Track, string OutputDirectory, AudioEffectStack Effects = null, CancellationToken cancellationToken = default) { int Steps; int Step = 0; if (Effects == null) { Steps = 9; } else { Steps = 9 + Effects.EffectCount; } TryCallback(Step, Steps, "Starting Download", Track); if (cancellationToken.IsCancellationRequested) { return; } bool HasEffects = Effects != null; if (HasEffects) { Console.WriteLine("Has Effects"); if (string.IsNullOrEmpty(Effects.AudioCachePath)) { Effects.AudioCachePath = AudioCache; } } // Step 1 Step++; TryCallback(Step, Steps, "Preparing Download", Track); Console.WriteLine("Start Download"); if (!Track.HasVideo) { Console.WriteLine("No Vid"); } if (!Track.HasVideo) { return; } string SourceAudio = Path.Combine(AudioCache, $"audio_source_{DateTime.Now.Ticks}"); string AlbumCover = Path.Combine(ImageCachePath, $"cover_{DateTime.Now.Ticks}.jpg"); string OutputFile = Path.Combine(OutputDirectory, FileHelpers.ScrubFileName($"{Track.SpotifyTrack.Artists[0].Name} - {Track.SpotifyTrack.Name.Replace("?", "").Trim(' ')}.mp3")); string MidConversionFile = Path.Combine(AudioCache, FileHelpers.ScrubFileName($"MidConversion_{DateTime.Now.Ticks}.mp3")); // Step 2 Step++; TryCallback(Step, Steps, "Aquiring streams", Track); StreamManifest StreamData = await YouTube.Videos.Streams.GetManifestAsync(Track.YoutubeVideo.Id); if (cancellationToken.IsCancellationRequested) { return; } // Step 3 Step++; TryCallback(Step, Steps, "Sorting Streams", Track); List <AudioOnlyStreamInfo> AudioStreams = StreamData.GetAudioOnly().ToList(); AudioStreams.OrderBy(dat => dat.Bitrate); if (AudioStreams.Count() == 0) { Console.WriteLine("No Streams"); } if (AudioStreams.Count() == 0) { return; } IAudioStreamInfo SelectedStream = AudioStreams[0]; // Step 4 Step++; TryCallback(Step, Steps, "Starting downloads", Track); if (cancellationToken.IsCancellationRequested) { return; } Task AudioDownloadTask = YouTube.Videos.Streams.DownloadAsync(SelectedStream, SourceAudio); WebClient WebCl = new WebClient(); Step++; TryCallback(Step, Steps, "Starting", Track); SpotifyImage Cover = Track.SpotifyTrack.Album.Images[0]; var CoverDownloadTask = new Task(() => { Console.WriteLine("Downloading Cover"); WebCl.DownloadFile(new Uri(Cover.Url), AlbumCover); } ); CoverDownloadTask.Start(); Step++; TryCallback(Step, Steps, "Waiting for downloads", Track); if (cancellationToken.IsCancellationRequested) { return; } if (!AudioDownloadTask.IsCompleted) { Console.WriteLine("Waiting on artwork..."); CoverDownloadTask.Wait(); } if (cancellationToken.IsCancellationRequested) { return; } if (!AudioDownloadTask.IsCompleted) { Console.WriteLine("Waiting on audio..."); AudioDownloadTask.Wait(); Console.WriteLine("Download Complete."); } Thread.Sleep(100); if (cancellationToken.IsCancellationRequested) { return; } string ConversionFile = OutputFile; if (HasEffects) { ConversionFile = MidConversionFile; } if (File.Exists(OutputFile)) { File.Delete(OutputFile); } if (File.Exists(ConversionFile)) { File.Delete(ConversionFile); } Step++; TryCallback(Step, Steps, "Transcoding audio to mp3", Track); // Step 8 Console.WriteLine("Starting Conversion..."); await ConversionsProvider.Convert(SourceAudio, ConversionFile); Console.WriteLine("Conversion Complete."); // Step 9 if (cancellationToken.IsCancellationRequested) { return; } if (HasEffects) { Step++; int InternalStep = Step; TryCallback(Step, Steps, "Applying audio effects", Track); Effects.ApplyEffects(ConversionFile, OutputFile, (step, stepmax, status, download) => { step++; TryCallback(Step, Steps, status, Track); }, cancellationToken); } if (cancellationToken.IsCancellationRequested) { return; } Step++; TryCallback(Step, Steps, "Applying ID3 metadata tags", Track); // Step 10 TagLib.Id3v2.Tag.DefaultVersion = 3; TagLib.Id3v2.Tag.ForceDefaultVersion = true; TagLibFile TLF = TagLibFile.Create(OutputFile); TagLibPicture Pic = new TagLibPicture(AlbumCover); TagLib.Id3v2.AttachedPictureFrame Frame = new TagLib.Id3v2.AttachedPictureFrame(Pic) { MimeType = System.Net.Mime.MediaTypeNames.Image.Jpeg }; Pic.Type = TagLib.PictureType.FrontCover; TagLib.IPicture[] Pics = { Pic }; TLF.Tag.Pictures = Pics; TLF.Tag.Title = Track.SpotifyTrack.Name.Split('-')[0].Trim(' '); TLF.Tag.Album = Track.SpotifyTrack.Album.Name; TLF.Tag.AlbumArtists = Track.SpotifyTrack.Album.Artists.CastEnumerable(x => x.Name).ToArray(); TLF.Tag.Disc = (uint)Track.SpotifyTrack.DiscNumber; TLF.Tag.AlbumSort = Track.SpotifyTrack.Album.AlbumType; DateTime?DT = GetDate(Track.SpotifyTrack.Album.ReleaseDate); if (DT.HasValue) { TLF.Tag.Year = (uint)DT.Value.Year; } if (cancellationToken.IsCancellationRequested) { return; } TLF.Save(); // Clean Up // Step 11 Step++; TryCallback(Step, Steps, "Cleaning up", Track); WebCl.Dispose(); TLF.Dispose(); Console.WriteLine("Done."); OnMusixDownloadComplete?.Invoke(Track); }
private IStreamInfo GetMp3Stream(StreamManifest streamManifest) { return(streamManifest.GetAudioOnly().FirstOrDefault(w => w.Container.Name.Equals("mp3")) ?? streamManifest.GetAudioOnly().FirstOrDefault(w => w.Container.Name.Equals("mp4")) ?? streamManifest.GetAudioOnly().FirstOrDefault(w => !w.Container.Name.Equals("webm"))); }
private IAudioStreamInfo GetAudioStreamInfo(StreamManifest manifest) => manifest.GetAudioOnly().OrderByDescending(streamInfo => streamInfo.Bitrate).First();
public static Tuple <string, string> LoadYoutubeVideo(string videoId, int startSeconds, int duration, IProgress <double> progressWriter = null) { MySettings settings = MySettings.Instance; string youtubeFolder = settings.PlaysoundsYoutubeFolder; int durationSecondsLimit = settings.PlaysoundsYoutubeMaxVideoDurationSeconds; double maxFileSizeMb = settings.PlaysoundsYoutubeMaxVideoDurationSeconds; if (youtubeFolder == null) { youtubeFolder = Utils.GetProjectFolderPath("youtube"); } else { //youtubeFolder = Path.GetFullPath(youtubeFolder); if (!Directory.Exists(youtubeFolder)) { Directory.CreateDirectory(youtubeFolder); } } string existingFile = null; try { existingFile = Directory.GetFiles(youtubeFolder).First((s) => Path.GetFileNameWithoutExtension(s) == videoId); } catch (Exception) { } string cachedCutFile = $"{videoId}_{startSeconds}_{duration}"; try { cachedCutFile = Directory.GetFiles(youtubeFolder).First((s) => s.Contains(cachedCutFile)); } catch (Exception) { if (existingFile != null) { cachedCutFile = Path.Combine(youtubeFolder, $"{cachedCutFile}{Path.GetExtension(existingFile)}"); } } YoutubeClient youtube = new YoutubeClient(); Video video = youtube.Videos.GetAsync($"https://youtube.com/watch?v={videoId}").Result; string title = video.Title; if (!string.IsNullOrEmpty(existingFile)) { Console.WriteLine("Audio was cached"); } else { if (durationSecondsLimit != -1 && video.Duration.TotalSeconds > durationSecondsLimit) { throw new ArgumentException($"The video is too long to download (> {durationSecondsLimit} seconds)..."); } StreamManifest streamManifest = youtube.Videos.Streams.GetManifestAsync(videoId).Result; IStreamInfo streamInfo = streamManifest.GetAudioOnly().WithHighestBitrate(); string extension = streamInfo.Container.ToString().ToLower(); string fileName = $"{videoId}.{extension}"; existingFile = Path.Combine(youtubeFolder, fileName); string fileNameOut = $"{videoId}_{startSeconds}_{duration}.{extension}"; cachedCutFile = Path.Combine(youtubeFolder, fileNameOut); // Get the actual stream Stream stream = youtube.Videos.Streams.GetAsync(streamInfo).Result; if (maxFileSizeMb != -1 && stream.Length / 1024 / 1024 > maxFileSizeMb) { throw new ArgumentException($"The video is too large (>{maxFileSizeMb}MB) to download..."); } Console.WriteLine($"Stream length (MB): {stream.Length / 1024 / 1024}"); stream.Dispose(); progressWriter = progressWriter ?? new ProgressWriter(); Console.Write($"Downloading stream: {streamInfo.Size} bytes ({streamInfo.Container.Name})"); youtube.Videos.Streams.DownloadAsync(streamInfo, existingFile, new ProgressWriter()).Wait(); if (existingFile.EndsWith(".webm")) { RepackageExistingWebm(existingFile); } } if (File.Exists(cachedCutFile)) { Console.WriteLine("Audio also was cut"); } else { CutAudio(existingFile, cachedCutFile, startSeconds, duration); } return(Tuple.Create(cachedCutFile, title)); }
public static async Task PlayYoutubeAudio(string videoId, int startSeconds, int duration, double speed = 1.0, double pitch = 1.0, double volume = 1.0, string audioDevice = null, int durationSecondsLimit = -1, int maxFileSizeMb = -1) { if (!Directory.Exists("playsounds")) { Directory.CreateDirectory("playsounds"); } if (!Directory.Exists(@"playsounds\cut")) { Directory.CreateDirectory(@"playsounds\cut"); } string existingFile = null; try { existingFile = Directory.GetFiles("playsounds").First((s) => s.Contains(videoId)); } catch (Exception) { } if (!string.IsNullOrEmpty(existingFile)) { string existingExtension = Path.GetExtension(existingFile); Console.WriteLine("Audio was cached"); GetAudioDurationInSeconds(existingFile); string cachedCutFile = $"playsounds\\cut\\{videoId}_{startSeconds}_{duration}{existingExtension}"; if (File.Exists(cachedCutFile)) { Console.WriteLine("Audio also was cut"); } else { CutAudio(existingFile, cachedCutFile, startSeconds, duration); } PlayAudio(cachedCutFile, volume, speed, pitch, audioDevice: audioDevice); return; } YoutubeClient youtube = new YoutubeClient(); // You can specify video ID or URL Video video = await youtube.Videos.GetAsync($"https://youtube.com/watch?v={videoId}"); string title = video.Title; string author = video.Author; if (durationSecondsLimit != -1 && video.Duration.TotalSeconds > durationSecondsLimit) { throw new ArgumentException("The video is too long to download..."); } Console.WriteLine($"Downloading audio from '{title}' by '{author}'"); StreamManifest streamManifest = await youtube.Videos.Streams.GetManifestAsync(videoId); IStreamInfo streamInfo = streamManifest.GetAudioOnly().WithHighestBitrate(); if (streamInfo != null) { string extension = streamInfo.Container.ToString().ToLower(); string fileName = $"playsounds\\{videoId}.{extension}"; string fileNameOut = $"playsounds\\cut\\{videoId}_{startSeconds}_{duration}.{extension}"; // Get the actual stream Stream stream = youtube.Videos.Streams.GetAsync(streamInfo).Result; if (maxFileSizeMb != -1 && stream.Length / 1024 / 1024 > maxFileSizeMb) { throw new ArgumentException($"The video is too large (>{maxFileSizeMb}MB) to download..."); } Console.WriteLine($"Stream length (MB): {stream.Length / 1024 / 1024}"); stream.Dispose(); Console.Write($"Downloading stream: {streamInfo.Size} bytes ({streamInfo.Container.Name})"); await youtube.Videos.Streams.DownloadAsync(streamInfo, fileName, new ProgressWriter()); CutAudio(fileName, fileNameOut, startSeconds, duration); PlayAudio(fileNameOut, volume, speed, pitch, audioDevice: audioDevice); } }