mirror of
https://github.com/th-ch/youtube-music.git
synced 2026-01-11 10:31:47 +00:00
"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:
@ -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({
|
queueInfo: createRoute({
|
||||||
method: 'get',
|
method: 'get',
|
||||||
path: `/api/${API_VERSION}/queue`,
|
path: `/api/${API_VERSION}/queue`,
|
||||||
@ -748,6 +768,63 @@ export const register = (
|
|||||||
app.openapi(routes.oldQueueInfo, queueInfo);
|
app.openapi(routes.oldQueueInfo, queueInfo);
|
||||||
app.openapi(routes.queueInfo, 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) => {
|
app.openapi(routes.addSongToQueue, (ctx) => {
|
||||||
const { videoId, insertPosition } = ctx.req.valid('json');
|
const { videoId, insertPosition } = ctx.req.valid('json');
|
||||||
controller.addSongToQueue(videoId, insertPosition);
|
controller.addSongToQueue(videoId, insertPosition);
|
||||||
|
|||||||
Reference in New Issue
Block a user