Implement Tuner v1 — Go backend, React frontend, Docker setup

- Go backend: REST API, M3U parser, FFmpeg/MediaMTX process manager
- React/Vite frontend: HLS player, admin panel, channel browser (dark theme)
- MediaMTX config for RTMP ingest + HLS output
- Multi-stage Dockerfile (Go + Bun + Alpine runtime)
- docker-compose.yml for single-container deployment
- Sample M3U playlist with test streams

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-07 09:47:32 -08:00
parent 2e66b8c73d
commit b8bfcefee8
33 changed files with 2257 additions and 0 deletions

32
backend/api/middleware.go Normal file
View File

@@ -0,0 +1,32 @@
package api
import (
"log"
"net/http"
"time"
)
// CORS wraps a handler with permissive CORS headers (allow all origins for MVP).
func CORS(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
if r.Method == http.MethodOptions {
w.WriteHeader(http.StatusNoContent)
return
}
next.ServeHTTP(w, r)
})
}
// Logging wraps a handler with request logging (method, path, duration).
func Logging(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
next.ServeHTTP(w, r)
log.Printf("%s %s %s", r.Method, r.URL.Path, time.Since(start).Truncate(time.Microsecond))
})
}