Serves a file to a video element with HTTP range requests, including a
file that is still being written. Any file: a fragmented MP4 a playlist
from Fmp4.playlist/3 points at, a plain MP4, a Matroska release.
A browser plays a plain MP4 by asking for byte ranges (Safari starts with
bytes=0-1 to learn the size), so a file has to answer 206 with
Content-Range. A file still growing (growing?: true) has no total yet:
its ranges are answered with * for the total, a piece at a time so the
browser asks again as it fills, and a request past what exists so far
waits for the writer to catch up before giving up with 416.
def media(conn, %{"name" => name}) do
Fmp4.RangeFile.send(conn, path(name), "video/mp4", growing?: not finished?(name))
end
Summary
Functions
@spec send(Plug.Conn.t(), Path.t(), String.t(), keyword()) :: Plug.Conn.t()
Sends the file, answering the request's Range header. Options:
growing?— the file is still being written (default false). Setscache-control: no-store, answers at most:chunkbytes per range, and waits up to:waitms for bytes not written yet.chunk— bytes per answered range while growing (default 1 MiB).wait— ms to wait for a growing file to reach the range asked for (default 20 000), checked every:pollms (default 200).cache_control— the header for a finished file (default"private, max-age=3600").