public async Task NowPlayingAsync() { Language lang = Commands.GetLanguage(Context.Guild.Id); if (!_lavaNode.TryGetPlayer(Context.Guild, out LavaPlayer player)) { await ReplyAsync(lang.Not_connected); return; } if (player.PlayerState != PlayerState.Playing) { await ReplyAsync(lang.Not_playing); return; } LavaTrack track = player.Track; string artwork = await track.FetchArtworkAsync(); EmbedBuilder embed = new EmbedBuilder { Title = $"{track.Author} - {track.Title}", ThumbnailUrl = artwork, Url = track.Url } .AddField("Id", track.Id, true) .AddField("Duration", track.Duration, true) .AddField("Position", track.Position, true); await ReplyAsync(embed : embed.Build()); }
private async Task ReplyMusicExtended(LavaTrack track, bool added = true) { var url = await track.FetchArtworkAsync(); await ReplyMusicEmbedExtended( track.Title, track.Author, url, track.Duration.ToString(@"mm\:ss"), track.Url, added); }
public async Task ForceSkipAsync() { Language lang = Commands.GetLanguage(Context.Guild.Id); if (!_lavaNode.TryGetPlayer(Context.Guild, out LavaPlayer player)) { await ReplyAsync(lang.Not_connected); return; } if (player.PlayerState != PlayerState.Playing) { await ReplyAsync(lang.Not_playing); return; } SocketGuildUser user = Context.User as SocketGuildUser; bool isatsilvercraft = Commands.Is_at_silvercraft(Context.User); bool isbotadmin = false; if (isatsilvercraft) { isbotadmin = Commands.Is_bot_admin(user); } if (isbotadmin || Isdj((SocketGuildUser)Context.User) == 1) { try { LavaTrack oldTrack = player.Track; LavaTrack currenTrack = await player.SkipAsync(); EmbedBuilder b = new EmbedBuilder(); b.WithTitle($"Skipped: {oldTrack.Title}\nNow Playing: {currenTrack.Title}"); string david = await currenTrack.FetchArtworkAsync(); b.WithThumbnailUrl(david); b.WithFooter(lang.Requested_by + Context.User.Username, Commands.GetUserAvatarUrl(Context.User)); await ReplyAsync(embed : b.Build()); } catch (Exception exception) { await Exeptionhandle(exception, "forceskip").ConfigureAwait(false); throw; } } }
/// <summary> Creates a now playing embed for specified LavaTrack and returns the embed. </summary> /// <returns> The created embed. </returns> public static async Task <Embed> NowPlayingEmbed(LavaTrack track, bool withDuration = false) { var embed = new EmbedBuilder() .WithTitle("Now playing :cd:") .WithDescription($"[{track.Title}]({track.Url})") .WithThumbnailUrl(await track.FetchArtworkAsync()) .WithColor(Color.Blue); if (withDuration) { embed.WithDescription($"[{track.Title}]({track.Url})\n({track.Position:hh\\:mm\\:ss}/{track.Duration:hh\\:mm\\:ss})"); } return(embed.Build()); }
public static async Task <Discord.Embed> CreateSongPlayEmbed(LavaTrack song) { var artwork = await song.FetchArtworkAsync(); Color color = Color.Blue; var embed = await Task.Run(() => (new EmbedBuilder() .WithTitle("Now Playing: " + song.Title) .WithDescription("Author: " + song.Author + "\nDuration: " + song.Duration.ToString("c") + " (HH:MM:SS)") .WithUrl(song.Url) .WithImageUrl(artwork) .WithColor(color) .WithAuthor("[NightRune] Music Bot") .WithCurrentTimestamp().Build())); return(embed); }
public static async Task <Embed> GetEmbedQueue(LavaTrack track, CQueue <TrackInput> tracks , LavaTrack ptrack) { EmbedBuilder Embed = new EmbedBuilder { Title = "Playing Song", Description = $"[{track.Title}]({track.Url})" }; Embed.AddField("Length", track.Duration.ToString(), true); Embed.AddField("Tracks in Queue", (tracks.Count).ToString(), true); Embed.AddField("Previous Track", ptrack.Title, true); Embed.AddField("Next Track", (tracks.Count == 0) ? "No tracks" : (tracks[0]).Track.Title, true); Embed.ImageUrl = await track.FetchArtworkAsync(); return(Embed.Build()); }
private async Task SendPlayingEmbed(LavaPlayer player, LavaTrack track) { await player.PlayAsync(track); var artwork = await track.FetchArtworkAsync(); var embed = new EmbedBuilder() .WithAuthor("Now Playing", Context.Client.CurrentUser.GetAvatarUrl()) .WithTitle(track.Title) .WithUrl(track.Url) .WithThumbnailUrl(artwork) .AddField("Channel", track.Author, true) .AddField("Duration", track.Duration, true) .WithFooter($"Requested By {track.Queued.Username}") .WithColor(Color.Teal) .Build(); await SendEmbedAsync(embed); }
private async Task <EmbedBuilder> GetExtendedMusicEmbed(LavaTrack track) { var eb = new EmbedBuilder() { Color = SoraSocketCommandModule.Blue, Title = $"{SoraSocketCommandModule.MUSICAL_NOTE} Next: [{Formatter.FormatTime(track.Duration)}] - **{track.Title}**", Footer = new EmbedFooterBuilder() { Text = $"Video by {track.Author}" }, Url = track.Url, }; var imageUrl = await track.FetchArtworkAsync(); if (!string.IsNullOrWhiteSpace(imageUrl)) { eb.WithThumbnailUrl(imageUrl); } return(eb); }
private async Task <EmbedBuilder> ProduceNowPlayingEmbed(LavaTrack track, SocketUser requestingUser) { return(new EmbedBuilder { Author = new EmbedAuthorBuilder { Name = "Now Playing!" }, Title = track.Title, Description = track.Author, ThumbnailUrl = await track.FetchArtworkAsync(), Url = track.Url, Footer = new EmbedFooterBuilder { Text = $"This track was requested by {requestingUser.Username}#{requestingUser.Discriminator}", IconUrl = requestingUser.GetAvatarUrl() } } .AddField("Duration", $@"{track.Duration:mm\:ss}") .AddField("Position", $@"{track.Position:mm\:ss}")); }
public async Task PlayAsync([Remainder] string searchQuery) { Language lang = Commands.GetLanguage(Context.Guild.Id); if (!_lavaNode.HasPlayer(Context.Guild)) { IVoiceState voiceState = Context.User as IVoiceState; if (voiceState?.VoiceChannel == null) { EmbedBuilder b = new EmbedBuilder(); b.WithTitle(lang.Not_connected); b.WithFooter(lang.Requested_by + Context.User.Username, Commands.GetUserAvatarUrl(Context.User)); await ReplyAsync(embed : b.Build()); return; } try { await _lavaNode.JoinAsync(voiceState.VoiceChannel, Context.Channel as ITextChannel); EmbedBuilder b = new EmbedBuilder(); b.WithTitle(lang.Joined_before + voiceState.VoiceChannel.Name + lang.Joined_after); b.WithFooter(lang.Requested_by + Context.User.Username, Commands.GetUserAvatarUrl(Context.User)); await ReplyAsync(embed : b.Build()); } catch (Exception exception) { await Exeptionhandle(exception, "join in play").ConfigureAwait(false); throw; } } LavaPlayer player = _lavaNode.GetPlayer(Context.Guild); if (player.PlayerState == PlayerState.Paused && string.IsNullOrEmpty(searchQuery)) { try { await player.ResumeAsync(); await ReplyAsync(lang.Resumed_front + player.Track.Title); return; } catch (Exception exception) { await Exeptionhandle(exception, "resume in play").ConfigureAwait(false); throw; } } else { if (string.IsNullOrWhiteSpace(searchQuery)) { await ReplyAsync(lang.No_search_term); return; } } int searchtype = 0; Victoria.Responses.Rest.SearchResponse searchResponse = await _lavaNode.SearchAsync(searchQuery); if (searchResponse.LoadStatus == LoadStatus.LoadFailed || searchResponse.LoadStatus == LoadStatus.NoMatches) { searchResponse = await _lavaNode.SearchYouTubeAsync(searchQuery); searchtype = 1; if (searchResponse.LoadStatus == LoadStatus.LoadFailed || searchResponse.LoadStatus == LoadStatus.NoMatches) { searchResponse = await _lavaNode.SearchSoundCloudAsync(searchQuery); searchtype = 2; if (searchResponse.LoadStatus == LoadStatus.LoadFailed || searchResponse.LoadStatus == LoadStatus.NoMatches) { EmbedBuilder eb = new EmbedBuilder(); eb.WithTitle(lang.No_results_front + searchQuery + lang.No_results_back); eb.WithFooter(lang.Requested_by + Context.User.Username, Commands.GetUserAvatarUrl(Context.User)); await ReplyAsync($"", false, eb.Build()); return; } } } if (player.PlayerState == PlayerState.Playing || player.PlayerState == PlayerState.Paused) { if (!string.IsNullOrWhiteSpace(searchResponse.Playlist.Name)) { foreach (LavaTrack track in searchResponse.Tracks) { player.Queue.Enqueue(track); } await ReplyAsync($"Enqueued {searchResponse.Tracks.Count} tracks."); } else { LavaTrack track = searchResponse.Tracks[0]; player.Queue.Enqueue(track); await ReplyAsync($"Enqueued: {track.Title}"); } } else { LavaTrack track = searchResponse.Tracks[0]; if (!string.IsNullOrWhiteSpace(searchResponse.Playlist.Name)) { for (int i = 0; i < searchResponse.Tracks.Count; i++) { if (i == 0) { await player.PlayAsync(track); EmbedBuilder b = new EmbedBuilder(); b.WithTitle($"Now playing: {track.Title}"); if (searchtype == 1) { b.AddField("source", "<:youtube:793403957871247360> search"); } if (searchtype == 2) { b.AddField("source", "<:soundcloud:793405493204090911> search"); } string art = await track.FetchArtworkAsync(); b.WithThumbnailUrl(art); b.WithFooter(lang.Requested_by + Context.User.Username, Commands.GetUserAvatarUrl(Context.User)); await ReplyAsync(embed : b.Build()); } else { if (searchResponse.Tracks[i] == null) { await ReplyAsync(i + " was null"); } player.Queue.Enqueue(searchResponse.Tracks[i]); } } await ReplyAsync($"Enqueued {searchResponse.Tracks.Count} tracks."); } else { await player.PlayAsync(track); EmbedBuilder b = new EmbedBuilder(); b.WithTitle($"Now playing: {track.Title}"); if (searchtype == 1) { b.AddField("source", "<:youtube:793403957871247360> search"); } if (searchtype == 2) { b.AddField("source", "<:soundcloud:793405493204090911> search"); } string art = await track.FetchArtworkAsync(); b.WithThumbnailUrl(art); b.WithFooter(new Language().Requested_by + Context.User.Username, Commands.GetUserAvatarUrl(Context.User)); await ReplyAsync(embed : b.Build()); } } }
public async Task SkipAsync() { Language lang = Commands.GetLanguage(Context.Guild.Id); if (!_lavaNode.TryGetPlayer(Context.Guild, out LavaPlayer player)) { await ReplyAsync(lang.Not_connected); return; } if (player.PlayerState != PlayerState.Playing) { await ReplyAsync(lang.Not_playing); return; } if (!thing1.ContainsKey(player.VoiceChannel.GuildId)) { thing1.TryAdd(player.VoiceChannel.GuildId, new HashSet <ulong>()); } SocketGuildUser[] voiceChannelUsers = (player.VoiceChannel as SocketVoiceChannel).Users.Where(x => !x.IsBot).ToArray(); if (thing1[player.VoiceChannel.GuildId].Contains(Context.User.Id)) { await ReplyAsync(lang.Already_voted); return; } thing1[player.VoiceChannel.GuildId].Add(Context.User.Id); int percentage = thing1[player.VoiceChannel.GuildId].Count / voiceChannelUsers.Length * 100; if (percentage < 85) { await ReplyAsync(lang.Voting_is_below_85_percent); return; } try { LavaTrack oldTrack = player.Track; LavaTrack currenTrack = await player.SkipAsync(); EmbedBuilder b = new EmbedBuilder(); b.WithTitle($"Skipped: {oldTrack.Title}\nNow Playing: {currenTrack.Title}"); string david = await currenTrack.FetchArtworkAsync(); b.WithThumbnailUrl(david); b.WithFooter("Requested by CONSOLE using votes", "https://cdn.discordapp.com/attachments/728360861483401240/728362412373180566/console.png"); await ReplyAsync(embed : b.Build()); thing1.TryRemove(player.VoiceChannel.GuildId, out HashSet <ulong> bitch); } catch (Exception exception) { await Exeptionhandle(exception, "skip").ConfigureAwait(false); throw; } }
/// <summary> /// Searches the specified <see cref="SearchProvider" /> for the provided <see cref="query" />. /// This method also adds the song to the guild's player queue and will even join the user's voice /// channel automatically. /// </summary> /// <param name="context"></param> /// <param name="query">The song to search for, user input.</param> /// <param name="playFirst"></param> /// <param name="provider"></param> /// <returns></returns> public async Task <ReactionCallbackData> SearchAndPlayAsync(ShardedCommandContext context, string query, bool playFirst = false, SearchProvider provider = SearchProvider.YOU_TUBE) { User user = await DatabaseQueries.GetOrCreateUserAsync(context.User.Id); Server server = await DatabaseQueries.GetOrCreateServerAsync(context.Guild.Id); LavaNode node = ConfigProperties.LavaNode; SocketVoiceChannel curVc = (context.User as SocketGuildUser).VoiceChannel; await ConsoleLogger.LogAsync($"Found node and voice channel for guild {context.Guild.Id}.", LogLvl.TRACE); if (curVc == null) { await context.Channel.SendMessageAsync($"{context.User.Mention} You must be in a voice " + "channel to use this command."); await ConsoleLogger.LogAsync("User was not in voice channel, cancelling music search operation.", LogLvl.TRACE); return(null); } SearchResponse result = provider switch { SearchProvider.YOU_TUBE => await node.SearchYouTubeAsync(query), SearchProvider.SOUNDCLOUD => await node.SearchSoundCloudAsync(query), _ => await node.SearchAsync(query) }; if (provider == SearchProvider.TWITCH) { const string PROVIDER_URL = "www.twitch.tv"; string errorString = "Your search returned no results. Ensure you are only " + "typing the name of the streamer who you want to watch or a direct link to their stream.\n\n" + "Note: The streamer must be live for this feature to work."; if (!query.ToLower().Contains(PROVIDER_URL)) { result = await node.SearchAsync($"https://{PROVIDER_URL}/{query}"); if (result.Tracks.Count == 0) { await context.Channel.SendBasicErrorEmbedAsync(errorString); await ConsoleLogger.LogAsync($"No livestream found for search {query} in guild {context.Guild.Id}.", LogLvl.TRACE); return(null); } } else { if ((await node.SearchAsync($"https://{PROVIDER_URL}/{query.Split('\\').Last()}")).Tracks.Count == 0 && (await node.SearchAsync(query)).Tracks.Count == 0) { await context.Channel.SendBasicErrorEmbedAsync(errorString); await ConsoleLogger.LogAsync($"No livestream found for search {query} in guild {context.Guild.Id}.", LogLvl.TRACE); return(null); } } } var tracks = new List <LavaTrack>(); if (user.IsPremium || server.IsPremium) { if (result.Tracks.Any()) { tracks.AddRange(result.Tracks); } } else { // Limit track duration to 10 minutes for non-premium servers/users. if (result.Tracks.Any()) { tracks.AddRange(result.Tracks.Where(x => x.Duration.TotalMinutes < 10).ToList()); } } if (!tracks.Any()) { string suppString = user.IsPremium ? "" : "If you are " + $"not a [Kaguya Premium Subscriber]({ConfigProperties.KAGUYA_STORE_URL}), " + "you are only limited to playing songs less than `10 minutes` in duration."; await context.Channel.SendBasicErrorEmbedAsync($"Your requested search returned no results. {suppString}"); await ConsoleLogger.LogAsync("Search request returned no usable " + $"results in guild {Context.Guild.Id} for query {query}", LogLvl.TRACE); } var fields = new List <EmbedFieldBuilder>(); var callbacks = new List <(IEmote, Func <SocketCommandContext, SocketReaction, Task>)>(); Emoji[] emojiNums = GlobalProperties.EmojisOneThroughNine(); LavaPlayer player = node.HasPlayer(context.Guild) ? node.GetPlayer(context.Guild) : await node.JoinAsync(curVc); await ConsoleLogger.LogAsync($"Player found for guild {context.Guild.Id}. Connected to voice channel.", LogLvl.TRACE); #region If the track is a livestream: if (tracks.Any(x => x.IsStream)) { LavaTrack trackSel = tracks.First(x => x.IsStream); // Gathers the first stream from the collection. string twitchName = (await ConfigProperties.TwitchApi.V5.Users.GetUserByNameAsync(trackSel.Author)).Matches[0].DisplayName; string playString = player.PlayerState == PlayerState.Playing ? $"Queued stream into position {player.Queue.Count}." : $"Now playing `{twitchName}`'s stream."; if (player.PlayerState == PlayerState.Playing) { try { player.Queue.Enqueue(trackSel); await ConsoleLogger.LogAsync($"Enqueued livestream {trackSel.Title} in guild {context.Guild.Id}", LogLvl.TRACE); } catch (Exception e) { await ConsoleLogger.LogAsync("An exception was thrown when trying to enqueue the livestream " + $"{trackSel.Title} in guild {Context.Guild.Id}.\n" + $"Exception Message: {e.Message}\n" + $"Stack Trace: {e.StackTrace}", LogLvl.WARN); } } else { try { await player.PlayAsync(trackSel); await ConsoleLogger.LogAsync($"Playing livestream {trackSel.Title} in guild {context.Guild.Id}", LogLvl.TRACE); } catch (Exception e) { await ConsoleLogger.LogAsync("An exception was thrown when trying to play track " + $"{trackSel.Title} in guild {Context.Guild.Id}.\n" + $"Exception Message: {e.Message}\n" + $"Stack Trace: {e.StackTrace}", LogLvl.WARN); } } var field = new EmbedFieldBuilder { Name = $"`{twitchName}`'s Stream", Value = $"{playString}\n" // We get rid of backticks for formatting. }; var embed = new KaguyaEmbedBuilder { Fields = new List <EmbedFieldBuilder> { field } }; await context.Channel.SendEmbedAsync(embed); return(null); } #endregion #region If we have chosen to only play the default track (via $play). if (playFirst && tracks.Any()) { LavaTrack trackSel = tracks[0]; var field = new EmbedFieldBuilder { Name = "Track #1.", Value = $"Title: `{trackSel.Title.Replace("`", "")}`\n" + // We get rid of backticks for formatting. $"Duration: `{trackSel.Duration.Humanize(minUnit: TimeUnit.Second, maxUnit: TimeUnit.Hour, precision: 3)}`\n" + $"Uploader: `{trackSel.Author}`" }; string playString = player.PlayerState == PlayerState.Playing && !player.Track.IsStream ? $"Queued track #1 into position {player.Queue.Count + 1}." : "Now playing track #1."; if (player.PlayerState == PlayerState.Playing) { if (player.Queue.Count() == 50 && !server.IsPremium) { await ConsoleLogger.LogAsync($"Queue is full in {context.Guild.Id}, sending error.", LogLvl.TRACE); await SendBasicErrorEmbedAsync("Your queue is full! `50 songs` is the maximum " + $"for non [Kaguya Premium]({ConfigProperties.KAGUYA_STORE_URL}) " + "servers."); } else { player.Queue.Enqueue(trackSel); await ConsoleLogger.LogAsync($"Enqueued track {trackSel.Title} in guild {context.Guild.Id}.", LogLvl.TRACE); if (player.Track.IsStream) { await player.SkipAsync(); await ConsoleLogger.LogAsync($"Skipped livestream to play incoming track in guild {context.Guild.Id}.", LogLvl.TRACE); } } } else { try { await player.PlayAsync(trackSel); await ConsoleLogger.LogAsync($"Playing track {trackSel.Title} in guild {context.Guild.Id}", LogLvl.TRACE); } catch (Exception e) { await ConsoleLogger.LogAsync("An exception was thrown when trying to play track " + $"{trackSel.Title} in guild {Context.Guild.Id}.\n" + $"Exception Message: {e.Message}\n" + $"Stack Trace: {e.StackTrace}", LogLvl.WARN); } } if (player.Volume == 0 && player.PlayerState == PlayerState.Playing) { await player.UpdateVolumeAsync(75); // Sets the volume back to default if it is muted. await ConsoleLogger.LogAsync($"Automatically set player volume to 75 in guild {context.Guild.Id}.", LogLvl.TRACE); } var embed = new KaguyaEmbedBuilder { Title = $"Kaguya Music {Centvrio.Emoji.Music.Notes}", Description = playString, ThumbnailUrl = await trackSel.FetchArtworkAsync(), Fields = new List <EmbedFieldBuilder> { field } }; await SendEmbedAsync(embed, context); return(null); } #endregion int h = tracks.Count; for (int i = 0; i < (h < 7 ? h : 7); i++) { int i1 = i; LavaTrack trackSel = tracks[i]; var field = new EmbedFieldBuilder { Name = $"Track {i1 + 1}.", Value = $"Title: `{trackSel.Title.Replace("`", "")}`\n" + // We get rid of backticks for formatting. $"Duration: `{trackSel.Duration.Humanize(minUnit: TimeUnit.Second, maxUnit: TimeUnit.Hour, precision: 3)}`\n" + $"Uploader: `{trackSel.Author}`" }; fields.Add(field); callbacks.Add((emojiNums[i], async(c, r) => { string playString = player.PlayerState == PlayerState.Playing && !player.Track.IsStream ? $"Queued track #{i1 + 1} into position {player.Queue.Count + 1}." : $"Now playing track #{i1 + 1}."; if (player.PlayerState == PlayerState.Playing) { if (player.Queue.Count() == 50 && !server.IsPremium) { await ConsoleLogger.LogAsync($"Queue was full in guild {context.Guild.Id}. Sending error message.", LogLvl.TRACE); await SendBasicErrorEmbedAsync("Your queue is full! `50 songs` is the maximum " + $"for non [Kaguya Premium]({ConfigProperties.KAGUYA_STORE_URL}) " + "servers."); return; } player.Queue.Enqueue(trackSel); await ConsoleLogger.LogAsync($"Enqueued track {trackSel} in guild {context.Guild.Id}", LogLvl.TRACE); if (player.Track.IsStream) { await player.SkipAsync(); await ConsoleLogger.LogAsync("Automatically skipped livestream to play" + $" incoming track in guild {context.Guild.Id}", LogLvl.TRACE); } } else { try { await player.PlayAsync(trackSel); await ConsoleLogger.LogAsync($"Playing track {trackSel.Title} in guild {context.Guild.Id}", LogLvl.TRACE); } catch (Exception e) { await ConsoleLogger.LogAsync("An exception was thrown when trying to play track " + $"{trackSel.Title} in guild {Context.Guild.Id}.\n" + $"Exception Message: {e.Message}\n" + $"Stack Trace: {e.StackTrace}", LogLvl.WARN); } } if (player.Volume == 0 && player.PlayerState == PlayerState.Playing) { await player.UpdateVolumeAsync(75); // Sets the volume back to default if it is muted. await ConsoleLogger.LogAsync($"Automatically set volume to 75 in guild {context.Guild.Id}", LogLvl.TRACE); } var embed = new KaguyaEmbedBuilder { Title = $"Kaguya Music {Centvrio.Emoji.Music.Notes}", Description = playString, ThumbnailUrl = await trackSel.FetchArtworkAsync(), Fields = new List <EmbedFieldBuilder> { field } }; await SendEmbedAsync(embed); } )); } callbacks.Add((GlobalProperties.NoEntryEmoji(), async(c, r) => { await c.Message.DeleteAsync(); await r.Message.Value.DeleteAsync(); })); string s = tracks.Count == 1 ? "" : "s"; var songDisplayEmbed = new KaguyaEmbedBuilder { Title = "Kaguya Music Search Results", Description = $" I found {tracks.Count} track{s} from {provider}, " + $"{(tracks.Count > 5 ? "but here are the top 5" : "here they are")}. " + "Please select a track to play.", Fields = fields }; var data = new ReactionCallbackData("", songDisplayEmbed.Build(), false, false, TimeSpan.FromSeconds(60)); data.SetCallbacks(callbacks); return(data); } }