- Integrate EventStream.js into montagereview.js for persistent MJPEG
streaming in replay mode (speeds >= 1x), falling back to per-frame
mode=single for speeds < 1x where zms lacks slow-motion support
- Add EventStream recovery logic: detect zms death via AJAX failures,
img.onerror, and error responses; auto-restart with new connkey and
exponential backoff (max 5 retries)
- Fix zms crash on bulk/interpolated frames: add stat() check in
sendFrame() for SaveJPEGs & 1 path, fall through to ffmpeg_input
when JPEG file doesn't exist on disk; send "No frame available"
text frame instead of terminating when no source available
- Center monitor canvases: text-align in CSS for scale mode,
horizontal offset calculation in maxfit2() for fit mode
- Reduce console noise: comment out high-frequency debug logs,
convert error-path logs to console.warn/error
- Fix ESLint sourceType to "script" for traditional non-module JS
files, resolving false-positive no-unused-vars on global functions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
A detached Image() object does not reliably decode multipart MJPEG
streams — browsers only update a DOM-attached <img> with each frame
from a multipart/x-mixed-replace response. Switch to creating a
hidden DOM <img> element and use requestAnimationFrame to copy
decoded frames to the canvas.
Also properly clean up the img element from the DOM in stop() and
switchEvent(), and guard drawFrame() against drawing before the
first frame has been decoded.
Tested: start, pause, play, seek, setRate, stop all verified
working against a live zms event stream.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduce EventStream constructor that manages a persistent zms MJPEG
connection for event playback, replacing the per-frame mode=single HTTP
request pattern. Frames arrive via a hidden Image element and are drawn
to a caller-supplied canvas on each onload.
Supports seek, pause, play, rate control, scale changes, and event
switching via the existing zms command-socket protocol. Follows the
same constructor-function pattern as MonitorStream.js.
Include the script in montagereview.php for upcoming integration.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>