Simulated camera for demos (the machinery behind PhxDemo.Steps.use_camera/3,
use_camera_image/2 and stop_camera/1).
A JS stand-in (priv/camera.js) replaces navigator.mediaDevices.getUserMedia
for video requests. It draws a hidden <video> or <img> onto a canvas and
hands out canvas.captureStream(). The same stand-in serves the simulated
microphone (see PhxDemo.Audio), so a {video, audio} request gets both fake
tracks. Because every stream comes from the same
canvas, switching fixtures between steps changes what an app that is already
streaming sees.
The fixture bytes reach the page through a Playwright route on the app's own
origin (/__phx_demo_camera/...), so there is no CORS or canvas tainting, and
the choice of fixture survives full page loads. The route is answered by
Playwright, so requests never reach your app. A strict CSP is unaffected as
long as it allows 'self' for connect-src and media-src/img-src blob:.
Formats
Images (png, jpg, gif, webp, bmp, svg) and .webm/.ogv videos are served
as they are. Playwright's Chromium has no H.264, so any other video (mp4,
mov, mkv, ...) is converted with ffmpeg to VP8 WebM at the viewport size and
30 fps, without audio. Conversions are cached under the system temp dir,
keyed by the file's path, size, mtime and the viewport.
Limits
Screen sharing (getDisplayMedia) is not simulated.
Summary
Functions
Raises with a clear message if a fixture is missing, or needs ffmpeg and it
isn't installed. Used by PhxDemo.Env (pre-flight) and by the steps.
How a fixture will be served: :image, :video (as is) or :convert (via ffmpeg).
Converts a video to VP8 WebM at viewport size (aspect ratio preserved, padded)
and 30 fps, cached. Returns the converted path.
Functions
Raises with a clear message if a fixture is missing, or needs ffmpeg and it
isn't installed. Used by PhxDemo.Env (pre-flight) and by the steps.
How a fixture will be served: :image, :video (as is) or :convert (via ffmpeg).
Converts a video to VP8 WebM at viewport size (aspect ratio preserved, padded)
and 30 fps, cached. Returns the converted path.