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>
The manageChannelStream() function expected Path and Restream fields
in monitorData to enable/disable StreamChannel options, but these
fields were not being populated. This caused CameraDirectPrimary and
Restream options to always be disabled on the watch view.
Also updated SecondPath to use validJsStr() for proper escaping.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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>
Rename Janus-specific restream fields to be more generic since they are
now used by Go2RTC and RTSP2Web as well:
- Janus_Use_RTSP_Restream → Restream
- Janus_RTSP_User → RTSP_User
Update visibility logic so the Restream checkbox appears when RTSPServer
is enabled AND any streaming service (Janus, Go2RTC, or RTSP2Web) is
selected, rather than only when Janus is enabled.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add ability to view motion analysis frames on the watch view, similar
to the existing functionality in the zone edit view. Includes a toggle
button that switches between raw and analysis frames using the existing
MonitorStream.show_analyse_frames() method.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The Add New Role button was not working because the AddNewRole
JavaScript function was missing from options.js. Added the handler
function following the same pattern as AddNewUser.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add a User Roles system where roles define reusable permission templates.
When a user has a role assigned, the role provides fallback permissions
(user's direct permissions take precedence; role is used when user has 'None').
Database changes:
- Add User_Roles table with same permission fields as Users
- Add Role_Groups_Permissions table for per-role group overrides
- Add Role_Monitors_Permissions table for per-role monitor overrides
- Add RoleId foreign key to Users table
Permission resolution order:
1. User's direct Monitor/Group permissions (if not 'Inherit')
2. Role's Monitor/Group permissions (if user has role)
3. Role's base permission (if user's is 'None')
4. User's base permission (fallback)
Includes:
- PHP models: User_Role, Role_Group_Permission, Role_Monitor_Permission
- Role management UI in Options > Roles tab
- Role selector in user edit form
- REST API endpoints for roles CRUD
- Translation strings for en_gb
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Updated all three video creation functions in thumbnail overlays to
respect the user's mute preference stored in the zmWatchMuted cookie:
- go2rtc streams (video-stream element)
- RTSP2Web HLS streams
- MP4 video playback for recorded events
Default behavior remains muted unless user has explicitly set the
cookie to 'false' via the watch page volume controls.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Increase font size ~28% for better readability
- Add more spacing between video and status bar
- Enlarge LIVE dot with glow effect
- Make pulse animation more pronounced (scale 1.0 to 1.4)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add status bar below video with LIVE indicator for live streams
- Show pulsing red dot animation for live streams
- Display wall clock time that updates as recorded video plays
- Add event start time data attribute to console and events pages
- Hide status bar when no content to display
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Support go2rtc, RTSP2Web, and Janus streaming in thumbnail popups
- Separate still thumbnail logic from hover overlay streaming
- Still thumbnails use event snapshot when not decoding
- Hover overlay prioritizes live streaming over recorded video
- Refactor thumbnail JS into focused helper functions
- Fix video-stream.js path for dynamic import
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add a Preview Rate dropdown control that allows users to adjust the
playback speed of thumbnail hover preview videos on the events page.
- Add previewRateHtml() helper method to Filter class
- Add Preview Rate to simple_widget() filter bar with matching term styling
- Add getPreviewRate() and changePreviewRate() JS functions in skin.js
- Add helper functions in _monitor_filters.php for rate options
- Store selected rate in zmPreviewRate cookie (values: 100-1600 for 1x-16x)
- Add PreviewRate translation to en_gb.php
- Add CSS styling for preview rate control
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When a monitor is not analyzing or decoding, the console thumbnail now
shows the most recent event's snapshot instead of attempting a live
stream. The hover overlay plays the event replay (with mp4 support if
available).
For active monitors with go2rtc enabled, the hover overlay now uses
go2rtc WebRTC streaming via the video-stream custom element, with a
3-second fallback to MJPEG if the connection fails.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix chained assignment creating implicit globals (shifted/ctrled/alted)
- Fix .done() callback executing immediately instead of on success
- Fix XOR operator (^) used instead of exponentiation in human_filesize()
- Fix invalid destructuring assignment in applyChosen()
- Fix implicit global creation in closeMbExtruder() call
- Add missing var declarations for runstate, length, modal variables
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Thumbnail hover now creates a separate overlay element centered
on-screen instead of transforming the original thumbnail in place.
The overlay shows the cached still image as a background for instant
display, with the stream or video layered on top.
When an event has an mp4 file (DefaultVideo), the overlay uses a
<video> tag at 5x playback speed for smooth hardware-decoded
playback. Falls back to MJPEG <img> stream with scale=32 when
no mp4 is available. On mouseout the stream/video connection is
explicitly stopped before the overlay is removed.
Removes the old .zoom/.zoom-console CSS classes and the console
overflow workarounds that were needed for the in-place approach.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Center-align QR code as focal point
- Add subtle box shadow and border radius to QR container
- Use compact inline form for optional password field
- Auto-generate QR code on page load, regenerate on password input
- Remove collapsed section, always show QR code
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add QR code generation feature to the user edit page that allows
administrators to quickly set up users in the zmNg mobile app.
- Add qrcode.min.js library for client-side QR code generation
- Add collapsible QR code section to user.php view
- Generate QR codes with zmNg-compatible JSON format containing
profile name, portal URL, username, and password
- Profile name uses ZM_WEB_TITLE or ZM_HOME_URL if customized,
otherwise defaults to 'ZoneMinder'
- Only visible when API is enabled and user has API access
- Add translation strings for new UI elements
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>