Replaced the bot's audio handling system by removing Lavaplayer dependencies and migrating to a Lavalink v4 node. Updated `MusicManager`, `TrackScheduler`, and related classes to utilize the `LavalinkClient`. Refactored playlist and track loading logic, task integrations, and event dispatch to integrate with the remote node. Deprecated the custom Udio source, preserving references for a future plugin port. Documented configuration and deployment details for the new audio architecture.
Udio source — follow-up reference
These files are not part of the build. They are the original client-side Lavaplayer implementation of the udio.com source, kept verbatim as the reference for a future port.
| File | Was |
|---|---|
UdioAudioSourceManager.java |
me.bobert.netneutrality.music.source.UdioAudioSourceManager |
UdioAudioTrack.java |
me.bobert.netneutrality.music.source.UdioAudioTrack |
UdioAudioSourceManagerTest.java |
its unit test |
Why they were moved
The bot no longer decodes audio itself: after the migration to Lavalink, source
resolution happens on the node. A Lavaplayer AudioSourceManager living in the bot process can
never be used by Lavalink, and these classes cannot even compile now that the dev.arbjerg:lavaplayer
dependency has been dropped from pom.xml.
Status
Udio playback is disabled. SourceFinder still classifies Udio URLs, but
SourceFinder.getIdentifier returns no identifier for them and MusicManager.play replies that
Udio is temporarily unsupported.
Follow-up
Port UdioAudioSourceManager / UdioAudioTrack into a standalone Lavalink server plugin
(its own build and published artifact), then enable it by adding the dependency to
lavalink/application.yml:
lavalink:
plugins:
- dependency: "<group>:udio-plugin:<version>"
Once the node resolves https://www.udio.com/songs/... identifiers, the only bot-side change is to
restore Udio in the SourceFinder.getIdentifier switch and drop the "temporarily unsupported"
reply in MusicManager.play.
The scraping logic itself still applies: the manager extracts metadata and a direct playback URL
from the Next.js payload (self.__next_f.push(...)) of the track page, and the URL must be
re-fetched right before playback because it expires.