"feat(api-server): add /api/v1/queue/next endpoint (#4117)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
Adrien Montariol
2025-12-19 08:17:30 +01:00
committed by GitHub
parent 5843e85c4d
commit 27e3796622

View File

@ -411,6 +411,26 @@ const routes = {
},
},
}),
nextSongInfo: createRoute({
method: 'get',
path: `/api/${API_VERSION}/queue/next`,
summary: 'get next song info',
description:
'Get information about the next song in the queue (relative index +1)',
responses: {
200: {
description: 'Success',
content: {
'application/json': {
schema: SongInfoSchema,
},
},
},
204: {
description: 'No next song in queue',
},
},
}),
queueInfo: createRoute({
method: 'get',
path: `/api/${API_VERSION}/queue`,
@ -748,6 +768,63 @@ export const register = (
app.openapi(routes.oldQueueInfo, queueInfo);
app.openapi(routes.queueInfo, queueInfo);
app.openapi(routes.nextSongInfo, async (ctx) => {
const queueResponsePromise = new Promise<QueueResponse>((resolve) => {
ipcMain.once('peard:get-queue-response', (_, queue: QueueResponse) => {
return resolve(queue);
});
controller.requestQueueInformation();
});
const queue = await queueResponsePromise;
if (!queue?.items || queue.items.length === 0) {
ctx.status(204);
return ctx.body(null);
}
// Find the currently selected song
const currentIndex = queue.items.findIndex((item) => {
const renderer =
item.playlistPanelVideoRenderer ||
item.playlistPanelVideoWrapperRenderer?.primaryRenderer
?.playlistPanelVideoRenderer;
return renderer?.selected === true;
});
// Get the next song (currentIndex + 1)
const nextIndex = currentIndex + 1;
if (nextIndex >= queue.items.length) {
// No next song available
ctx.status(204);
return ctx.body(null);
}
const nextItem = queue.items[nextIndex];
const nextRenderer =
nextItem.playlistPanelVideoRenderer ||
nextItem.playlistPanelVideoWrapperRenderer?.primaryRenderer
?.playlistPanelVideoRenderer;
if (!nextRenderer) {
ctx.status(204);
return ctx.body(null);
}
// Extract relevant information similar to SongInfo format
const nextSongInfo = {
title: nextRenderer.title?.runs?.[0]?.text,
videoId: nextRenderer.videoId,
thumbnail: nextRenderer.thumbnail,
lengthText: nextRenderer.lengthText,
shortBylineText: nextRenderer.shortBylineText,
};
ctx.status(200);
return ctx.json(nextSongInfo);
});
app.openapi(routes.addSongToQueue, (ctx) => {
const { videoId, insertPosition } = ctx.req.valid('json');
controller.addSongToQueue(videoId, insertPosition);