Skip to content

Commit

Permalink
feat: cleanup track loading (#1068)
Browse files Browse the repository at this point in the history
* feat: cleanup track loading

* fix: kdoc
  • Loading branch information
viztea authored Aug 16, 2024
1 parent 675aa16 commit 4384612
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 142 deletions.
95 changes: 0 additions & 95 deletions LavalinkServer/src/main/java/lavalink/server/player/AudioLoader.kt

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,21 @@
package lavalink.server.player

import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException
import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist
import com.sedmelluq.discord.lavaplayer.track.AudioTrack
import dev.arbjerg.lavalink.api.AudioPluginInfoModifier
import dev.arbjerg.lavalink.protocol.v4.EncodedTracks
import dev.arbjerg.lavalink.protocol.v4.LoadResult
import dev.arbjerg.lavalink.protocol.v4.Track
import dev.arbjerg.lavalink.protocol.v4.Tracks
import jakarta.servlet.http.HttpServletRequest
import lavalink.server.util.decodeTrack
import lavalink.server.util.toTrack
import lavalink.server.util.*
import org.slf4j.LoggerFactory
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
import org.springframework.web.server.ResponseStatusException
import java.util.concurrent.CompletionStage

@RestController
class AudioLoaderRestHandler(
Expand All @@ -53,7 +54,43 @@ class AudioLoaderRestHandler(
@RequestParam identifier: String
): ResponseEntity<LoadResult> {
log.info("Got request to load for identifier \"${identifier}\"")
return ResponseEntity.ok(AudioLoader(audioPlayerManager, pluginInfoModifiers).load(identifier))

val item = try {
loadAudioItem(audioPlayerManager, identifier)
} catch (ex: FriendlyException) {
log.error("Failed to load track", ex)
return ResponseEntity.ok(LoadResult.loadFailed(ex))
}

val result = when (item) {
null -> LoadResult.NoMatches()

is AudioTrack -> {
log.info("Loaded track ${item.info.title}")
LoadResult.trackLoaded(item.toTrack(audioPlayerManager, pluginInfoModifiers))
}

is AudioPlaylist -> {
log.info("Loaded playlist ${item.name}")

val tracks = item.tracks.map { it.toTrack(audioPlayerManager, pluginInfoModifiers) }
if (item.isSearchResult) {
LoadResult.searchResult(tracks)
} else {
LoadResult.playlistLoaded(item.toPlaylistInfo(), item.toPluginInfo(pluginInfoModifiers), tracks)
}
}

else -> {
log.error("Unknown item type: ${item.javaClass}")
throw ResponseStatusException(
HttpStatus.INTERNAL_SERVER_ERROR,
"Identifier returned unknown audio item type: ${item.javaClass.canonicalName}"
)
}
}

return ResponseEntity.ok(result)
}

@GetMapping("/v4/decodetrack")
Expand All @@ -62,7 +99,12 @@ class AudioLoaderRestHandler(
HttpStatus.BAD_REQUEST,
"No track to decode provided"
)
return ResponseEntity.ok(decodeTrack(audioPlayerManager, trackToDecode).toTrack(trackToDecode, pluginInfoModifiers))
return ResponseEntity.ok(
decodeTrack(audioPlayerManager, trackToDecode).toTrack(
trackToDecode,
pluginInfoModifiers
)
)
}

@PostMapping("/v4/decodetracks")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package lavalink.server.player

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 com.sedmelluq.discord.lavaplayer.track.TrackMarker
import dev.arbjerg.lavalink.api.AudioFilterExtension
Expand All @@ -18,7 +16,6 @@ import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
import org.springframework.web.server.ResponseStatusException
import java.util.concurrent.CompletableFuture

@RestController
class PlayerRestHandler(
Expand Down Expand Up @@ -60,7 +57,10 @@ class PlayerRestHandler(
val context = socketContext(socketServer, sessionId)

if (playerUpdate.track.isPresent() && (playerUpdate.encodedTrack is Omissible.Present || playerUpdate.identifier is Omissible.Present)) {
throw ResponseStatusException(HttpStatus.BAD_REQUEST, "Cannot specify both track and encodedTrack/identifier")
throw ResponseStatusException(
HttpStatus.BAD_REQUEST,
"Cannot specify both track and encodedTrack/identifier"
)
}

val track = if (playerUpdate.track.isPresent()) {
Expand Down Expand Up @@ -180,44 +180,19 @@ class PlayerRestHandler(
decodeTrack(context.audioPlayerManager, it)
}
} else {
val trackFuture = CompletableFuture<AudioTrack>()
context.audioPlayerManager.loadItemSync(
(identifier as Omissible.Present).value,
object : AudioLoadResultHandler {
override fun trackLoaded(track: AudioTrack) {
trackFuture.complete(track)
}

override fun playlistLoaded(playlist: AudioPlaylist) {
trackFuture.completeExceptionally(
ResponseStatusException(
HttpStatus.BAD_REQUEST,
"Cannot play a playlist or search result"
)
)
}

override fun noMatches() {
trackFuture.completeExceptionally(
ResponseStatusException(
HttpStatus.BAD_REQUEST,
"No matches found for identifier"
)
)
}

override fun loadFailed(exception: FriendlyException) {
trackFuture.completeExceptionally(
ResponseStatusException(
HttpStatus.INTERNAL_SERVER_ERROR,
exception.message,
getRootCause(exception)
)
)
}
})

trackFuture.join()
val item = try {
loadAudioItem(context.audioPlayerManager, (identifier as Omissible.Present).value)
// Safety: loadAudioItem ONLY throws FriendlyException
} catch (ex: FriendlyException) {
throw ResponseStatusException(HttpStatus.BAD_REQUEST, ex.message, getRootCause(ex))
}

if (item !is AudioTrack) throw ResponseStatusException(
HttpStatus.BAD_REQUEST,
if (item == null) "No matches found for identifier" else "Cannot play a playlist or search result"
)

item
}

newTrack?.let {
Expand Down
25 changes: 25 additions & 0 deletions LavalinkServer/src/main/java/lavalink/server/util/loading.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package lavalink.server.util

import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager
import com.sedmelluq.discord.lavaplayer.tools.ExceptionTools
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException
import com.sedmelluq.discord.lavaplayer.track.AudioItem

/**
* Loads an audio item from the specified [identifier].
*
* This method wraps any exceptions thrown by the [AudioPlayerManager.loadItem] method in a [FriendlyException].
* This is meant to maintain the behavior from callback-style item loading.
*/
fun loadAudioItem(manager: AudioPlayerManager, identifier: String): AudioItem? = try {
manager.loadItemSync(identifier)
} catch (ex: Throwable) {
// re-throw any errors that are not exceptions
ExceptionTools.rethrowErrors(ex)

throw FriendlyException(
"Something went wrong while looking up the track.",
FriendlyException.Severity.FAULT,
ex
)
}

0 comments on commit 4384612

Please sign in to comment.