Update prepare caller

This commit is contained in:
Zoe Roux 2026-04-14 23:06:49 +02:00
parent 841212de52
commit ee9125b427
No known key found for this signature in database
2 changed files with 75 additions and 22 deletions

View File

@ -1,13 +1,16 @@
import { eq } from "drizzle-orm";
import { getLogger } from "@logtape/logtape";
import { eq, and } from "drizzle-orm";
import { Elysia, t } from "elysia";
import slugify from "slugify";
import { auth } from "~/auth";
import { db } from "~/db";
import { entryVideoJoin, videos } from "~/db/schema";
import { entries, entryVideoJoin, videos } from "~/db/schema";
import { KError } from "~/models/error";
import { isUuid } from "~/models/utils";
import { Video } from "~/models/video";
const logger = getLogger();
export const videosMetadata = new Elysia({
prefix: "/videos",
tags: ["videos"],
@ -188,4 +191,71 @@ export const videosMetadata = new Elysia({
},
},
},
)
.get(
":id/prepare",
async ({ params: { id }, headers: { authorization } }) => {
await prepareVideo(id, authorization!);
},
{
detail: { description: "Prepare a video for playback" },
params: t.Object({
id: t.String({
description: "The id or slug of the video to watch.",
example: "made-in-abyss-s1e13",
}),
}),
response: {
302: t.Void({
description:
"Prepare said video for playback (compute everything possible and cache it)",
}),
404: {
...KError,
description: "No video found with the given id or slug.",
},
},
},
);
export const prepareVideo = async (slug: string, auth: string) => {
logger.info("Preparing next video {slug}", { slug });
const [vid] = await db
.select({ path: videos.path, show: entries.showPk, order: entries.order })
.from(videos)
.innerJoin(entryVideoJoin, eq(videos.pk, entryVideoJoin.videoPk))
.leftJoin(entries, eq(entries.pk, entryVideoJoin.entryPk))
.where(eq(entryVideoJoin.slug, slug))
.limit(1);
const related = vid.show
? await db
.select({ order: entries.order, path: videos.path })
.from(entries)
.innerJoin(entryVideoJoin, eq(entries.pk, entryVideoJoin.entryPk))
.innerJoin(videos, eq(videos.pk, entryVideoJoin.videoPk))
.where(and(eq(entries.showPk, vid.show), eq(entries.kind, "episode")))
.orderBy(entries.order)
: [];
const idx = related.findIndex((x) => x.order === vid.order);
const path = Buffer.from(vid.path, "utf8").toString("base64url");
await fetch(
new URL(
`/video/${path}/prepare`,
process.env.TRANSCODER_SERVER ?? "http://transcoder:7666",
),
{
headers: {
authorization: auth,
"content-type": "application/json",
},
method: "POST",
body: JSON.stringify({
nearEpisodes: [related[idx - 1], related[idx + 1]]
.filter((x) => x)
.map((x) => x.path),
}),
},
);
};

View File

@ -1,15 +1,13 @@
import { getLogger } from "@logtape/logtape";
import type { TObject, TString } from "@sinclair/typebox";
import { eq } from "drizzle-orm";
import Elysia, { type TSchema, t } from "elysia";
import { auth } from "./auth";
import { updateProgress } from "./controllers/profiles/history";
import { getOrCreateProfile } from "./controllers/profiles/profile";
import { prepareVideo } from "./controllers/video-metadata";
import { getVideos } from "./controllers/videos";
import { videos } from "./db/schema";
const logger = getLogger();
const actionMap = {
ping: handler({
message(ws) {
@ -61,23 +59,8 @@ const actionMap = {
languages: ["*"],
userId: ws.data.jwt.sub,
});
if (!vid) return;
logger.info("Preparing next video {videoId}", {
videoId: vid.id,
});
const path = Buffer.from(vid.path, "utf8").toString("base64url");
await fetch(
new URL(
`/video/${path}/prepare`,
process.env.TRANSCODER_SERVER ?? "http://transcoder:7666",
),
{
headers: {
authorization: ws.data.headers.authorization!,
},
},
);
const next = vid?.next?.video;
if (next) await prepareVideo(next, ws.data.headers.authorization!);
}
},
}),