Skip to content

Refactor RTMP/SRT multistream relay server with HLS, HTTP-FLV, FFmpeg transcoding, REST API, and web dashboard#4

Closed
nglmercer wants to merge 47 commits into
RustLangES:mainfrom
nglmercer:reconnect
Closed

Refactor RTMP/SRT multistream relay server with HLS, HTTP-FLV, FFmpeg transcoding, REST API, and web dashboard#4
nglmercer wants to merge 47 commits into
RustLangES:mainfrom
nglmercer:reconnect

Conversation

@nglmercer

@nglmercer nglmercer commented May 29, 2026

Copy link
Copy Markdown
Contributor

What's built

Core

  • RTMP relay with multistream forwarding (RTMP/RTMPS)
  • SRT protocol (input listener, output sender, AES-128 encryption)
  • SRT bridge (SRT→RTMP→HLS pipeline with stats)
  • RTSP input support (TCP/UDP transport, FFmpeg restream)
  • TLS/RTMPS support with reconnection logic
  • Configuration via TOML with ConfigBuilder pattern
  • Concrete pipeline implementations (RTMP, SRT, File)

FFmpeg

  • Binary resolver (platform URL mapping, download, checksum)
  • Command builder (passthrough, HLS, transcode, HW accel)
  • Process supervisor with auto-restart and backoff
  • Hardware acceleration (VAAPI, NVENC, VideoToolbox, MMAL)
  • Stream processing (transcode profiles, resize, watermark, thumbnail)
  • Recording (FFmpeg-based, MP4/FLV/MKV/TS, scheduled, rotation)

Server

  • HTTP server using axum
  • HLS segmenter with live .m3u8 playlist
  • HTTP-FLV live streaming (/stream.flv)
  • REST API (25 endpoints)
  • Prometheus metrics (uptime, streams, viewers, bitrate)
  • Webhook notifications (stream start/end/error, viewer connect/disconnect)
  • DVR/timeshift buffer
  • WebRTC config (ICE servers)
  • Adaptive bitrate (ABR) for HLS (master playlist generation)

Dashboard

  • Vite 8 + Preact + TypeScript + Tailwind CSS 4
  • Video preview (FLV/HLS player with flv.js, latency monitor)
  • First-time setup wizard (CLI --setup + web wizard)
  • Settings panel (stream key reveal/reset, server endpoints, OBS guide)
  • Platform management (add/remove with presets)
  • Recording controls (start/stop/delete)
  • Stream and platform tables
  • Log viewer
  • Auto-refresh polling
imagen imagen imagen

nglmercer and others added 30 commits January 18, 2026 17:50
The client state handling and network tasks have been significantly refactored to prevent
resource deadlocks and unbounded memory growth. This includes proper buffering of media
before publication, graceful shutdown procedures, and enhanced logging for connection status.

Key changes:
- Added bounded media buffers with LRU eviction for video/audio frames to prevent memory leaks
- Implemented structured background tasks for TCP reading/writing with proper cancellation
- Added sequence header caching and pre-publication buffering to ensure stream continuity
- Enhanced RTMP event handling to detect connection failures and reject streams appropriately
- Improved logging for connection status, errors, and shutdown events
- Simplified TLS connection setup and error propagation
Create reestream-srt with listener and sender implementations,
configuration, and error handling. Update workspace and roadmap to
reflect new protocol support.
Introduce graceful shutdown, rate limiting, and connection pooling in
reestream-core. Add webhook module to reestream-server for stream event
notifications. Enable SRT feature in main crate with proper dependency
management.
- Simplify error responses in stop_recording and delete_recording
- Clone input and path for async task ownership in RecordingManager
- Adjust build_ffmpeg_args to accept &Path instead of &PathBuf
and SRT bridge

Add RTSP input support with TCP/UDP transport and FFmpeg integration.
Implement
security module with IP allowlist/blocklist, API token auth, and ACME
config.
Add stream processing capabilities including transcode profiles,
watermarks,
thumbnails, and resize filters. Introduce DVR buffer with timeshift
support and
segment management. Add WebRTC configuration with ICE servers and
adaptive bitrate
for HLS output. Implement SRT bridge enabling SRT to RTMP/HLS pipeline
with stats.
Include fuzz tests for parsing edge cases and stress tests for
concurrent load.
…oints

- Add PUT /api/platforms/{id} for editing platforms (name, url, key, enabled)
- Add update_platform() to StreamManager with partial update support
- Make GET /api/config read real config from disk with platform list
- Make PUT /api/config write changes to config.toml
- Sync platform add/edit/remove to config.toml automatically
- Add setup.rs functions: read_config, save_config, update_config_fields,
  add_platform_to_config, update_platform_in_config, remove_platform_from_config
