Skip to content

Commit 27e3796

Browse files
"feat(api-server): add /api/v1/queue/next endpoint (#4117)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 5843e85 commit 27e3796

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

src/plugins/api-server/backend/routes/control.ts

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,26 @@ const routes = {
411411
},
412412
},
413413
}),
414+
nextSongInfo: createRoute({
415+
method: 'get',
416+
path: `/api/${API_VERSION}/queue/next`,
417+
summary: 'get next song info',
418+
description:
419+
'Get information about the next song in the queue (relative index +1)',
420+
responses: {
421+
200: {
422+
description: 'Success',
423+
content: {
424+
'application/json': {
425+
schema: SongInfoSchema,
426+
},
427+
},
428+
},
429+
204: {
430+
description: 'No next song in queue',
431+
},
432+
},
433+
}),
414434
queueInfo: createRoute({
415435
method: 'get',
416436
path: `/api/${API_VERSION}/queue`,
@@ -748,6 +768,63 @@ export const register = (
748768
app.openapi(routes.oldQueueInfo, queueInfo);
749769
app.openapi(routes.queueInfo, queueInfo);
750770

771+
app.openapi(routes.nextSongInfo, async (ctx) => {
772+
const queueResponsePromise = new Promise<QueueResponse>((resolve) => {
773+
ipcMain.once('peard:get-queue-response', (_, queue: QueueResponse) => {
774+
return resolve(queue);
775+
});
776+
777+
controller.requestQueueInformation();
778+
});
779+
780+
const queue = await queueResponsePromise;
781+
782+
if (!queue?.items || queue.items.length === 0) {
783+
ctx.status(204);
784+
return ctx.body(null);
785+
}
786+
787+
// Find the currently selected song
788+
const currentIndex = queue.items.findIndex((item) => {
789+
const renderer =
790+
item.playlistPanelVideoRenderer ||
791+
item.playlistPanelVideoWrapperRenderer?.primaryRenderer
792+
?.playlistPanelVideoRenderer;
793+
return renderer?.selected === true;
794+
});
795+
796+
// Get the next song (currentIndex + 1)
797+
const nextIndex = currentIndex + 1;
798+
if (nextIndex >= queue.items.length) {
799+
// No next song available
800+
ctx.status(204);
801+
return ctx.body(null);
802+
}
803+
804+
const nextItem = queue.items[nextIndex];
805+
const nextRenderer =
806+
nextItem.playlistPanelVideoRenderer ||
807+
nextItem.playlistPanelVideoWrapperRenderer?.primaryRenderer
808+
?.playlistPanelVideoRenderer;
809+
810+
if (!nextRenderer) {
811+
ctx.status(204);
812+
return ctx.body(null);
813+
}
814+
815+
// Extract relevant information similar to SongInfo format
816+
const nextSongInfo = {
817+
title: nextRenderer.title?.runs?.[0]?.text,
818+
videoId: nextRenderer.videoId,
819+
thumbnail: nextRenderer.thumbnail,
820+
lengthText: nextRenderer.lengthText,
821+
shortBylineText: nextRenderer.shortBylineText,
822+
};
823+
824+
ctx.status(200);
825+
return ctx.json(nextSongInfo);
826+
});
827+
751828
app.openapi(routes.addSongToQueue, (ctx) => {
752829
const { videoId, insertPosition } = ctx.req.valid('json');
753830
controller.addSongToQueue(videoId, insertPosition);

0 commit comments

Comments
 (0)