Commit Graph

457 Commits

Author SHA1 Message Date
IgorA100
3d02585634 Fix: If an RTSP2Web type RTC error occurs, restart the stream instead of killing it (MonitorStream.js) 2026-03-01 00:31:08 +03:00
Isaac Connor
07345d095a Merge pull request #4638 from IgorA100/patch-129096
Optimizing "VolumeSlider" (MonitorStream.js)
2026-02-28 10:39:03 -05:00
Isaac Connor
812251f40f fix: improve JS error logging for undefined messages and cross-origin errors
window.onerror now captures column number and error stack trace when
available. Undefined or browser-sanitized "Script error." messages get a
descriptive placeholder instead of logging "undefined". Caller name
introspection is guarded against strict mode and empty names.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 22:16:23 -05:00
Isaac Connor
99986eeed2 Merge branch 'master' of github.com:ZoneMinder/zoneminder 2026-02-26 19:16:54 -05:00
Isaac Connor
bf82278b6e feat: integrate EventStream into montagereview with zms recovery and fixes
- 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>
2026-02-26 19:14:06 -05:00
IgorA100
f23098fa6a Fix: Check the "players" variable (MonitorStream.js).
After adding the "players" variable, the "players is not defined" issue appears on various pages.

There's currently an error on the Zones page.
Yes, ideally, the variable should be added in *.js.php files on various pages.
The absence of the variable has no significant impact, other than incomplete display of information.
The current error disrupts all JavaScript.
This PR prevents the disruption of all JavaScript code on the page.
2026-02-26 22:49:20 +03:00
Isaac Connor
a12d9749eb fix: use DOM img element and rAF loop for MJPEG stream reception
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>
2026-02-26 14:47:39 -05:00
Isaac Connor
516ff419a5 feat: add EventStream.js for persistent MJPEG event playback
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>
2026-02-26 14:09:59 -05:00
IgorA100
6c9e5e644b Added getTracksFromStream function for Go2RTC (video-stream.js) 2026-02-23 18:16:56 -05:00
IgorA100
72f0bee2d7 Moved the getTracksFromStream functions to sfin.js, as this will allow you to retrieve tracks from recorded events. (MonitorStream.js)
Also: If any error occurs during execution of "appendMseBuffer" (not just 'QuotaExceededError'), restart the thread
2026-02-23 18:16:56 -05:00
Isaac Connor
ef6cde54b9 fix: guard against null monitor div in video-stream.js divMode and divError setters
this.closest() returns null when the <video-stream> element isn't inside
a monitor div, causing TypeError on the subsequent querySelector call.
Add null checks in both divMode and divError setters.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 18:16:55 -05:00
Isaac Connor
615055e496 fix: default analysis overlay to off in zms streams
MonitorStream.js initialized analyse_frames = true, causing zone
overlays to always appear on stream start regardless of view settings.
Change default to false so watch view starts clean. The zone editor
view already explicitly enables analysis after monitor creation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 18:16:55 -05:00
IgorA100
9cd7de74bf Code optimization (MonitorStream.js) 2026-02-21 12:12:03 +03:00
IgorA100
25ed572167 Changed the destroy method for VolumeSlider (MonitorStream.js) 2026-02-21 00:29:55 +03:00
IgorA100
b35942b2b9 Fix: Display volumeSlider when switching monitors on the Watch page (MonitorStream.js) 2026-02-20 11:32:59 +03:00
IgorA100
6b109280e3 #volumeControls always includes the monitor ID (MonitorStream.js) 2026-02-20 00:40:36 +03:00
IgorA100
31bb7ab918 Optimizing "VolumeSlider" (MonitorStream.js)
Avoid recreating a VolumeSlider (instead of destroying the existing one) if one already exists.
This will at least save resources and avoid assigning a repeat listener to "volumechange."
2026-02-19 14:50:48 +03:00
Isaac Connor
ff0e84886a Merge pull request #4631 from IgorA100/patch-672404
Feat: Moved the getTracksFromStream functions from MonitorStream.js to sfin.js, as this will allow you to retrieve tracks from recorded events.
2026-02-18 10:15:44 -05:00
Isaac Connor
5434518046 fix: guard against null monitor div in video-stream.js divMode and divError setters
this.closest() returns null when the <video-stream> element isn't inside
a monitor div, causing TypeError on the subsequent querySelector call.
Add null checks in both divMode and divError setters.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 10:52:40 -05:00
Isaac Connor
091ce8bb00 fix: default analysis overlay to off in zms streams
MonitorStream.js initialized analyse_frames = true, causing zone
overlays to always appear on stream start regardless of view settings.
Change default to false so watch view starts clean. The zone editor
view already explicitly enables analysis after monitor creation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 15:30:36 -05:00
IgorA100
90891e3456 Fix: Clear "srcObject" for "Stream" and adjust Janus connection timeout (MonitorStream.js) 2026-02-15 15:38:07 -05:00
IgorA100
8dff591f37 Added getTracksFromStream function for Go2RTC (video-stream.js) 2026-02-15 22:19:00 +03:00
IgorA100
4ce20f9c4c Moved the getTracksFromStream functions to sfin.js, as this will allow you to retrieve tracks from recorded events. (MonitorStream.js)
Also: If any error occurs during execution of "appendMseBuffer" (not just 'QuotaExceededError'), restart the thread
2026-02-15 21:53:16 +03:00
Isaac Connor
632adaec62 Merge pull request #4623 from IgorA100/patch-164992
Fix: Clear "srcObject" for "Stream" and adjust Janus connection timeout (MonitorStream.js)
2026-02-13 13:25:44 -05:00
Isaac Connor
7b71ad2149 fix: pass analysis=true in zone view stream URL on initial load
The zone view enables analysis frames by default but the initial image
src and the rebuilt streaming URL were missing the analysis query param.
Add analysis=true to the getStreamHTML call in zone.php and preserve it
in MonitorStream.start() when switching from single to jpeg mode.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 18:12:06 -05:00
IgorA100
42280d2f75 Fix: Clear "srcObject" for "Stream" and adjust Janus connection timeout (MonitorStream.js) 2026-02-12 23:21:23 +03:00
IgorA100
d15febf205 Moved the "replaceDOMElement" function to "skin.js" (MonitorStream.js) 2026-02-10 22:15:48 +03:00
Isaac Connor
368affc08e Merge pull request #4591 from IgorA100/patch-955784
Fix: More correct logic for #volumeSlider processing & Improved functionality for RTSP2web, Janus, and ZMS
2026-02-10 12:55:09 -05:00
Isaac Connor
c9196e8fd5 Merge branch 'master' of github.com:ZoneMinder/zoneminder 2026-02-10 09:38:03 -05:00
Isaac Connor
9a2e9a8600 fix: fall back to CameraDirectPrimary when RTSPServer is disabled
When StreamChannel is set to Restream, the JS maps it to the
_ZoneMinderPrimary go2rtc stream. However, that stream is only
registered when RTSPServer is enabled on the monitor. Fall back
to _CameraDirectPrimary when RTSPServer is not enabled.

