feat: add jukebox player engine for server-side playback (#2109)

* feat: add jukebox player engine for server-side playback

---------

Co-authored-by: jeffvli <jeffvictorli@gmail.com>
This commit is contained in:
mannansainidev
2026-07-10 09:59:22 +05:30
committed by GitHub
parent dd136f91e6
commit 0c89fea1ea
15 changed files with 743 additions and 31 deletions
@@ -1395,6 +1395,22 @@ export const SubsonicController: InternalControllerEndpoint = {
if (subsonicFeatures[SubsonicExtensions.PLAYBACK_REPORT]) {
features.reportPlayback = [1];
}
try {
const jukeboxStatus = await ssApiClient(apiClientProps).jukeboxControl({
query: { action: 'status' },
});
if (jukeboxStatus.status === 200 && !(jukeboxStatus.body as any)?.error) {
features[ServerFeature.JUKEBOX] = [1];
} else {
console.log(
'Jukebox endpoint returned an error payload:',
(jukeboxStatus.body as any)?.error,
);
}
} catch (error) {
console.log('Jukebox is not supported by this server:', error);
}
return { features, id: apiClientProps.server?.id, version: ping.body.serverVersion };
},
@@ -2052,6 +2068,25 @@ export const SubsonicController: InternalControllerEndpoint = {
name: res.body.user.username,
};
},
jukeboxControl: async (args) => {
const { apiClientProps, query } = args;
const res = await ssApiClient(apiClientProps).jukeboxControl({
query: {
action: query.action,
gain: query.gain,
id: query.id,
index: query.index,
offset: query.offset,
},
});
if (res.status !== 200) {
throw new Error('Failed to control jukebox');
}
return res.body;
},
removeFromPlaylist: async ({ apiClientProps, query }) => {
const res = await ssApiClient(apiClientProps).updatePlaylist({
query: {