package nl.voidcorp.dbot.commands import com.jagrosh.jdautilities.command.CommandBuilder import com.jagrosh.jdautilities.command.CommandEvent import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler import com.sedmelluq.discord.lavaplayer.player.AudioPlayer import com.sedmelluq.discord.lavaplayer.source.AudioSourceManagers import com.sedmelluq.discord.lavaplayer.tools.FriendlyException import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist import com.sedmelluq.discord.lavaplayer.track.AudioTrack import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrame import net.dv8tion.jda.core.EmbedBuilder import net.dv8tion.jda.core.audio.AudioSendHandler import net.dv8tion.jda.core.entities.Member import nl.voidcorp.dbot.cb import nl.voidcorp.dbot.log import nl.voidcorp.dbot.music.TrackScheduler import nl.voidcorp.dbot.playerManager import java.time.LocalDateTime val guildMusicMap = mutableMapOf() fun initMusic() { AudioSourceManagers.registerRemoteSources(playerManager) val queueCommand = CommandBuilder().setName("queue").addAlias("q").setHelp("Queue's a song").build { event -> val scheduler = if (guildMusicMap.containsKey(event.guild.idLong)) guildMusicMap[event.guild.idLong]!! else { val channel = event.guild.voiceChannels.firstOrNull { it.members.contains(event.member) } if (channel == null) { event.reply("Join a voice Channel please!") return@build } val s = TrackScheduler(playerManager.createPlayer(), event.guild, channel) guildMusicMap[event.guild.idLong] = s s } playerManager.loadItem(event.args, object : AudioLoadResultHandler { override fun loadFailed(exception: FriendlyException) { event.reply("Shit's fucked!") } override fun trackLoaded(track: AudioTrack) { scheduler.queue(track, event.member) } override fun noMatches() { getLinkFromSearch(event, scheduler) } override fun playlistLoaded(playlist: AudioPlaylist) { for (t in playlist.tracks) { scheduler.queue(t, event.member) } } }) } val playCommand = CommandBuilder().setName("play").addAlias("p").setHelp("Plays the song instantly").build { event -> val scheduler = if (guildMusicMap.containsKey(event.guild.idLong)) guildMusicMap[event.guild.idLong]!! else { val channel = event.guild.voiceChannels.firstOrNull { it.members.contains(event.member) } if (channel == null) { event.reply("Join a voice Channel please!") return@build } val s = TrackScheduler(playerManager.createPlayer(), event.guild, channel) guildMusicMap[event.guild.idLong] = s s } playerManager.loadItem(event.args, object : AudioLoadResultHandler { override fun loadFailed(exception: FriendlyException) { event.reply("Shit's fucked!") } override fun trackLoaded(track: AudioTrack) { scheduler.insertFront(track, event.member) } override fun noMatches() { getLinkFromSearch(event, scheduler) } override fun playlistLoaded(playlist: AudioPlaylist) { for (t in playlist.tracks) { scheduler.insertFront(t, event.member) } } }) } val skipCommand = CommandBuilder().setName("skip").addAlias("s").setHelp("Skips the currently playing track").build { event -> val scheduler = guildMusicMap[event.guild.idLong] if (scheduler == null) { event.reply("There is no music playing?") } else { scheduler.skip() } } cb.addCommands(playCommand, skipCommand, queueCommand) } fun getLinkFromSearch(event: CommandEvent, scheduler: TrackScheduler) { log.info("Searching for '${event.args}'") /*val search = yt.search().list("id,snippet") search.key = "AIzaSyDiEYrQNT-eDRZKy6JvQHBDymttwaLd7Mg" search.q = event.args search.type = "video" search.fields = "items(id/kind,id/videoId,snippet/title,snippet/thumbnails/high/url,snippet/description,snippet/channelTitle)" search.maxResults = 10 val res = search.execute() if (res.isEmpty()) { event.reply("Really nothing was found...") } else { var found = false for (r in res.items) { if (r.id.kind == "youtube#video" && !found) { found = true val id = r.id.videoId } } if (!found) { event.replyError("I could really not find anything for '${event.args}'") } }*/ playerManager.loadItem("ytsearch:${event.args}", object : AudioLoadResultHandler { override fun loadFailed(exception: FriendlyException) { event.reply("Shit's fucked!") } override fun trackLoaded(track: AudioTrack) { scheduler.queue(track, event.member) /*event.reply( EmbedBuilder().setImage(r.snippet.thumbnails.high.url).setTitle(r.snippet.title, "https://youtu.be/$id") .setAuthor(r.snippet.channelTitle).setFooter("Requested by ${event.member.effectiveName}", event.author.effectiveAvatarUrl) .setDescription(r.snippet.description).build() )*/ } override fun noMatches() { } override fun playlistLoaded(playlist: AudioPlaylist) { if (!playlist.isSearchResult) for (t in playlist.tracks) { scheduler.queue(t, event.member) } else { val track = playlist.tracks.first() event.reply(EmbedBuilder() .setFooter("Requested by ${event.member.effectiveName}", event.member.user.effectiveAvatarUrl) .setAuthor(track.info.author).setTitle(track.info.title, track.info.uri) .setThumbnail("https://img.youtube.com/vi/${track.info.identifier}/hqdefault.jpg\n") .setTimestamp(LocalDateTime.now()).build()) scheduler.queue(track, event.member) } } }) } class AudioPlayerSendHandler(private val audioPlayer: AudioPlayer) : AudioSendHandler { private var lastFrame: AudioFrame? = null override fun canProvide(): Boolean { lastFrame = audioPlayer.provide() return lastFrame != null } override fun provide20MsAudio(): ByteArray { return lastFrame!!.data } override fun isOpus(): Boolean { return true } }