205 lines
6.8 KiB
Kotlin
205 lines
6.8 KiB
Kotlin
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<Long, TrackScheduler>()
|
|
|
|
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
|
|
}
|
|
} |