Woo, audio! Added a basic play command, which for now just loads a totally random video. Also added a kill command to forcefully stop a connection, might move that to debug
This commit is contained in:
parent
e8ae29d1ce
commit
faab0c818c
|
@ -35,6 +35,7 @@ dependencies {
|
|||
testImplementation "org.junit.jupiter:junit-jupiter:5.4.2"
|
||||
|
||||
implementation 'net.dv8tion:JDA:4.ALPHA.0_88'
|
||||
implementation 'com.sedmelluq:lavaplayer:1.3.17'
|
||||
|
||||
implementation "com.h2database:h2"
|
||||
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
package nl.voidcorp.discord
|
||||
|
||||
import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager
|
||||
import com.sedmelluq.discord.lavaplayer.source.AudioSourceManagers
|
||||
import net.dv8tion.jda.api.sharding.DefaultShardManagerBuilder
|
||||
import nl.voidcorp.discord.events.CommandListener
|
||||
import nl.voidcorp.discord.events.OttoListener
|
||||
import org.springframework.stereotype.Component
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Component
|
||||
class Loader(listener: CommandListener) {
|
||||
|
||||
@Service
|
||||
class Loader(listener: CommandListener, playerManager: DefaultAudioPlayerManager) {
|
||||
init {
|
||||
val token = System.getenv("DISCORD_TOKEN") ?: throw RuntimeException("'DISCORD_TOKEN' not set!")
|
||||
val builder = DefaultShardManagerBuilder(token)
|
||||
|
@ -16,5 +19,6 @@ class Loader(listener: CommandListener) {
|
|||
builder.addEventListeners(OttoListener, listener)
|
||||
|
||||
jda = builder.build()
|
||||
AudioSourceManagers.registerRemoteSources(playerManager)
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ package nl.voidcorp.discord.command
|
|||
enum class CommandGroup {
|
||||
GENERAL,
|
||||
FUN,
|
||||
MUSIC,
|
||||
ROLES,
|
||||
ADMIN,
|
||||
VeRY_hIdden_CaTegoRY_LoL,
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package nl.voidcorp.discord.commands.music
|
||||
|
||||
import nl.voidcorp.discord.command.*
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class ForceLeave : Command(
|
||||
"forceleave",
|
||||
group = CommandGroup.MUSIC,
|
||||
location = CommandSource.GUILD,
|
||||
commandLevel = CommandLevel.MODERATOR
|
||||
) {
|
||||
override fun handle(event: CommandMessage): CommandResult {
|
||||
event.guild!!.audioManager.closeAudioConnection()
|
||||
return CommandResult.SUCCESS
|
||||
}
|
||||
}
|
28
src/main/kotlin/nl/voidcorp/discord/commands/music/Play.kt
Normal file
28
src/main/kotlin/nl/voidcorp/discord/commands/music/Play.kt
Normal file
|
@ -0,0 +1,28 @@
|
|||
package nl.voidcorp.discord.commands.music
|
||||
|
||||
import nl.voidcorp.discord.command.*
|
||||
import nl.voidcorp.discord.music.AudioLoadHandler
|
||||
import nl.voidcorp.discord.music.PlayerManager
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class Play(val playerManager: PlayerManager) :
|
||||
Command("play", location = CommandSource.GUILD, group = CommandGroup.MUSIC) {
|
||||
override fun handle(event: CommandMessage): CommandResult {
|
||||
val chan = event.member!!.voiceState!!.channel
|
||||
if (chan == null) {
|
||||
event.reply("Please join a voice channel to play music!")
|
||||
return CommandResult.SUCCESS
|
||||
}
|
||||
val am = event.guild!!.audioManager
|
||||
|
||||
am.openAudioConnection(chan)
|
||||
|
||||
val ts = playerManager.getGuildPlayer(event.guild)
|
||||
|
||||
playerManager.loadItem("https://www.youtube.com/watch?v=kPgiJUeSP6Q", AudioLoadHandler(ts))
|
||||
|
||||
|
||||
return CommandResult.SUCCESS
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package nl.voidcorp.discord.music
|
||||
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler
|
||||
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioTrack
|
||||
import nl.voidcorp.discord.logger
|
||||
|
||||
|
||||
class AudioLoadHandler(private val trackScheduler: TrackScheduler) : AudioLoadResultHandler {
|
||||
|
||||
override fun loadFailed(exception: FriendlyException) {
|
||||
throw exception
|
||||
}
|
||||
|
||||
override fun trackLoaded(track: AudioTrack) {
|
||||
logger.info("loaded track ${track.identifier}")
|
||||
trackScheduler.queue(track)
|
||||
}
|
||||
|
||||
override fun noMatches() {
|
||||
|
||||
}
|
||||
|
||||
override fun playlistLoaded(playlist: AudioPlaylist) {
|
||||
for (t in playlist.tracks) {
|
||||
trackScheduler.queue(t)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package nl.voidcorp.discord.music
|
||||
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer
|
||||
import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrame
|
||||
import net.dv8tion.jda.api.audio.AudioSendHandler
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
|
||||
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() = ByteBuffer.wrap(lastFrame!!.data)
|
||||
|
||||
override fun isOpus(): Boolean {
|
||||
return true
|
||||
}
|
||||
}
|
22
src/main/kotlin/nl/voidcorp/discord/music/PlayerManager.kt
Normal file
22
src/main/kotlin/nl/voidcorp/discord/music/PlayerManager.kt
Normal file
|
@ -0,0 +1,22 @@
|
|||
package nl.voidcorp.discord.music
|
||||
|
||||
import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager
|
||||
import net.dv8tion.jda.api.entities.Guild
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class PlayerManager : DefaultAudioPlayerManager() {
|
||||
val guildPlayMap = mutableMapOf<Long, TrackScheduler>()
|
||||
fun getGuildPlayer(guild: Guild): TrackScheduler {
|
||||
return if (guildPlayMap.containsKey(guild.idLong)) {
|
||||
guildPlayMap[guild.idLong] ?: error("oof?")
|
||||
} else {
|
||||
val player = createPlayer()
|
||||
val ts = TrackScheduler(player)
|
||||
player.addListener(ts)
|
||||
guild.audioManager.sendingHandler = AudioPlayerSendHandler(player)
|
||||
guildPlayMap[guild.idLong] = ts
|
||||
ts
|
||||
}
|
||||
}
|
||||
}
|
25
src/main/kotlin/nl/voidcorp/discord/music/TrackScheduler.kt
Normal file
25
src/main/kotlin/nl/voidcorp/discord/music/TrackScheduler.kt
Normal file
|
@ -0,0 +1,25 @@
|
|||
package nl.voidcorp.discord.music
|
||||
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer
|
||||
import com.sedmelluq.discord.lavaplayer.player.event.AudioEventAdapter
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioTrack
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason
|
||||
import java.util.*
|
||||
|
||||
class TrackScheduler(private val player: AudioPlayer) : AudioEventAdapter() {
|
||||
private val queue = ArrayDeque<AudioTrack>()
|
||||
fun queue(track: AudioTrack) {
|
||||
if (!player.startTrack(track, true)) {
|
||||
queue.addLast(track)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun pop() = queue.pop()
|
||||
|
||||
override fun onTrackEnd(player: AudioPlayer, track: AudioTrack, endReason: AudioTrackEndReason) {
|
||||
if (endReason.mayStartNext && queue.isNotEmpty()) {
|
||||
player.startTrack(pop(), true)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue