#!/bin/bash # Generate emergency slate video + pre-rendered HLS segments for failover. # Output: data/slate/ (slate MP4 + HLS segments + manifest) # Requires: ffmpeg set -e SLATE_DIR="${1:-data/slate}" mkdir -p "$SLATE_DIR" SLATE_MP4="$SLATE_DIR/slate.mp4" SLATE_HLS="$SLATE_DIR/hls" mkdir -p "$SLATE_HLS" echo "=== Generating Emergency Slate ===" # 1. Generate 10s slate video: color bars + "We'll Be Right Back" text echo "[1/3] Generating slate video (10s, H.264/AAC, 30fps, 2s keyframes)..." ffmpeg -y -f lavfi -i "color=c=#1a1a2e:s=1280x720:d=10:r=30" \ -f lavfi -i "sine=frequency=440:duration=10" \ -filter_complex "[0]drawtext=text='Linear Void':fontcolor=#587792:fontsize=60:x=(w-text_w)/2:y=(h-text_h)/2-40,drawtext=text='We'\''ll Be Right Back':fontcolor=#ede8e6:fontsize=36:x=(w-text_w)/2:y=(h-text_h)/2+30[bg];[1]volume=0.15[a]" \ -map "[bg]" -map "[a]" \ -c:v libx264 -preset medium -crf 21 \ -r 30 -g 60 -keyint_min 60 -sc_threshold 0 \ -pix_fmt yuv420p \ -c:a aac -b:a 128k -ar 48000 -ac 2 \ -movflags +faststart \ -t 10 \ "$SLATE_MP4" echo " Slate MP4: $(du -h "$SLATE_MP4" | cut -f1)" # 2. Verify slate meets normalization profile echo "[2/3] Verifying slate normalization..." ffprobe -v error -show_entries stream=codec_name,width,height,r_frame_rate,pix_fmt,sample_rate \ -of default=noprint_wrappers=1 "$SLATE_MP4" 2>&1 | head -10 # 3. Package as pre-rendered HLS (fMP4, 6s segments) echo "[3/3] Packaging as HLS..." ffmpeg -y -i "$SLATE_MP4" \ -c copy \ -f hls \ -hls_time 6 \ -hls_list_size 5 \ -hls_segment_type fmp4 \ -hls_fmp4_init_filename "init.mp4" \ -hls_flags "independent_segments" \ -hls_segment_filename "$SLATE_HLS/slate_segment_%03d.m4s" \ "$SLATE_HLS/slate.m3u8" echo "" echo "=== Slate Generated ===" echo " MP4: $SLATE_MP4" echo " Manifest: $SLATE_HLS/slate.m3u8" echo " Segments: $(find "$SLATE_HLS" -name '*.m4s' | wc -l) files" echo " Init: $SLATE_HLS/init.mp4" echo "" echo "To use: mount $SLATE_HLS as /app/slate in playout container"