fix: guard all R2 operations behind nil client checks for local dev support

This commit is contained in:
zwitschi committed 2026-08-11 14:46:50 +02:00
1 parent 1019972e25
commit 2a718e4652
1 file changed
+29 -7
+29 -7
View File
@@ -59,8 +59,21 @@ const (
manifestCacheControl = "public, max-age=1, s-maxage=2, must-revalidate" manifestCacheControl = "public, max-age=1, s-maxage=2, must-revalidate"
) )
// initR2Client initializes the R2 (S3-compatible) client // isR2Configured returns true when the required R2 environment variables are set.
func isR2Configured() bool {
return os.Getenv("R2_ENDPOINT") != "" &&
os.Getenv("R2_ACCESS_KEY_ID") != "" &&
os.Getenv("R2_SECRET_ACCESS_KEY") != "" &&
os.Getenv("R2_BUCKET_NAME") != ""
}
// initR2Client initializes the R2 (S3-compatible) client.
// Returns an error if required environment variables are missing.
func initR2Client() error { func initR2Client() error {
if !isR2Configured() {
return fmt.Errorf("R2 not configured: R2_ENDPOINT, R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY, or R2_BUCKET_NAME is empty")
}
cfg, err := config.LoadDefaultConfig(context.TODO(), cfg, err := config.LoadDefaultConfig(context.TODO(),
config.WithRegion("auto"), config.WithRegion("auto"),
config.WithCredentialsProvider(aws.CredentialsProviderFunc(func(ctx context.Context) (aws.Credentials, error) { config.WithCredentialsProvider(aws.CredentialsProviderFunc(func(ctx context.Context) (aws.Credentials, error) {
@@ -566,10 +579,9 @@ func main() {
os.Exit(1) os.Exit(1)
} }
// Initialize R2 client // Initialize R2 client (skip if not configured — local HLS via nginx still works)
if err := initR2Client(); err != nil { if err := initR2Client(); err != nil {
fmt.Println("Warning: R2 client initialization failed:", err) fmt.Println("R2 sync disabled:", err)
// Continue without R2 for local testing
} }
// Start HTTP health check server // Start HTTP health check server
@@ -612,9 +624,14 @@ func main() {
continue continue
} }
// Start filesystem watcher for real-time R2 segment upload (STREAMING.md) // Start filesystem watcher for real-time R2 segment upload (STREAMING.md).
watchCtx, watchCancel := context.WithCancel(context.Background()) // Only active when R2 is configured; otherwise the watcher is skipped.
var watchCtx context.Context
var watchCancel context.CancelFunc
if r2Client != nil {
watchCtx, watchCancel = context.WithCancel(context.Background())
go watchAndPublishSegments(watchCtx, hlsDir) go watchAndPublishSegments(watchCtx, hlsDir)
}
fmt.Printf("[%s] Starting FFmpeg playout with browser-safe H.264/AAC HLS encoding...\n", time.Now().Format(time.RFC3339)) fmt.Printf("[%s] Starting FFmpeg playout with browser-safe H.264/AAC HLS encoding...\n", time.Now().Format(time.RFC3339))
@@ -635,7 +652,9 @@ func main() {
filepath.Join(hlsDir, "playlist.m3u8")) filepath.Join(hlsDir, "playlist.m3u8"))
runErr := cmd.Run() runErr := cmd.Run()
if watchCancel != nil {
watchCancel() // Stop the filesystem watcher watchCancel() // Stop the filesystem watcher
}
// Track restart and check for slate escalation // Track restart and check for slate escalation
restartCount++ restartCount++
@@ -659,7 +678,9 @@ func main() {
deactivateSlate() deactivateSlate()
} }
// After FFmpeg run, publish remaining segments and atomic manifest to R2 // After FFmpeg run, publish remaining segments and atomic manifest to R2.
// Skipped when R2 is not configured.
if r2Client != nil {
if err := syncLatestToR2(hlsDir); err != nil { if err := syncLatestToR2(hlsDir); err != nil {
fmt.Println("R2 sync warning:", err) fmt.Println("R2 sync warning:", err)
} }
@@ -669,6 +690,7 @@ func main() {
if err := publishManifest(manifestPath); err != nil { if err := publishManifest(manifestPath); err != nil {
fmt.Println("Manifest publish warning:", err) fmt.Println("Manifest publish warning:", err)
} }
}
time.Sleep(5 * time.Second) time.Sleep(5 * time.Second)
} }