import { HandlerContext } from "$fresh/server.ts";
import { Err, isErr, Ok } from "eav/mod.ts";
const video = await Deno.readFile("./static/assets/hero.mp4");
const chunkSize = 1024 * 1024 * 10;
export async function handler(
req: Request,
ctx: HandlerContext,
): Promise<Response> {
if (req.headers.has("range")) {
const range = Ok(parseRange(req.headers.get("range")!)) ??
{ start: 0, end: NaN };
if (range.start === 0 && isNaN(range.end)) {
return new Response(video.slice(0, chunkSize), {
status: 206,
headers: {
"Content-Type": "video/mp4",
"Content-Length": chunkSize.toString(),
"Content-Range": `bytes 0-100/${video.length}`,
"Accept-Ranges": "bytes",
},
});
}
const end = isNaN(range.end) ? range.start + chunkSize : range.end;
return new Response(video.slice(range.start, end), {
status: 206,
headers: {
"Content-Type": "video/mp4",
"Content-Length": chunkSize.toString(),
"Content-Range": `bytes ${range.start}-${end}/${video.length}`,
"Accept-Ranges": "bytes",
},
});
}
return new Response(null, {
status: 404,
});
}
function parseRange(range: string) {
if (!range.includes("bytes=")) {
return new Err("invalid range");
}
const [_, rangeStr] = range.split("=");
const [start, end] = rangeStr.split("-");
return { start: parseInt(start), end: parseInt(end) };
}