Pass RTSPServer property through monitorData in all views so the
JS can check it at stream selection time.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 09:32:24 -05:00
Nic Boet
5393c626c5 fix: preserve maxfps when MonitorStream.start() rebuilds stream URL
start() reconstructs the zms URL from url_to_zms, which only contains
the monitor id. Parameters like auth, connkey, scale, and mode are
carried over, but maxfps was dropped. This causes streams to start at
the camera's native capture rate even when PHP rendered the initial
<img src> with a maxfps value (e.g. from the montage Rate cookie).

Carry over maxfps from the existing src the same way the other
parameters are preserved.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 18:42:44 -06:00
Isaac Connor
079b873380 fix: correct auth property name in getStatusCmdResponse
The PHP status.php returns 'auth' but getStatusCmdResponse was checking
for 'auth_hash'. This mismatch prevented auth hash updates from status
responses from ever being applied, causing invalid hash errors after
the auth expired.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 16:44:52 -05:00
Isaac Connor
d64636cf7d fix: prevent stream commands from being sent after quit
Added started flag checks in streamCommand() and streamCmdQuery() to
prevent commands from being sent after the stream has been killed.
This fixes an issue where scale commands were being sent after quit
commands during page reload.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 14:59:16 -05:00
IgorA100
ef74b63587 Code optimization (MonitorStream.js) 2026-02-05 00:44:46 +03:00
IgorA100
27c225e4ef Missing Semicolon (MonitorStream.js) 2026-02-05 00:32:31 +03:00
IgorA100
62faabc5f0 When using ZMS, destroy VolumeSlider if it exists (MonitorStream.js) 2026-02-05 00:30:00 +03:00
IgorA100
534a9ef197 Fix: Eslint (MonitorStream.js) 2026-02-04 19:36:35 +03:00
IgorA100
85d5cbd63a Added the ability to retrieve tracks from a stream, disable Volume Controls if there is no audio track, and improved functionality for RTSP2Web, Janus, and ZMS. (MonitorStream.js) 2026-02-04 19:28:33 +03:00
Isaac Connor
f17d68cb3d Log when ondata is not defined 2026-02-03 12:11:32 -05:00
Isaac Connor
ac4585b6b4 fix: use monitor's StreamChannel setting for go2rtc stream selection
Two issues caused monitors to stream from wrong channel:

1. In setChannelStream(), the expression `StreamChannel && SecondPath`
   returned SecondPath (often empty) instead of StreamChannel. Now
   correctly uses the monitor's configured StreamChannel.

2. In MonitorStream.start(), default channel only checked for
   CameraDirectSecondary and defaulted everything else to Restream.
   Now respects the actual StreamChannel setting.

Also improved fallback when selected option is disabled to find first
enabled option rather than always defaulting to Restream.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 13:01:50 -05:00
Isaac Connor
eae89025ee refactor: rename RTSP2WebStream to StreamChannel
Rename applies to Go2RTC, Janus, and RTSP2Web streaming options.
Update enum values from Primary/Secondary to Restream/CameraDirectPrimary/CameraDirectSecondary.

- Add db migration zm_update-1.37.79.sql to rename column and migrate data
- Update C++ enum StreamChannelOption and member stream_channel
- Update PHP getStreamChannelOptions() method
- Update all JavaScript references
- Auto-select CameraDirectPrimary when Restream option becomes disabled

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 19:37:08 -05:00
Ben Dailey
c80542343a Remove Preview Rate Control. Disable BuiltIn Video controls. 2026-01-29 11:18:30 -05:00
IgorA100
c7a8e5a78c Fix Eslint (MonitorStream.js) 2026-01-21 21:14:00 +03:00
IgorA100
b6ad1b94dd Fix: More correct handling of "muted" and copying of all attributes when cloning a DOM node (MonitorStream.js) 2026-01-21 20:59:29 +03:00
Isaac Connor
eb2d90eed0 Set started=false so we don't send STOP after QUIT 2026-01-20 22:10:20 -05:00
IgorA100
1759381a8e Fix: Eslint (MonitorStream.js) 2026-01-13 18:18:25 +03:00
IgorA100
ffc7f96b58 Fix: Correct operation of controlMute if iconMute or volumeSlider are missing (MonitorStream.js)
Actual for Montage page
2026-01-13 17:34:39 +03:00
IgorA100
3496937825 I returned the old "this.controlMute" function (MonitorStream.js)
It's not entirely clear why it was necessary to change the "this.controlMute" function in the commit.f796fa913f

After this change, the "volumeSlider" and "iconMute" styling sometimes doesn't work correctly.

The old code was 99.9% debugged and worked without any issues.

It's also unclear why "this.muted" was added? After all, we already had "audioStream.muted." Now we're probably getting duplicates.
2026-01-12 15:30:27 +03:00
Isaac Connor
8864d5759d Merge pull request #4510 from SteveGilvarry/videojs_update
Videojs update
2026-01-10 10:21:50 -05:00
Isaac Connor
90da1be90e Funny thing img.src is NEVER == ''. It will return the current nav url. So all the code testing for '' is bogus. This fixes sending an additional STOP after QUIT, which leaves errors in logs. 2026-01-02 10:41:44 -05:00