Add a custom queue

This commit is contained in:
Zoe Roux 2022-10-25 16:46:13 +09:00
parent 2c724eae5c
commit c9d977916b
No known key found for this signature in database
GPG Key ID: B2AB52A2636E5C46
4 changed files with 98 additions and 11 deletions

View File

@ -81,6 +81,14 @@ export type Item = {
direct: string;
transmux: string;
};
nextEpisode: {
id: number,
slug: string,
},
previousEpisode: {
id: number,
slug: string,
}
};
export const getItem = async (slug: string, apiUrl: string) => {
@ -125,3 +133,13 @@ export const itemToMovie = (item: Item) => {
return metadata;
}
export const itemToMedia = (item: Item, apiUrl: string) => {
const media = new cast.framework.messages.MediaInformation();
media.contentUrl = item.link.direct;
media.metadata = item.isMovie
? itemToMovie(item)
: itemToTvMetadata(item);
media.customData = item;
media.customData.serverUrl = apiUrl;
return media;
}

View File

@ -18,7 +18,8 @@
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
*/
import { getItem, itemToMovie, itemToTvMetadata } from "./api";
import { getItem, itemToMedia } from "./api";
import { Queue } from "./queue";
const Command = cast.framework.messages.Command;
const context = cast.framework.CastReceiverContext.getInstance();
@ -35,27 +36,22 @@ playerManager.setSupportedMediaCommands(
Command.STREAM_TRANSFER,
);
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD,
async (loadRequestData) => {
if (loadRequestData.media.contentUrl && loadRequestData.media.metadata) return loadRequestData;
const apiUrl = loadRequestData.media.customData.serverUrl;
const item = await getItem(
loadRequestData.media.contentId,
loadRequestData.media.customData.serverUrl,
apiUrl,
);
if (!item) {
return new cast.framework.messages.ErrorData(cast.framework.messages.ErrorType.LOAD_FAILED);
}
loadRequestData.media.contentUrl = item.link.direct;
loadRequestData.media.metadata = item.isMovie
? itemToMovie(item)
: itemToTvMetadata(item);
loadRequestData.media.customData = item;
loadRequestData.media = itemToMedia(item, apiUrl);
return loadRequestData;
},
);
context.start();
context.start({ queue: new Queue() });

73
chromecast/src/queue.ts Normal file
View File

@ -0,0 +1,73 @@
/*
* Kyoo - A portable and vast media library solution.
* Copyright (c) Kyoo.
*
* See AUTHORS.md and LICENSE file in the project root for full license information.
*
* Kyoo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* Kyoo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
*/
import { QueueManager } from "chromecast-caf-receiver/cast.framework";
import { LoadRequestData, QueueData, QueueItem } from "chromecast-caf-receiver/cast.framework.messages";
import { getItem, Item, itemToMedia } from "./api";
export class Queue extends cast.framework.QueueBase {
queue: QueueManager | null;
constructor() {
super();
this.queue = cast.framework.CastReceiverContext.getInstance().getPlayerManager().getQueueManager();
}
initialize(requestData: LoadRequestData): QueueData {
if (requestData.queueData) return requestData.queueData;
const queueData = new cast.framework.messages.QueueData();
queueData.name = "queue";
queueData.items = [requestData.media];
return queueData;
}
async nextItems(itemId?: number): Promise<QueueItem[]> {
const current = this.queue?.getItems().find(x => x.itemId == itemId);
if (!current || !current.media?.contentId || !current.media.customData?.serverUrl) return [];
const metadata = current?.media?.customData as Item;
const apiUrl = current.media?.customData.serverUrl;
if (!metadata.nextEpisode) return [];
const item = await getItem(metadata.nextEpisode.slug, apiUrl);
if (!item) return [];
const data = new cast.framework.messages.QueueItem();
data.media = itemToMedia(item, apiUrl);
return [data];
}
async prevItems(itemId?: number): Promise<QueueItem[]> {
const current = this.queue?.getItems().find(x => x.itemId == itemId);
if (!current || !current.media?.contentId || !current.media.customData?.serverUrl) return [];
const metadata = current?.media?.customData as Item;
const apiUrl = current.media?.customData.serverUrl;
if (!metadata.previousEpisode) return [];
const item = await getItem(metadata.previousEpisode.slug, apiUrl);
if (!item) return [];
const data = new cast.framework.messages.QueueItem();
data.media = itemToMedia(item, apiUrl);
return [data];
}
}

View File

@ -91,7 +91,7 @@ export const useCastController = () => {
[cast.framework.RemotePlayerEventType.DURATION_CHANGED, (event) => setDuration(event.value)],
[
cast.framework.RemotePlayerEventType.MEDIA_INFO_CHANGED,
() => setMedia(player.mediaInfo?.customData),
() => setMedia(player.mediaInfo?.customData ?? null),
],
];