Skip to content

Instantly share code, notes, and snippets.

@carlHandy
Last active November 22, 2024 22:57
Show Gist options
  • Save carlHandy/868cf539cb730c9ce3f435444f77b435 to your computer and use it in GitHub Desktop.
Save carlHandy/868cf539cb730c9ce3f435444f77b435 to your computer and use it in GitHub Desktop.
RTSP to HLS conversion
import { serve } from "https://deno.land/[email protected]/http/server.ts";
import { ensureDir } from "https://deno.land/[email protected]/fs/mod.ts";
const server = serve({ port: 8000 });
console.log("HTTP webserver running. Access it at: http://localhost:8000/");
for await (const request of server) {
if (request.method === "POST" && request.url === "/stream") {
const body = await request.json();
const rtspUrl = body.rtspUrl;
if (!rtspUrl) {
request.respond({ status: 400, body: "RTSP URL is required" });
continue;
}
const streamKey = crypto.randomUUID();
const outputDir = `./streams/${streamKey}`;
await ensureDir(outputDir);
const ffmpeg = Deno.run({
cmd: [
"ffmpeg",
"-i", rtspUrl,
"-c:v", "libx264",
"-f", "hls",
"-hls_time", "10",
"-hls_list_size", "5",
"-hls_flags", "delete_segments",
`${outputDir}/index.m3u8`,
],
stdout: "piped",
stderr: "piped",
});
request.respond({
status: 200,
body: JSON.stringify({ streamKey }),
});
ffmpeg.status().then(async (status) => {
const { code } = status;
const rawError = await ffmpeg.stderrOutput();
const errorString = new TextDecoder().decode(rawError);
if (code !== 0) {
console.error(`FFmpeg process exited with code ${code}: ${errorString}`);
}
ffmpeg.close();
});
} else if (request.method === "GET" && request.url.startsWith("/streams/")) {
const filePath = `.${request.url}`;
try {
const file = await Deno.readFile(filePath);
const contentType = filePath.endsWith(".m3u8") ? "application/vnd.apple.mpegurl" : "video/MP2T";
request.respond({ status: 200, body: file, headers: new Headers({ "Content-Type": contentType }) });
} catch (error) {
request.respond({ status: 404, body: "Stream not found" });
}
} else {
request.respond({ status: 404, body: "Not Found" });
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment