This repository has been archived on 2024-06-24. You can view files and clone it, but cannot push or open issues or pull requests.
augie/webapp/lib/augie_web/controllers/camera_controller.ex

57 lines
1.5 KiB
Elixir

defmodule AugieWeb.CameraController do
use AugieWeb, :controller
@camera Application.get_env(:picam, :camera, Picam.Camera)
def static(conn, _params) do
Picam.set_size(640, 480)
conn
|> put_resp_header("Age", "0")
|> put_resp_header("Cache-Control", "no-cache, private")
|> put_resp_header("Pragma", "no-cache")
|> put_resp_header("Content-Type", "image/jpeg")
|> send_chunked(200)
|> send_image()
end
def stream(conn, _params) do
Picam.set_size(640, 480)
boundary = generate_boundary(16)
conn
|> put_resp_header("Age", "0")
|> put_resp_header("Cache-Control", "no-cache, private")
|> put_resp_header("Pragma", "no-cache")
|> put_resp_header("Content-Type", "multipart/x-mixed-replace; boundary=#{boundary}")
|> send_chunked(200)
|> send_stream(boundary)
end
defp send_image(conn) do
jpg = GenServer.call(@camera, :next_frame)
with {:ok, conn} <- chunk(conn, jpg),
do: conn
end
defp send_stream(conn, boundary) do
jpg = GenServer.call(@camera, :next_frame)
size = byte_size(jpg)
header = "------#{boundary}\r\nContent-Type: image/jpeg\r\nContent-length: #{size}\r\n\r\n"
footer = "\r\n"
with {:ok, conn} <- chunk(conn, header),
{:ok, conn} <- chunk(conn, jpg),
{:ok, conn} <- chunk(conn, footer),
do: conn
end
defp generate_boundary(length) do
length
|> :crypto.strong_rand_bytes()
|> Base.encode64()
|> binary_part(0, length)
end
end