- Add UpdatePlatformRequest type to API and dashboard client
- Update dashboard PlatformsTable with inline edit form (name, url, key, enabled)
- Update dashboard API types for new config response format
- Fix integration tests to use reestream:: re-exports with feature gates
- Add 8 new tests for config sync functions
- Remove unused ConfigResponse and UpdateConfigRequest from http.rs

Total: 360 tests, 0 clippy warnings, clean fmt
- Add WebSocket endpoint /ws/streams for live stream events
- Integrate StreamManager with RTMP publisher for auto-registration
- Add useStreamWs hook in dashboard for real-time updates
- Show connection status indicator in header
- Wrap raw RTMP data in proper FLV tags (11-byte header + prev-tag-size)
  in the DataBus→FlvState bridge; previously raw payloads were sent
  causing 'URI no válida' and MSE decode errors
- Fix flv.js ESM bundler incompatibility: disable web worker, change
  seekType to 'param', add optimizeDeps.include in vite.config.ts
  to resolve 'Class extends value undefined' error
- Add ffmpeg-based HLS transmuxer (hls_transmux.rs) that pipes FLV data
  to ffmpeg stdin to produce .ts segments and .m3u8 playlist
- Update HLS playlist/segment endpoints to serve ffmpeg-generated files
- Add integration tests for FLV stream, HLS playlist, and HLS segment
  endpoints, plus FLV tag wrapping correctness tests
- Add bytes and tower dependencies for new code and tests
…eview switching

Theme system:
- Add useTheme hook with Context/Provider, localStorage persistence, OS preference detection
- Add CSS custom properties for semantic colors (surface, fg, accent, danger, success, warning)
- Add theme toggle button (sun/moon) in Header
- Update all components to use theme-aware CSS tokens

Memory leak fixes:
- Track setTimeout in SettingsPanel with useRef, clear on unmount
- Add AbortController to fetch calls in SetupWizard, app.tsx, SettingsPanel

Performance:
- usePolling: store fetcher in ref to prevent unnecessary interval resets
- useVideoPlayer: use ref for playing state in toggle callback

Video preview fix:
- Properly destroy FLV/HLS players with detachMediaElement before destroying
- Add video.load() after clearing src to fully reset video element state
- Use initIdRef to prevent async player init from attaching to wrong effect run
- Use requestAnimationFrame to ensure video element is reset before new player init
- Add language dropdown to Header (en/es)
- Update app.tsx with translated log messages and error strings
- Update RecordingControls with translated UI and log messages
- Update SettingsPanel with translated UI and log messages
- Update VideoPreview with translated UI strings
- Update useVideoPlayer with translated error messages
- Rebuild static assets
- Calculate bitrate from incoming data bytes per second
- Update stream stats via StreamManager every second
- Use tokio::select! for concurrent packet processing and bitrate reporting
nglmercer added 17 commits May 28, 2026 23:55
Fixes FLV preview not working after switching to HLS and back.
The resetVideo() function now waits for the 'emptied' event to ensure
the video element is fully cleaned up before attaching a new player.
readyState === 0 means the element has no source, so emptied event
never fires and the promise hangs forever, blocking player init.
Backend:
- DataBus bridge breaks permanently on broadcast Lagged error
  (Err(_) => break catches recoverable Lagged, now handled separately)
- FlvState race condition: subscribe() before get_recent() causes
  duplicate/gap in data (added subscribe_with_recent for atomic op)
- PlatformEvent::Toggled missing url/key fields

Frontend:
- flv.js destroy order reversed (destroy before detachMediaElement)
- requestAnimationFrame race prevents FLV reinit on source switch
- enableStashBuffer disabled causes flv.js to fail on reconnection
Added serve_static handler and /{path} route for root-level files.
index.html references /index.js and /index.css but only /assets/{*path}
was routed, causing MIME type error on module load.
@Juanperias

Copy link
Copy Markdown
Member

+18,032-964Lines changed: 18032 additions & 964 deletions

This is going to take a while to review

@Juanperias

Copy link
Copy Markdown
Member

This pull request contains several critical issues and features that, frankly, seem unnecessary. Furthermore, the sheer volume of changes makes me suspect this code might be AI-generated. If this was written by a human, please don't take this review personally; my concerns are strictly with the code itself. The added TypeScript code in the dashboard doesn't seem to add any real value.

Also, regarding the FLV implementation: we already have an established implementation within the community. Using that one would save you time and be much better for the project's long-term maintenance.

@Juanperias Juanperias closed this May 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants