PhxDemo.Camera (phx_demo v0.1.1)

Copy Markdown View Source

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

check_fixtures!(paths)

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.

classify(path)

How a fixture will be served: :image, :video (as is) or :convert (via ffmpeg).

convert!(path, viewport)

Converts a video to VP8 WebM at viewport size (aspect ratio preserved, padded) and 30 fps, cached. Returns the converted path.

js()