public void FetchMidoData() { MidoFile midoFile = m_AudioPlayer.GetCurrentMidoFile(); if (midoFile == null) { throw new Exception("Currently not playing anything!"); } EmbedBuilder eb = new EmbedBuilder { Author = new EmbedAuthorBuilder { Name = "Now playing", IconUrl = "https://i.imgur.com/GYpajrA.png", }, Title = midoFile.Title, Description = midoFile.Description, ThumbnailUrl = midoFile.Thumbnail, Color = Color.Red, Footer = new EmbedFooterBuilder { Text = "Mido for Ranka" }, }; DiscordReply(eb); }
public SmolYTObject GetAudio() { SmolYTObject smol = new SmolYTObject(); Process youtube; try { Console.WriteLine("Getting metadata..."); MidoFile metadata = YouTubeMetaData(_url); Console.WriteLine("Metadata fetched, downloading..."); ProcessStartInfo ytinfo = new ProcessStartInfo() { FileName = "youtube-dl", Arguments = $"-f \"bestvideo[filesize < 7M] + bestaudio[filesize < 7M]\" -x --audio-format \"mp3\" -o \"{_output}\" \"{metadata.FileName}\"", CreateNoWindow = true, RedirectStandardOutput = true, UseShellExecute = false }; youtube = Process.Start(ytinfo); youtube.WaitForExit(); Console.WriteLine("Done! Returning data"); smol.file = $"{_rootdir}/{metadata.Title}.mp3"; smol.meta = metadata; return(smol); } catch (Exception) { throw; } }
private MidoFile YouTubeMetaData(string input) { Process youtubedl; MidoFile midoFile = new MidoFile(); var youtubePath = "https://www.youtube.com/watch?v="; ProcessStartInfo youtubedlMetaData = new ProcessStartInfo() { FileName = "youtube-dl", Arguments = $" -s -e --get-id --get-description --get-thumbnail {input}", CreateNoWindow = true, RedirectStandardOutput = true, UseShellExecute = false }; youtubedl = Process.Start(youtubedlMetaData); youtubedl.WaitForExit(); string[] output = youtubedl.StandardOutput.ReadToEnd().Split('\n'); if (output.Length > 0) { midoFile.Title = output[0]; midoFile.FileName = youtubePath + output[1]; midoFile.Description = output[3]; midoFile.Thumbnail = output[2]; } return(midoFile); }
// Prints the playlist information. public void PrintPlaylist() { // If none, we return. int count = m_Playlist.Count; if (count == 0) { Log("There are currently no items in the playlist.", (int)LogOutput.Reply); return; } // Count the number of total digits. int countDigits = (int)(Math.Floor(Math.Log10(count) + 1)); // Create an embed builder. var emb = new EmbedBuilder(); emb.WithAuthor(author => { author.Name = "Current Playlist"; author.IconUrl = "https://i.imgur.com/GYpajrA.png"; }); // Get currently playing file MidoFile midoFile = m_AudioPlayer.GetCurrentMidoFile(); emb.WithTitle($"{midoFile.Title}"); for (int i = 0; i < count; i++) { // Prepend 0's so it matches in length. (What?, it didn't work.) string zeros = ""; int numDigits = (i == 0) ? 1 : (int)(Math.Floor(Math.Log10(i) + 1)); while (numDigits < countDigits) { zeros += "0"; ++numDigits; } // Filename. MidoFile current = m_Playlist.ElementAt(i); emb.AddField(zeros + i + 1, current); } emb.WithFooter(footer => { footer.Text = $"{count} tracks in the current playlist"; footer.IconUrl = rankaModule.Context.Client.CurrentUser.GetAvatarUrl(); }); emb.WithColor(Color.Red); DiscordReply(emb); }
// Extracts simple meta data from the path and fills a new AudioFile // information about the audio source. If it fails in the downloader or here, // we simply return null. private async Task <MidoFile> GetAudioFileAsync(string path) { try // We put this in a try catch block. { MidoFile song = await m_AudioDownloader.GetAudioFileInfo(path).ConfigureAwait(false); return(song); } catch { throw new Exception("Failed to get song"); } }
// Force Play the current audio in the voice channel of the target. // TODO: Consider adding it to autoplay list if it is already playing. public async Task ForcePlayAudioAsync(IGuild guild, IMessageChannel channel, string path) { // We can't play from an empty guild. if (guild == null) { return; } // Get audio info. MidoFile song = await GetAudioFileAsync(path).ConfigureAwait(false); // Can't play an empty song. if (song == null) { throw new Exception("I can't play it! ╯︿╰"); } // We can only resume autoplay on the last 'play' wait loop. We have to check other 'play's haven't been called. Interlocked.Increment(ref m_NumPlaysCalled); // To avoid any issues, we stop any other audio running. The audioplayer will also stop the current song... if (m_AudioPlayer.IsRunning()) { StopAudio(); } while (m_AudioPlayer.IsRunning()) { await Task.Delay(1000).ConfigureAwait(false); } // Start the stream, this is the main part of 'play' if (m_ConnectedChannels.TryGetValue(guild.Id, out var audioClient)) { Log($"Oke! I'll play {song.Title} now", (int)LogOutput.Reply); // Reply in the text channel. Log(song.Title, (int)LogOutput.Playing); // Set playing. await m_AudioPlayer.Play(audioClient, song).ConfigureAwait(false); // The song should already be identified as local or network. Log("nothing /_ \\", (int)LogOutput.Playing); } else { // If we can't get it from the dictionary, we're probably not connected to it yet. Log("Unable to play in the proper channel. Make sure the Mido client is connected.", 1); } // Uncount this play. Interlocked.Decrement(ref m_NumPlaysCalled); }
// Adds a song to the playlist. public async Task PlaylistAddAsync(string path) { // Get audio info. MidoFile audio = await GetAudioFileAsync(path).ConfigureAwait(false); if (audio != null) { m_Playlist.Enqueue(audio); // Only add if there's no errors. Log($"Added to playlist: {audio.Title}", (int)LogOutput.Reply); // If the downloader is set to true, we start the autodownload helper. if (m_AutoDownload) { m_AudioDownloader.Push(audio); // Auto download while in playlist. } } }
// This is for the autoplay function which waits after each playback and pulls from the playlist. // Since the playlist extracts the audio information, we can safely assume that it's chosen the local // if it exists, or just uses the network link. public async Task AutoPlayAudioAsync(IGuild guild, IMessageChannel channel) { // We can't play from an empty guild. if (guild == null) { return; } if (m_AutoPlayRunning) { return; // Only allow one instance of autoplay. } while (m_AutoPlayRunning = m_AutoPlay) { // If the audio player is already playing, we need to wait until it's fully finished. if (m_AudioPlayer.IsRunning()) { await Task.Delay(1000).ConfigureAwait(false); } // We do some checks before entering this loop. if (m_Playlist.IsEmpty || !m_AutoPlayRunning || !m_AutoPlay) { break; } // If there's nothing playing, start the stream, this is the main part of 'play' if (m_ConnectedChannels.TryGetValue(guild.Id, out var audioClient)) { MidoFile song = PlaylistNext(); // If null, nothing in the playlist. We can wait in this loop until there is. if (song != null) { Log($"Now playing: {song.Title}", (int)LogOutput.Reply); // Reply in the text channel. Log(song.Title, (int)LogOutput.Playing); // Set playing. await m_AudioPlayer.Play(audioClient, song).ConfigureAwait(false); // The song should already be identified as local or network. Log("nothing /_ \\", (int)LogOutput.Playing); } else { Log($"What is {song} ??? ~(>_<。)\"); } // We do the same checks again to make sure we exit right away. May not be necessary, but let's check anyways. if (m_Playlist.IsEmpty || !m_AutoPlayRunning || !m_AutoPlay) { break; } // Is null or done with playback. continue; } // If we can't get it from the dictionary, we're probably not connected to it yet. Log("Unable to play in the proper channel. Make sure the Mido client is connected."); break; } // Stops autoplay once we're done with it. if (m_AutoStop) { m_AutoPlay = false; } m_AutoPlayRunning = false; }