private async Task <bool> DownloadTrailerAsync(Movie movie) { try { YoutubeClient youtube = new YoutubeClient(); StreamManifest streamManifest = await youtube.Videos.Streams.GetManifestAsync(movie.TrailerURL); // Get highest quality muxed stream IVideoStreamInfo streamInfo = streamManifest.GetMuxed().WithHighestVideoQuality(); if (streamInfo != null) { // Download the stream to file await youtube.Videos.Streams.DownloadAsync(streamInfo, Path.Combine(movie.FilePath, $"{movie.Title}-trailer.{streamInfo.Container}")); return(true); } return(false); } catch (Exception ex) { _logger.LogError($"Error downloading trailer for {movie.Title}\n{ex.Message}"); await _hubContext.Clients.All.SendAsync("downloadAllTrailers", movie); return(false); } }
static IEnumerable <IStreamInfo> GetOptimalStreams(StreamManifest streamManifest, Container container) { if (streamManifest.GetAudioOnlyStreams().Any() && streamManifest.GetVideoOnlyStreams().Any()) { // Include audio stream // Priority: transcoding -> bitrate yield return(streamManifest .GetAudioOnlyStreams() .OrderByDescending(s => s.Container == container) .ThenByDescending(s => s.Bitrate) .First()); // Include video stream if (!container.IsAudioOnly) { // Priority: video quality -> transcoding yield return(streamManifest .GetVideoOnlyStreams() .OrderByDescending(s => s.VideoQuality) .ThenByDescending(s => s.Container == container) .First()); } } // Use single muxed stream if adaptive streams are not available else { // Priority: video quality -> transcoding yield return(streamManifest .GetMuxedStreams() .OrderByDescending(s => s.VideoQuality) .ThenByDescending(s => s.Container == container) .First()); } }
/// <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); }
/// <summary> /// Gets the muxed stream with custom video quality and Mp4 container. /// Returns null if sequence is empty. /// </summary> public static MuxedStreamInfo WithCustomVideoQualitySupported(this StreamManifest streamManifest, VideoQuality quality) { if (streamManifest == null) { throw new ArgumentNullException(nameof(streamManifest)); } return(streamManifest.GetMuxed().Where(info => info.VideoQuality == quality).Select(info => info).FirstOrDefault()); }
/// <summary> /// Gets the muxed stream with highest video quality and Mp4 container. /// Returns null if sequence is empty. /// </summary> public static MuxedStreamInfo WithHighestVideoQualitySupported(this StreamManifest streamManifest) { if (streamManifest == null) { throw new ArgumentNullException(nameof(streamManifest)); } return(streamManifest.GetMuxed().WithHighestVideoQualitySupported()); }
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)); }
private async Task DownloadVideosAsync() { try { downloading = true; int count = 0, selectedVideos = 0; for (int i = 0; i < gvVideos.RowCount; i++) { if (Convert.ToBoolean(gvVideos.Rows[i].Cells[1].Value) == true) { selectedVideos++; } } progressBar1.Maximum = selectedVideos; foreach (var videoInfo in PlaylistVideosInfo) { if (Convert.ToBoolean(gvVideos.Rows[count].Cells[1].Value) == false) { count++; continue; } StreamManifest streamManifest = await Youtube.Videos.Streams.GetManifestAsync(videoInfo.Id); gvVideos.Rows[count].Cells[3].Value = "Downloading"; var streamInfo = streamManifest.GetMuxed().FirstOrDefault(x => x.VideoQualityLabel == qualityComboBox.Text); if (streamInfo == null) { streamInfo = (MuxedStreamInfo)streamManifest.GetMuxed().WithHighestVideoQuality(); } gvVideos.Rows[count].Cells[4].Value = streamInfo.Size.ToString(); if (streamInfo != null) { try { var stream = await Youtube.Videos.Streams.GetAsync(streamInfo); await Youtube.Videos.Streams.DownloadAsync(streamInfo, Path.Combine(extractPath, RemoveInvalidChars(videoInfo.Title) + '.' + streamInfo.Container)); } catch (Exception ex) { gvVideos.Rows[count].Cells[3].Value = "Failed"; count++; continue; } } gvVideos.Rows[count].Cells[3].Value = "Done"; count++; progressBar1.PerformStep(); } MessageBox.Show("Download complete successfully"); downloadBtn.Text = " Get Playlist"; downloading = false; } catch (Exception ex) { } }
public static List <VideoQuality> GetVideoQualityList(this StreamManifest streamManifest) { if (streamManifest == null) { throw new ArgumentNullException(nameof(streamManifest)); } return(streamManifest.GetMuxed().GetAllVideoQualities().ToList()); }
static async Task DownloadMuxOnly(YoutubeClient youtube, StreamManifest streamManifest, string title, string path) { var highMuxQuality = streamManifest.GetMuxed().WithHighestVideoQuality(); if (highMuxQuality != null) { string newPath = $"{path}/m{title}.{highMuxQuality.Container}"; await youtube.Videos.Streams.DownloadAsync(highMuxQuality, newPath); } }
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 Utils.VideoSettings GetVideoSettings(VideoId videoId) { StreamManifest manifest = client.Videos.Streams.GetManifestAsync(videoId).Result; Utils.VideoSettings videoSettings = new Utils.VideoSettings() { StreamManifest = manifest, MuxedStreamInfo = manifest.GetMuxedStreams().ToList(), VideoOnlyStreamInfo = manifest.GetVideoOnlyStreams().ToList(), AudioOnlyStreamInfo = manifest.GetAudioOnlyStreams().ToList() }; return(videoSettings); }
/// <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 GetVideosAsync() { try { List <string> quality = new List <string>(); StreamManifest streamManifest = await Youtube.Videos.Streams.GetManifestAsync(PlaylistVideosInfo[0].Id); List <MuxedStreamInfo> streamInfos = streamManifest.GetMuxed().ToList(); for (int i = 0; i < streamInfos.Count(); i++) { quality.Add(streamInfos[i].VideoQualityLabel); } qualityComboBox.DataSource = quality; downloadBtn.Text = " Download"; } catch (Exception ex) { } }
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 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; } } }
private async void Search() { MessageError = string.Empty; try { VideoId videoId = Helper.NormalizeId(Url); if (videoId.Value != string.Empty) { IsBusy = true; StreamManifest streamManifest = await youTubeClientService.GetStreams(videoId); IReadOnlyList <ClosedCaptionTrackInfo> closedCaptionTrackInfos = await youTubeClientService.GetClosedCaption(videoId); Video video = await youTubeClientService.GetVideoDescription(videoId); Channel channel = await youTubeClientService.GetVideoChannel(videoId); ResumeVideo resumeVideo = new ResumeVideo(); resumeVideo.Channel = channel; resumeVideo.ClosedCaptionTrackInfos = closedCaptionTrackInfos; resumeVideo.Video = video; resumeVideo.MediaStreamList = Helper.PopulateListGrouped(streamManifest); await navigationService.NavigateToAsync <DetailPageViewModel>(resumeVideo); IsBusy = false; } else { MessageError = "Url is not valid"; } IsBusy = false; } catch (Exception ex) { IsBusy = false; MessageError = "Error: " + ex.Message; } }
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); }
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 <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 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 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 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); * } * }*/ }
private async Task <List <FileDownloadingInfo> > InitDownloadingAsync(IList <Video> videos, string directory, DownloadQuality quality, string audioExtForced) { List <FileDownloadingInfo> result = new List <FileDownloadingInfo>(); //_client.DownloadClosedCaptionTrackAsync(); //ThreadPool.SetMaxThreads(Environment.ProcessorCount, Environment.ProcessorCount); if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); } foreach (var vid in videos) { try { StreamManifest infoSet = await _client.Videos.Streams.GetManifestAsync(vid.Id); string vidTitle = RemoveProhibitedChars(vid.Title); switch (quality) { case DownloadQuality.Default: case DownloadQuality.MuxedBest: IEnumerable <MuxedStreamInfo> muxedStreams = infoSet.GetMuxedStreams(); IVideoStreamInfo muxedHighestQuality = muxedStreams.GetWithHighestVideoQuality(); string ext = muxedHighestQuality.Container.Name; //string ext = "mkv"; string path = directory + "/" + vidTitle + "." + ext; var file = new FileDownloadingInfo() { Name = vidTitle, StreamInfo = muxedHighestQuality }; InitStreamDownloading(file, path, vid); result.Add(file); break; case DownloadQuality.SeparateBest: IEnumerable <IVideoStreamInfo> videoStreams = infoSet.GetVideoStreams(); IEnumerable <IAudioStreamInfo> audioStreams = infoSet.GetAudioStreams(); IStreamInfo highestBitRate = audioStreams.GetWithHighestBitrate(); IStreamInfo videoHighestQuality = videoStreams.GetWithHighestVideoQuality(); string extVideo = videoHighestQuality.Container.Name; string pathVideo = directory + "/" + vidTitle + "." + extVideo; string extAudio = highestBitRate.Container.Name; string pathAudio = directory + "/" + vidTitle + "." + extAudio; if (audioExtForced == String.Empty) { if (pathAudio.Equals(pathVideo)) { pathAudio += ".audio." + extAudio; } } else { pathAudio += "." + audioExtForced; } FileDownloadingInfo audio = new FileDownloadingInfo() { Name = vidTitle + "(audio)", StreamInfo = highestBitRate }; FileDownloadingInfo video = new FileDownloadingInfo() { Name = vidTitle, StreamInfo = videoHighestQuality }; if (File.Exists(pathAudio)) { _logger.Log("File " + pathAudio + "already exists!. Consider removing or renaming."); } else { InitStreamDownloading(audio, pathAudio, vid); result.Add(audio); } if (File.Exists(pathVideo)) { _logger.Log("File " + pathVideo + "already exists!. Consider removing or renaming."); } else { InitStreamDownloading(video, pathVideo, vid); result.Add(video); } break; default: throw new ArgumentOutOfRangeException(nameof(quality), quality, null); } } catch (Exception ex) { _logger.Log(ex.InnerException?.Message); } } return(result); }
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); } }
public async Task <StreamManifest> GetStreams(VideoId videoId) { StreamManifest streamManifest = await Client.Videos.Streams.GetManifestAsync(videoId); return(streamManifest); }
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.GetAudioOnlyStreams().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 = new Task(async () => await YouTube.Videos.Streams.DownloadAsync(SelectedStream, SourceAudio)); var req = WebRequest.CreateHttp(SelectedStream.Url); req.Method = "GET"; using (var resp = req.GetResponse()) using (var network = resp.GetResponseStream()) using (var fs = new FileStream(SourceAudio, FileMode.OpenOrCreate, FileAccess.ReadWrite)) { Console.WriteLine("Downloading"); await network.CopyToAsync(fs); Console.WriteLine("flushing"); await fs.FlushAsync(); Console.WriteLine("done"); } 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 IVideoStreamInfo GetVideoStreamInfo(StreamManifest manifest) => manifest.GetVideoOnly().OrderByDescending(streamInfo => streamInfo.Bitrate).First();
public async Task DownloadAsync() { if (comboBox1.Text != "") { SaveFileDialog saveFile = new SaveFileDialog(); saveFile.ShowDialog(); if (saveFile.FileName != "") { youtube = new YoutubeClient(); streamManifest = await youtube.Videos.Streams.GetManifestAsync(LinkID); switch (comboBox1.Text) { case "1080p": _ = DownloadHightQualityAsync(VideoQuality.High1080, saveFile.FileName); break; case "1080p60": _ = DownloadHightQualityAsync(VideoQuality.High1080, saveFile.FileName); break; case "1080p30": _ = DownloadHightQualityAsync(VideoQuality.High1080, saveFile.FileName); break; case "2160p60 HDR": _ = DownloadHightQualityAsync(VideoQuality.High2160, saveFile.FileName); break; case "2160p60": _ = DownloadHightQualityAsync(VideoQuality.High2160, saveFile.FileName); break; case "2160p": _ = DownloadHightQualityAsync(VideoQuality.High2160, saveFile.FileName); break; case "4320p60 HDR": _ = DownloadHightQualityAsync(VideoQuality.High4320, saveFile.FileName); break; case "4320p60": _ = DownloadHightQualityAsync(VideoQuality.High4320, saveFile.FileName); break; case "4320p": _ = DownloadHightQualityAsync(VideoQuality.High4320, saveFile.FileName); break; case "1440p": _ = DownloadHightQualityAsync(VideoQuality.High1440, saveFile.FileName); break; case "1440p60 HDR": _ = DownloadHightQualityAsync(VideoQuality.High1440, saveFile.FileName); break; case "1440p60": _ = DownloadHightQualityAsync(VideoQuality.High1440, saveFile.FileName); break; case "720p": _ = DownloadMediumQualityAsync(VideoQuality.High720, saveFile.FileName); break; case "720p60": _ = DownloadMediumQualityAsync(VideoQuality.High720, saveFile.FileName); break; case "720p30": _ = DownloadMediumQualityAsync(VideoQuality.High720, saveFile.FileName); break; case "480p": _ = DownloadMediumQualityAsync(VideoQuality.Medium480, saveFile.FileName); break; case "360p": _ = DownloadMediumQualityAsync(VideoQuality.Medium360, saveFile.FileName); break; case "240p": _ = DownloadMediumQualityAsync(VideoQuality.Low240, saveFile.FileName); break; case "144p": _ = DownloadMediumQualityAsync(VideoQuality.Low144, saveFile.FileName); break; default: break; } } } }