init
This commit is contained in:
97
src/routes/api/stream/+server.ts
Normal file
97
src/routes/api/stream/+server.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user