Files
grown/src/routes/api/stream/+server.ts
2026-03-11 00:06:51 +01:00

98 lines
2.4 KiB
TypeScript

import { json } from "@sveltejs/kit";
import {
startStream,
stopStream,
getStreamStatus,
getAllStreams,
getStreamProcess,
addStreamClient,
removeStreamClient,
} from "$lib/server/streaming.js";
export async function POST({ request }) {
const { action, streamId, rtspUrl } = await request.json();
if (action === "start") {
if (!streamId || !rtspUrl) {
return json({ error: "Missing streamId or rtspUrl" }, { status: 400 });
}
const result = startStream(streamId, rtspUrl);
if (result.error) {
return json({ error: result.error }, { status: 500 });
}
return json({ success: true, streamId });
} else if (action === "stop") {
if (!streamId) {
return json({ error: "Missing streamId" }, { status: 400 });
}
stopStream(streamId);
return json({ success: true });
} else if (action === "status") {
if (!streamId) {
return json({ error: "Missing streamId" }, { status: 400 });
}
const status = getStreamStatus(streamId);
return json(status);
} else if (action === "list") {
const streams = getAllStreams();
return json({ streams });
} else {
return json({ error: "Unknown action" }, { status: 400 });
}
}
export async function GET({ url }) {
const streamId = url.searchParams.get("id");
if (!streamId) {
return new Response("Missing stream ID", { status: 400 });
}
const stream = getStreamProcess(streamId);
if (!stream || !stream.process || !stream.process.stdout) {
return new Response("Stream not found", { status: 404 });
}
// Track client
const clientId = Math.random().toString(36).substring(7);
addStreamClient(streamId, clientId);
// Create readable stream from FFmpeg stdout
const readable = stream.process.stdout;
// Return as multipart/x-mixed-replace for MJPEG
const response = new Response(readable as any, {
headers: {
"Content-Type": "multipart/x-mixed-replace; boundary=FFMPEG",
"Cache-Control": "no-cache, no-store, must-revalidate",
Pragma: "no-cache",
Expires: "0",
Connection: "keep-alive",
},
});
// Track when connection closes
if (response.body) {
const reader = response.body.getReader();
(async () => {
try {
while (true) {
await reader.read();
}
} catch (e) {
// Connection closed
console.error("Error monitoring stream connection:", e);
} finally {
removeStreamClient(streamId, clientId);
reader.releaseLock();
}
})();
}
return response;
}