Tuner v1: HLS pipeline with playback/ingest modes

FFmpeg -> MediaMTX -> HLS relay with runtime-configurable modes:
- PLAYBACK_MODE: standard (mpegts), fmp4 (HEVC), llhls
- INGEST_MODE: rtmp, rtsp
- INGEST_AUDIO_MODE: aac, copy
- Hourly playlist auto-refresh from upstream URL
- Fullscreen video UI with collapsible sidebar, upstream-down banner
- Same-origin HLS proxy for HTTPS deployments

Tagged as the last HLS-based version before the mpegts.js (v2) rework.
This commit is contained in:
2026-06-12 19:17:15 -07:00
parent a41c3ee56c
commit 88a189de34
20 changed files with 814 additions and 123 deletions

View File

@@ -5,6 +5,7 @@ import (
"fmt"
"io"
"log"
"os"
"os/exec"
"sync"
"time"
@@ -18,6 +19,7 @@ type MediaMTXManager struct {
cmd *exec.Cmd
binaryPath string
configPath string
extraEnv []string
startTime time.Time
lastError string
stopCh chan struct{}
@@ -32,6 +34,14 @@ func NewMediaMTXManager(binaryPath, configPath string) *MediaMTXManager {
}
}
// SetEnv sets additional environment variables (e.g. MTX_HLSVARIANT) that are
// passed to MediaMTX. Must be called before Start.
func (m *MediaMTXManager) SetEnv(env []string) {
m.mu.Lock()
defer m.mu.Unlock()
m.extraEnv = env
}
// Start launches the MediaMTX process. It auto-restarts on unexpected exit.
func (m *MediaMTXManager) Start() error {
m.mu.Lock()
@@ -52,6 +62,9 @@ func (m *MediaMTXManager) startLocked() error {
}
m.cmd = exec.Command(m.binaryPath, m.configPath)
if len(m.extraEnv) > 0 {
m.cmd.Env = append(os.Environ(), m.extraEnv...)
}
m.lastError = ""
m.stopped = false
m.stopCh = make(chan struct{})