refactor: Direct MP4 playback, HLS smoothing, manual camera setup, and operational hardening #1

Closed
crypt wants to merge 2 commits from opencode into master
First-time contributor

Backend:

  • Add dedicated -webrtc go2rtc stream keys with forced H.264 transcoding for WebRTC (not yet working)
    consumers (MSE/HLS keep passthrough RTSP); clean up on stream_delete
  • HLS path allowlist in go2rtc config (/api/hls/playlist.m3u8, init.mp4, segment.m4s, segment.ts)
  • Direct MP4 playback endpoints: /api/playback/segment/ and
    /api/playback/segment/<camera_id>/at.mp4?at=ISO — bypass go2rtc for frame-accurate
    seeking via HTTP Range requests (no HLS chunk boundaries)
  • Fix recording_reconcile: streaming iterator + batch DELETE instead of full-table load
  • Fix cameras.py _fetch_go2rtc_streams: try/except when go2rtc is unreachable
  • Fix ops_alerts.py: threading.RLock for thread-safe alert state
  • Fix recorder_retention.py: SQL string formatting cleanup
  • Default WebRTC ICE candidates: stun:stun.l.google.com:19302 (was stun:8555) (no working yet)
  • worker_status_server: bind to 127.0.0.1 instead of 0.0.0.0

Frontend:

  • PlaybackHlsPlayer: native
  • HLS live config: liveSyncDuration=90s, liveMaxLatencyDuration=180s, maxBufferLength=60,
    backBufferLength=60, liveDurationInfinity=true — eliminates rebuffering by
    staying 90s behind the live edge
  • LivePlayer: HLS config increased (sync=3, buffer=12, back=8); iframe consumer
    probing via go2rtc /api/streams polling with 1s interval for accurate TTFF metrics
  • CameraView: HLS mode uses PlaybackHlsPlayer; WebRTC mode uses webrtc_stream_name;
    periodic 3s webrtc stats polling; debug panels for HLS/WebRTC probe state
  • Dashboard: pass playbackMode through to tiles for correct WebRTC stream name
  • DeviceSetup: manual RTSP camera add form with stream key slug, main/sub RTSP URLs;
    camera editor now loads and saves RTSP URLs; camera delete with confirmation
  • Configuration: ICE candidate default updated to google STUN

Infra:

  • docker-compose: expose go2rtc 8555/tcp+udp, nginx on 8080
  • nginx: sub_filter go2rtc container hostnames in HLS playlists for browser access
Backend: - Add dedicated -webrtc go2rtc stream keys with forced H.264 transcoding for WebRTC (not yet working) consumers (MSE/HLS keep passthrough RTSP); clean up on stream_delete - HLS path allowlist in go2rtc config (/api/hls/playlist.m3u8, init.mp4, segment.m4s, segment.ts) - Direct MP4 playback endpoints: /api/playback/segment/<id> and /api/playback/segment/<camera_id>/at.mp4?at=ISO — bypass go2rtc for frame-accurate seeking via HTTP Range requests (no HLS chunk boundaries) - Fix recording_reconcile: streaming iterator + batch DELETE instead of full-table load - Fix cameras.py _fetch_go2rtc_streams: try/except when go2rtc is unreachable - Fix ops_alerts.py: threading.RLock for thread-safe alert state - Fix recorder_retention.py: SQL string formatting cleanup - Default WebRTC ICE candidates: stun:stun.l.google.com:19302 (was stun:8555) (no working yet) - worker_status_server: bind to 127.0.0.1 instead of 0.0.0.0 Frontend: - PlaybackHlsPlayer: native <video> for VOD with direct MP4, hls.js for live only; stable player key per camera (no remount on seek) - HLS live config: liveSyncDuration=90s, liveMaxLatencyDuration=180s, maxBufferLength=60, backBufferLength=60, liveDurationInfinity=true — eliminates rebuffering by staying 90s behind the live edge - LivePlayer: HLS config increased (sync=3, buffer=12, back=8); iframe consumer probing via go2rtc /api/streams polling with 1s interval for accurate TTFF metrics - CameraView: HLS mode uses PlaybackHlsPlayer; WebRTC mode uses webrtc_stream_name; periodic 3s webrtc stats polling; debug panels for HLS/WebRTC probe state - Dashboard: pass playbackMode through to tiles for correct WebRTC stream name - DeviceSetup: manual RTSP camera add form with stream key slug, main/sub RTSP URLs; camera editor now loads and saves RTSP URLs; camera delete with confirmation - Configuration: ICE candidate default updated to google STUN Infra: - docker-compose: expose go2rtc 8555/tcp+udp, nginx on 8080 - nginx: sub_filter go2rtc container hostnames in HLS playlists for browser access
Backend:
- Add dedicated -webrtc go2rtc stream keys with forced H.264 transcoding for WebRTC
  consumers (MSE/HLS keep passthrough RTSP); clean up on stream_delete
- HLS path allowlist in go2rtc config (/api/hls/playlist.m3u8, init.mp4, segment.m4s, segment.ts)
- Direct MP4 playback endpoints: /api/playback/segment/<id> and
  /api/playback/segment/<camera_id>/at.mp4?at=ISO — bypass go2rtc for frame-accurate
  seeking via HTTP Range requests (no HLS chunk boundaries)
- Fix recording_reconcile: streaming iterator + batch DELETE instead of full-table load
- Fix cameras.py _fetch_go2rtc_streams: try/except when go2rtc is unreachable
- Fix ops_alerts.py: threading.RLock for thread-safe alert state
- Fix recorder_retention.py: SQL string formatting cleanup
- Default WebRTC ICE candidates: stun:stun.l.google.com:19302 (was stun:8555)
- worker_status_server: bind to 127.0.0.1 instead of 0.0.0.0

Frontend:
- PlaybackHlsPlayer: native <video> for VOD with direct MP4, hls.js for live only;
  stable player key per camera (no remount on seek)
- HLS live config: liveSyncDuration=90s, liveMaxLatencyDuration=180s, maxBufferLength=60,
  backBufferLength=60, liveDurationInfinity=true — eliminates rebuffering by
  staying 90s behind the live edge
- LivePlayer: HLS config increased (sync=3, buffer=12, back=8); iframe consumer
  probing via go2rtc /api/streams polling with 1s interval for accurate TTFF metrics
- CameraView: HLS mode uses PlaybackHlsPlayer; WebRTC mode uses webrtc_stream_name;
  periodic 3s webrtc stats polling; debug panels for HLS/WebRTC probe state
- Dashboard: pass playbackMode through to tiles for correct WebRTC stream name
- DeviceSetup: manual RTSP camera add form with stream key slug, main/sub RTSP URLs;
  camera editor now loads and saves RTSP URLs; camera delete with confirmation
- Configuration: ICE candidate default updated to google STUN

Infra:
- docker-compose: expose go2rtc 8555/tcp+udp, nginx on 8080
- nginx: sub_filter go2rtc container hostnames in HLS playlists for browser access
crypt requested review from elirtf 2026-05-10 23:24:56 -05:00
elirtf closed this pull request 2026-05-12 10:51:30 -05:00
Owner

silly me f'd this up

silly me f'd this up

Pull request closed

Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
elirtf/opus!1
No description provided.