Skip to content

Commit 4384612

Browse files
authored
feat: cleanup track loading (#1068)
* feat: cleanup track loading * fix: kdoc
1 parent 675aa16 commit 4384612

File tree

4 files changed

+89
-142
lines changed

4 files changed

+89
-142
lines changed

LavalinkServer/src/main/java/lavalink/server/player/AudioLoader.kt

Lines changed: 0 additions & 95 deletions
This file was deleted.

LavalinkServer/src/main/java/lavalink/server/player/AudioLoaderRestHandler.kt

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,21 @@
2222
package lavalink.server.player
2323

2424
import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager
25+
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException
26+
import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist
27+
import com.sedmelluq.discord.lavaplayer.track.AudioTrack
2528
import dev.arbjerg.lavalink.api.AudioPluginInfoModifier
2629
import dev.arbjerg.lavalink.protocol.v4.EncodedTracks
2730
import dev.arbjerg.lavalink.protocol.v4.LoadResult
2831
import dev.arbjerg.lavalink.protocol.v4.Track
2932
import dev.arbjerg.lavalink.protocol.v4.Tracks
3033
import jakarta.servlet.http.HttpServletRequest
31-
import lavalink.server.util.decodeTrack
32-
import lavalink.server.util.toTrack
34+
import lavalink.server.util.*
3335
import org.slf4j.LoggerFactory
3436
import org.springframework.http.HttpStatus
3537
import org.springframework.http.ResponseEntity
3638
import org.springframework.web.bind.annotation.*
3739
import org.springframework.web.server.ResponseStatusException
38-
import java.util.concurrent.CompletionStage
3940

4041
@RestController
4142
class AudioLoaderRestHandler(
@@ -53,7 +54,43 @@ class AudioLoaderRestHandler(
5354
@RequestParam identifier: String
5455
): ResponseEntity<LoadResult> {
5556
log.info("Got request to load for identifier \"${identifier}\"")
56-
return ResponseEntity.ok(AudioLoader(audioPlayerManager, pluginInfoModifiers).load(identifier))
57+
58+
val item = try {
59+
loadAudioItem(audioPlayerManager, identifier)
60+
} catch (ex: FriendlyException) {
61+
log.error("Failed to load track", ex)
62+
return ResponseEntity.ok(LoadResult.loadFailed(ex))
63+
}
64+
65+
val result = when (item) {
66+
null -> LoadResult.NoMatches()
67+
68+
is AudioTrack -> {
69+
log.info("Loaded track ${item.info.title}")
70+
LoadResult.trackLoaded(item.toTrack(audioPlayerManager, pluginInfoModifiers))
71+
}
72+
73+
is AudioPlaylist -> {
74+
log.info("Loaded playlist ${item.name}")
75+
76+
val tracks = item.tracks.map { it.toTrack(audioPlayerManager, pluginInfoModifiers) }
77+
if (item.isSearchResult) {
78+
LoadResult.searchResult(tracks)
79+
} else {
80+
LoadResult.playlistLoaded(item.toPlaylistInfo(), item.toPluginInfo(pluginInfoModifiers), tracks)
81+
}
82+
}
83+
84+
else -> {
85+
log.error("Unknown item type: ${item.javaClass}")
86+
throw ResponseStatusException(
87+
HttpStatus.INTERNAL_SERVER_ERROR,
88+
"Identifier returned unknown audio item type: ${item.javaClass.canonicalName}"
89+
)
90+
}
91+
}
92+
93+
return ResponseEntity.ok(result)
5794
}
5895

5996
@GetMapping("/v4/decodetrack")
@@ -62,7 +99,12 @@ class AudioLoaderRestHandler(
6299
HttpStatus.BAD_REQUEST,
63100
"No track to decode provided"
64101
)
65-
return ResponseEntity.ok(decodeTrack(audioPlayerManager, trackToDecode).toTrack(trackToDecode, pluginInfoModifiers))
102+
return ResponseEntity.ok(
103+
decodeTrack(audioPlayerManager, trackToDecode).toTrack(
104+
trackToDecode,
105+
pluginInfoModifiers
106+
)
107+
)
66108
}
67109

68110
@PostMapping("/v4/decodetracks")

LavalinkServer/src/main/java/lavalink/server/player/PlayerRestHandler.kt

Lines changed: 17 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package lavalink.server.player
22

3-
import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler
43
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException
5-
import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist
64
import com.sedmelluq.discord.lavaplayer.track.AudioTrack
75
import com.sedmelluq.discord.lavaplayer.track.TrackMarker
86
import dev.arbjerg.lavalink.api.AudioFilterExtension
@@ -18,7 +16,6 @@ import org.springframework.http.HttpStatus
1816
import org.springframework.http.ResponseEntity
1917
import org.springframework.web.bind.annotation.*
2018
import org.springframework.web.server.ResponseStatusException
21-
import java.util.concurrent.CompletableFuture
2219

2320
@RestController
2421
class PlayerRestHandler(
@@ -60,7 +57,10 @@ class PlayerRestHandler(
6057
val context = socketContext(socketServer, sessionId)
6158

6259
if (playerUpdate.track.isPresent() && (playerUpdate.encodedTrack is Omissible.Present || playerUpdate.identifier is Omissible.Present)) {
63-
throw ResponseStatusException(HttpStatus.BAD_REQUEST, "Cannot specify both track and encodedTrack/identifier")
60+
throw ResponseStatusException(
61+
HttpStatus.BAD_REQUEST,
62+
"Cannot specify both track and encodedTrack/identifier"
63+
)
6464
}
6565

6666
val track = if (playerUpdate.track.isPresent()) {
@@ -180,44 +180,19 @@ class PlayerRestHandler(
180180
decodeTrack(context.audioPlayerManager, it)
181181
}
182182
} else {
183-
val trackFuture = CompletableFuture<AudioTrack>()
184-
context.audioPlayerManager.loadItemSync(
185-
(identifier as Omissible.Present).value,
186-
object : AudioLoadResultHandler {
187-
override fun trackLoaded(track: AudioTrack) {
188-
trackFuture.complete(track)
189-
}
190-
191-
override fun playlistLoaded(playlist: AudioPlaylist) {
192-
trackFuture.completeExceptionally(
193-
ResponseStatusException(
194-
HttpStatus.BAD_REQUEST,
195-
"Cannot play a playlist or search result"
196-
)
197-
)
198-
}
199-
200-
override fun noMatches() {
201-
trackFuture.completeExceptionally(
202-
ResponseStatusException(
203-
HttpStatus.BAD_REQUEST,
204-
"No matches found for identifier"
205-
)
206-
)
207-
}
208-
209-
override fun loadFailed(exception: FriendlyException) {
210-
trackFuture.completeExceptionally(
211-
ResponseStatusException(
212-
HttpStatus.INTERNAL_SERVER_ERROR,
213-
exception.message,
214-
getRootCause(exception)
215-
)
216-
)
217-
}
218-
})
219-
220-
trackFuture.join()
183+
val item = try {
184+
loadAudioItem(context.audioPlayerManager, (identifier as Omissible.Present).value)
185+
// Safety: loadAudioItem ONLY throws FriendlyException
186+
} catch (ex: FriendlyException) {
187+
throw ResponseStatusException(HttpStatus.BAD_REQUEST, ex.message, getRootCause(ex))
188+
}
189+
190+
if (item !is AudioTrack) throw ResponseStatusException(
191+
HttpStatus.BAD_REQUEST,
192+
if (item == null) "No matches found for identifier" else "Cannot play a playlist or search result"
193+
)
194+
195+
item
221196
}
222197

223198
newTrack?.let {
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package lavalink.server.util
2+
3+
import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager
4+
import com.sedmelluq.discord.lavaplayer.tools.ExceptionTools
5+
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException
6+
import com.sedmelluq.discord.lavaplayer.track.AudioItem
7+
8+
/**
9+
* Loads an audio item from the specified [identifier].
10+
*
11+
* This method wraps any exceptions thrown by the [AudioPlayerManager.loadItem] method in a [FriendlyException].
12+
* This is meant to maintain the behavior from callback-style item loading.
13+
*/
14+
fun loadAudioItem(manager: AudioPlayerManager, identifier: String): AudioItem? = try {
15+
manager.loadItemSync(identifier)
16+
} catch (ex: Throwable) {
17+
// re-throw any errors that are not exceptions
18+
ExceptionTools.rethrowErrors(ex)
19+
20+
throw FriendlyException(
21+
"Something went wrong while looking up the track.",
22+
FriendlyException.Severity.FAULT,
23+
ex
24+
)
25+
}

0 commit comments

Comments
 (0)