Last active
November 22, 2024 22:57
-
-
Save carlHandy/868cf539cb730c9ce3f435444f77b435 to your computer and use it in GitHub Desktop.
RTSP to HLS conversion
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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