--- id: potential-fixes type: reference status: draft tags: [startup-race, plex-live-tv, troubleshooting, improvements] --- # Potential Fixes for Plex Live TV Startup Race This document catalogs potential solutions for the **Plex Live TV startup race** issue, where Plex opens a tuner session but fails to find the consumer (`dash_init_404`, `Failed to find consumer`). The core problem is that Plex's internal DASH/HLS packager cannot instantiate its consumer before receiving valid MPEG-TS bytes. > **Note:** Gateway code is split across many **`gateway_*.go`** files. Sections below may still mention historical **`gateway.go`** line numbers; treat those as **conceptual** and follow symbols in the tree (or [plex-livetv-http-tuning](reference/plex-livetv-http-tuning.md) **HR-001**). ## Current implementation (where the code lives today) 1. **WebSafe startup gate** — sliding window, IDR / HEVC IRAP + AAC detection, **`release=`** logging: [`internal/tuner/gateway_stream_helpers.go`](../internal/tuner/gateway_stream_helpers.go) (with [`gateway_relay.go`](../internal/tuner/gateway_relay.go) for ffmpeg TS relay). 2. **Bootstrap TS** — ffmpeg-generated fallback: [`writeBootstrapTS`](../internal/tuner/gateway_ffmpeg_relay.go) in **`gateway_ffmpeg_relay.go`**. 3. **Null / PAT+PMT keepalives** — same helper / relay layer as the startup gate (see **`gateway_stream_helpers.go`**). 4. **Plex client hints** — [`plexRequestHints`](../internal/tuner/gateway_adapt.go) in **`gateway_adapt.go`**. 5. **Serve path** — [`ServeHTTP`](../internal/tuner/gateway_servehttp.go) in **`gateway_servehttp.go`** → upstream walk in **`gateway_stream_upstream.go`** / response relay in **`gateway_stream_response.go`**. ## Potential Fixes --- ### 1. Client-Aware Adaptation **Description**: Detect Plex client type via User-Agent header and dynamically adjust startup parameters. **Current Code Evidence**: - Plex client hints are parsed in [`gateway_adapt.go`](../internal/tuner/gateway_adapt.go) (`plexRequestHints`): ```go SessionIdentifier: get("X-Plex-Session-Identifier", ...) ClientIdentifier: get("X-Plex-Client-Identifier", ...) Product: get("X-Plex-Product"), Platform: get("X-Plex-Platform", "X-Plex-Client-Platform"), Device: get("X-Plex-Device", "X-Plex-Device-Name"), ``` - Client class resolution: `requestAdaptation` / `resolvePlexClient` in the same package (**`gateway_adapt.go`** and tests in **`gateway_test.go`**) **Implementation**: - Map known Plex clients to timing profiles: - **Plex Web**: Most sensitive to startup timing - **Roku**: Known for strict timing requirements - **Apple TV**: More tolerant - **Shield TV**: Generally reliable - **Fire TV**: Variable by generation - Adjust these parameters per client: - `WEBSAFE_STARTUP_MIN_BYTES`: 64KB (web) → 128KB (Roku) - `WEBSAFE_STARTUP_TIMEOUT_MS`: 12000 → 20000 (slower clients) - Prefer PAT+PMT keepalive for stricter clients **Pros**: - Already has client detection infrastructure - Targeted optimization per client type **Cons**: - Requires maintaining client compatibility matrix - Some clients may not send identifiable User-Agent --- ### 2. Pre-Segment Fetching **Description**: Prefetch HLS manifest and first 3-5 segments before connecting to Plex, then stream them contiguously. **Current Implementation Gap**: - Current startup gate buffers ffmpeg output - No pre-fetch of HLS segments before ffmpeg starts **Implementation**: ``` 1. Plex requests /stream/1 2. Fetch HLS manifest from provider 3. Download first N segments (e.g., segments 0-4) 4. Start ffmpeg, feeding it from cached segments 5. Once startup gate passes, switch to live ffmpeg output ``` **Technical Details**: - HLS segments typically 2-10 seconds each - First segments often larger (keyframe-aligned) - Need to handle segment encryption (EXT-X-KEY) **Pros**: - Eliminates network round-trip from critical path - More predictable first bytes **Cons**: - Increases memory usage during startup - Adds complexity for segment caching - May not help if ffmpeg is the bottleneck --- ### 3. Adaptive Transcode Priority for Startup **Description**: Temporarily force transcoding during startup, then downgrade to remux after startup gate passes. **Current Code**: - Transcode mode is set globally via `StreamTranscodeMode` ("off", "on", "auto") - The `auto` mode uses ffprobe to detect Plex-friendly codecs **Implementation**: ```go // Pseudo-code if transcodeMode == "off" { // Force transcode during startup startupProfile := "libx264/aac" actualProfile = startupProfile } // After startup gate passes: // If original mode was "off" and codec is Plex-friendly, switch to remux ``` **Why It Might Help**: - Transcoded streams have deterministic output timing - Remuxed HLS depends on upstream segment availability - Transcoded output is continuous MPEG-TS vs segment-based **Pros**: - More predictable timing during critical startup window - Falls back to optimized mode after initialization **Cons**: - Higher CPU usage during startup - May increase startup latency - Complexity in profile switching --- ### 4. Metrics-Driven Auto-Tuning **Description**: Add structured metrics collection and use data to automatically tune parameters. **What to Measure**: - Startup time percentiles (p50, p95, p99) per client type - Startup failure rate per client/channel/time - Time to first valid TS packet - Keepalive effectiveness **Implementation**: ```go // Add metrics var ( startupDuration = prometheus.NewHistogramVec(...) startupFailures = prometheus.NewCounterVec(...) ) // In stream handler timer := prometheus.NewTimer(startupDuration.WithLabelValues(clientType, channelName)) defer timer.ObserveDuration() ``` **Tools to Use**: - Prometheus client for Go (`prometheus/client_golang`) - Export at `/metrics` endpoint **Pros**: - Data-driven optimization decisions - Identifies problematic clients/channels - Enables alerting on failure spikes **Cons**: - Adds dependencies - Requires operational overhead --- ### 5. Simulated "Live" Buffer Offset **Description**: Start streaming 2-5 seconds behind live edge instead of at live edge. **Implementation**: - HLS: Set `-hls_start_offset` in ffmpeg - For 3 second offset at 2s segments: `-hls_start_offset 3` - This gives Plex's packager time to initialize while stream still appears "live" **Configuration**: ```bash IPTV_TUNERR_STARTUP_LIVE_OFFSET_SECONDS=3 ``` **Trade-offs**: - Small delay (acceptable for live TV) - Must calculate based on segment duration --- ### 6. HTTP/2 Multiplexing **Description**: Upgrade from HTTP/1.1 to HTTP/2 for upstream connections. **Current State**: - Uses standard Go HTTP client (HTTP/1.1 by default) - Each backup URL attempt creates new connection **Implementation**: ```go // In httpclient or gateway transport := &http2.Transport{} client := &http.Client{Transport: transport} ``` **Pros**: - Reduced connection overhead - Better handling of multiple backup URLs - Header compression **Cons**: - Single long-lived stream - minimal benefit - May not work with all IPTV providers - Adds HTTP/2 dependency --- ### 7. Graceful Degradation Chain **Description**: Automatic fallback chain: primary URL → backup URLs → transcode → different protocol. **Current Behavior**: - Backup URLs are tried in order (lines 93-101 in main.go) - If all fail, stream fails - No automatic fallback to transcoding if remux fails **Implementation**: ``` Priority chain: 1. Primary URL + remux (current default) 2. Backup URL 1 + remux 3. Backup URL 2 + remux 4. Primary URL + transcode 5. Bootstrap TS (last resort) ``` **Pros**: - Maximizes chances of successful stream - Leverages existing backup URL infrastructure **Cons**: - Increases startup latency if multiple fallbacks needed - Complex error handling --- ### 8. Alternative Protocol Support **Description**: Support additional streaming protocols beyond HLS. **Candidates**: - **MPEG-DASH**: Some providers offer this instead of HLS - **RTMP**: Older but reliable - **UDP multicast**: For local network sources - **SRT**: Modern secure reliable transport **Implementation**: - Detect available protocols from provider - Add protocol-specific handlers in gateway - Test compatibility with Plex **Pros**: - Different timing characteristics - May work better with certain providers **Cons**: - Significant development effort - Plex must support the output format --- ### 9. Improved Bootstrap TS Generation **Description**: Enhance the deterministic bootstrap TS generation for timeout fallback. **Current Implementation**: - [`writeBootstrapTS()`](../internal/tuner/gateway_ffmpeg_relay.go) (**`gateway_ffmpeg_relay.go`**) generates basic MPEG-TS - Uses ffmpeg with `-f mpegts` and null input **Improvements**: - Include PAT/PMT with proper program numbers - Add video (black frame with IDR) + audio (silence) - Make it longer/deterministic - Include PCR timestamps for DASH compatibility **Pros**: - More realistic fallback when upstream is slow - Better chance of satisfying Plex's packager **Cons**: - Slightly larger bootstrap payload - More ffmpeg overhead --- ### 10. Diagnostic and Tuner Self-Test on Startup **Description**: Run a quick self-test when Plex connects, rather than immediately trying the live stream. **Implementation**: 1. When Plex opens `/stream/`: 2. Send a known test pattern (small TS with PAT/PMT/IDR) 3. Verify Plex acknowledged the stream 4. Then switch to live stream **Why It Might Help**: - Separates "can Plex see this?" from "here's live content" - May pre-initialize Plex's consumer **Pros**: - Early detection of Plex compatibility issues - Gives Plex more time **Cons**: - Adds latency - Complex state management --- ## Recommendations Based on the current codebase and implementation: 1. **Highest Priority**: Client-Aware Adaptation - leverage existing client detection infrastructure 2. **Second Priority**: Improved Bootstrap TS - extend current fallback mechanism 3. **Third Priority**: Metrics-Driven Auto-Tuning - enables data-driven decisions 4. **Lower Priority**: Pre-Segment Fetching, HTTP/2 - more complex with uncertain benefit The PAT+PMT keepalive feature (already implemented) is theoretically the most promising current approach, but may need tuning of the interval (`WEBSAFE_PROGRAM_KEEPALIVE_MS`) for different clients. ## References - [`docs/runbooks/iptvtunerr-troubleshooting.md`](runbooks/iptvtunerr-troubleshooting.md) — troubleshooting guide - [`docs/reference/plex-livetv-http-tuning.md`](reference/plex-livetv-http-tuning.md) — **HR-001** WebSafe startup gate + env table - [`internal/tuner/gateway_stream_helpers.go`](../internal/tuner/gateway_stream_helpers.go) — prefetch / keyframe gate - [`.env.example`](../.env.example) — configuration options