Exemplo n.º 1
0
        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());
            }
        }
Exemplo n.º 2
0
        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);
        }
        private static IEnumerable <IStreamInfo> GetBestMediaStreamInfos(
            StreamManifest streamManifest,
            ConversionFormat format)
        {
            // Use single muxed stream if adaptive streams are not available
            if (!streamManifest.GetAudioOnlyStreams().Any() || !streamManifest.GetVideoOnlyStreams().Any())
            {
                // Priority: video quality -> transcoding
                yield return(streamManifest
                             .GetMuxedStreams()
                             .OrderByDescending(s => s.VideoQuality)
                             .ThenByDescending(s => !IsTranscodingRequired(s.Container, format))
                             .First());

                yield break;
            }

            // Include audio stream
            // Priority: transcoding -> bitrate
            yield return(streamManifest
                         .GetAudioOnlyStreams()
                         .OrderByDescending(s => !IsTranscodingRequired(s.Container, format))
                         .ThenByDescending(s => s.Bitrate)
                         .First());

            // Include video stream
            if (!format.IsAudioOnly)
            {
                // Priority: video quality -> transcoding
                yield return(streamManifest
                             .GetVideoOnlyStreams()
                             .OrderByDescending(s => s.VideoQuality)
                             .ThenByDescending(s => !IsTranscodingRequired(s.Container, format))
                             .First());
            }
        }
Exemplo n.º 4
0
        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);
        }
Exemplo n.º 5
0
        public async Task SendYoutubeAudioAsync(IMessage message, IGuildUser user, string query)
        {
            // Check that we have a query
            if (string.IsNullOrWhiteSpace(query))
            {
                return;
            }

            if (this.connectedChannels.TryGetValue(user.GuildId, out AudioClient audioClient))
            {
                VideoInfo videoInfo = new VideoInfo(user.GetName());

                // Try to parse the url given to return just the video id
                string id;
                if (query.Contains("v=") && query.Length >= 3)
                {
                    if (query.Contains("&"))
                    {
                        id = Regex.Match(query, "v=(.*?)&").ToString();
                        id = id.Substring(2, id.Length - 3);
                    }
                    else
                    {
                        id = Regex.Match(query, "v=(.*?)$").ToString();
                        id = id.Substring(2, id.Length - 2);
                    }

                    YoutubeExplode.Videos.Video video = await youtube.Videos.GetAsync(id);

                    videoInfo.Title     = video.Title;
                    videoInfo.Duration  = video.Duration.ToString();
                    videoInfo.Thumbnail = video.Thumbnails.GetFirst().Url;
                }
                else
                {
                    // Get the stream from YT via search
                    IReadOnlyList <YoutubeExplode.Search.VideoSearchResult> searchResult = await youtube.Search.GetVideosAsync(query).CollectAsync(1);

                    YoutubeExplode.Search.VideoSearchResult result = searchResult.GetFirst();

                    videoInfo.Title     = result.Title;
                    videoInfo.Duration  = result.Duration.ToString();
                    videoInfo.Thumbnail = result.Thumbnails.GetFirst().Url;

                    id = result.Id;
                }

                // Get the stream from YT via video id
                StreamManifest streamManifest = await youtube.Videos.Streams.GetManifestAsync(id);

                AudioOnlyStreamInfo streamInfo = streamManifest.GetAudioOnlyStreams().GetFirst();

                videoInfo.Stream = streamInfo;

                // If song currently playing, add to playlist
                if (audioClient.CurrentStream != null)
                {
                    audioClient.PlayList.Add(videoInfo);

                    // Delete calling command
                    await message.DeleteAsync();
                }
                else
                {
                    // Play song
                    audioClient.CurrentSong = videoInfo;
                    this.StartStream(youtube, audioClient, streamInfo, message);
                }
            }
        }