Skip to content

Conversation

@praisedavid787
Copy link

@praisedavid787 praisedavid787 commented Aug 8, 2025

Summary

This PR implements a new feature that maintains stream continuity when SRT publishers disconnect temporarily. Instead of terminating the stream, MediaMTX now generates silence for audio tracks, keeping consumers connected until the publisher reconnects.

Motivation

In production streaming environments, brief network interruptions can cause SRT publishers to disconnect, forcing all consumers to reconnect and disrupting the viewing experience. This feature addresses this issue by maintaining stream availability during temporary disconnections.

Changes

Core Features

  • New Configuration Option: srtPersistOnDisconnect (default: false)
    • Available via YAML configuration and REST API
    • Per-path configurable setting
  • Configurable Timeout: srtPersistTimeout (default: 20m)
    • Automatically closes streams if publisher doesn't reconnect within timeout
    • Prevents indefinite resource consumption
    • Configurable from 1 minute to 24 hours
  • Silence Generator: Generates format-aware silence for audio streams
    • Supports Opus (DTX frames), AAC, G.711 (µ-law/A-law)
    • Runs at 20ms intervals (standard audio frame duration)
  • Seamless Reconnection: Publishers can reconnect without consumer interruption

Technical Implementation

  • Added SilenceGenerator class in internal/stream/silence_generator.go
  • Modified path management in internal/core/path.go to handle persistence
  • Updated configuration system in internal/conf/path.go
  • Full API support through existing REST endpoints

Usage

YAML Configuration

paths:
  my_stream:
    source: publisher
    srtPersistOnDisconnect: yes
    srtPersistTimeout: 15m  # Close stream after 15 minutes if no reconnection

API Configuration

const props = {
    // ... other properties
    srtPersistOnDisconnect: true,
    srtPersistTimeout: "10m",  // Timeout after 10 minutes
    srtPublishPassphrase: "optional_passphrase"
};

REST API Examples

# Create path with SRT persistence and timeout
curl -X POST "http://localhost:9997/v3/config/paths/add/my_stream" \
     -H "Content-Type: application/json" \
     -d '{
       "source": "publisher",
       "srtPersistOnDisconnect": true,
       "srtPersistTimeout": "30m"
     }'

# Update existing path
curl -X PATCH "http://localhost:9997/v3/config/paths/patch/my_stream" \
     -H "Content-Type: application/json" \
     -d '{
       "srtPersistOnDisconnect": false
     }'

Behavior

When SRT Publisher Disconnects (persistence enabled)

  1. Stream remains active and ready
  2. Silence generator starts automatically
  3. Audio tracks output silence frames
  4. Consumers stay connected
  5. Timeout timer starts counting down
  6. Log: "SRT publisher disconnected, maintaining stream with silence generation for 20m"

When SRT Publisher Reconnects

  1. Silence generator stops
  2. Normal media flow resumes
  3. Timeout timer cancelled
  4. No interruption to consumers
  5. Log: "SRT publisher reconnecting, stopping silence generation"

When Timeout Expires (no reconnection)

  1. Silence generator stops
  2. Stream closes gracefully
  3. Consumers receive normal end-of-stream signals
  4. Log: "SRT persistence timeout reached, closing stream"

Testing

  • ✅ API integration tests pass
  • ✅ Configuration properly exposed via REST API
  • ✅ Field can be dynamically updated via PATCH requests
  • ✅ Backward compatible (disabled by default)

Test Scripts Included

  • test_srt_persistence_api.sh - API functionality verification
  • test_srt_persistence.sh - Full feature demonstration
  • example_srt_persistence.yml - Example configuration

Documentation

  • Comprehensive README with usage examples (SRT_PERSISTENCE_README.md)
  • API test scripts included
  • Example configurations provided

Breaking Changes

None. The feature is disabled by default and fully backward compatible.

Files Changed

  • internal/stream/silence_generator.go - New silence generation logic
  • internal/core/path.go - Path persistence management
  • internal/conf/path.go - Configuration support
  • mediamtx.yml - Updated default configuration
  • example_srt_persistence.yml - Example configuration
  • SRT_PERSISTENCE_README.md - Feature documentation
  • Test scripts for verification

Use Cases

  1. Live Broadcasting: Maintain stream continuity during brief network issues
  2. Conference Streaming: Keep audio channels alive during temporary disconnections
  3. Remote Production: Ensure uninterrupted output during encoder restarts
  4. Failover Scenarios: Bridge the gap between primary and backup publishers

Performance Impact

  • Minimal CPU overhead during silence generation
  • Memory usage: Keeps stream objects active during disconnection
  • Thread-safe implementation
  • No impact when feature is disabled

Future Improvements

  • Add video frame persistence (last frame repeat)
  • Configurable silence generation parameters
  • Metrics for persistence duration tracking
  • Support for other publisher protocols (RTMP, RTSP)

Related Issues

This feature addresses common production issues with SRT streaming:

  • Publisher network instability causing viewer disconnections
  • Brief encoder restarts disrupting entire streams
  • Failover gaps between redundant publishers

Compatibility

  • Tested with MediaMTX v1.8.5
  • Compatible with all SRT clients
  • Works with existing authentication and recording features
  • No changes required to existing configurations

David Akpan and others added 3 commits August 7, 2025 21:23
Implements a new feature that maintains stream continuity when SRT publishers
disconnect by generating silence until reconnection occurs.

Features:
- New configuration option: srtPersistOnDisconnect
- Silence generator for audio streams (Opus, AAC, G.711)
- Stream persistence during SRT publisher disconnection
- Seamless reconnection without consumer interruption
- Format-aware silence generation
- Comprehensive logging and monitoring

Technical changes:
- Add SilenceGenerator class in internal/stream/
- Modify path management to handle SRT disconnection persistence
- Add configuration support for persistence option
- Update default configuration with new option

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Add test script for verifying API functionality
- Update documentation with API usage examples
- Document how srtPersistOnDisconnect field works with REST API

The field is automatically available via the API through MediaMTX's
reflection-based OptionalPath system.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Added `srtPersistTimeout` configuration field (default: 20 minutes)
- Implemented timer mechanism to automatically close streams after timeout
- Timer starts when SRT publisher disconnects during persistence mode
- Timer cancelled when publisher reconnects before timeout
- Configurable via YAML and REST API
- Maintains backward compatibility with existing configurations

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@roger-
Copy link

roger- commented Aug 26, 2025

I’d like to see the upper limit on srtPersistTimeout be higher (infinity), but perhaps when video frame persistence is implemented.

- Replace mutex with atomic operations for better performance
- Add proper AAC-LC silence frame generation with ADTS headers
- Add nil checks in WriteUnit/WriteRTPPacket to prevent panics
- Implement graceful shutdown with done channel

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
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