11 KiB
Movie Scheduler - Testing Environment
Complete Docker-based testing environment for the movie scheduler. Fire and forget - just run one command and everything is set up automatically!
Quick Start
./start-test-environment.sh
That's it! The script will:
- Build all Docker containers
- Start PostgreSQL, NocoDB, and RTMP server
- Initialize NocoDB with test data
- Download a test video (Big Buck Bunny)
- Start the scheduler
Services
After running the startup script, you'll have:
NocoDB Dashboard
- URL: http://localhost:8080
- Email: admin@test.com
- Password: admin123
Login and view the "Movies" table to see scheduled movies and their status.
RTMP Streaming Server
- Stream URL: rtmp://localhost:1935/live/stream
- Statistics: http://localhost:8081/stat
This is where processed movies will be streamed.
Movie Scheduler
Runs in the background, automatically:
- Syncs movies from NocoDB every 60 seconds (configurable)
- Monitors stream health every 10 seconds (configurable)
- Prepares videos 6 hours before scheduled time
- Streams at the scheduled time
Testing the Workflow
1. View Initial Data
The test environment comes with a pre-loaded movie:
- Title: BigBuckBunny
- Scheduled: 5 minutes from startup
Open NocoDB to see this entry.
2. Monitor the Scheduler
Watch the scheduler logs:
docker compose logs -f scheduler
You'll see:
- Syncing from NocoDB
- Preparation jobs (if within 6 hours of scheduled time)
- Subtitle generation
- Video encoding
- Streaming start
3. Check the Database
Query the local SQLite database:
sqlite3 scheduler.db "SELECT nocodb_id, title, prep_status, play_status FROM jobs;"
View detailed logs:
sqlite3 scheduler.db "SELECT title, log FROM jobs WHERE title='BigBuckBunny';"
4. Watch the Stream
When a movie starts streaming, watch it with VLC:
vlc rtmp://localhost:1935/live/stream
Or use ffplay:
ffplay rtmp://localhost:1935/live/stream
5. Add Your Own Movies
Option A: Through NocoDB UI
- Open http://localhost:8080
- Navigate to the Movies table
- Click "+ Add New Row"
- Fill in:
- Title: Name matching your video file
- Date: Schedule time (ISO format: 2024-01-21T20:00:00)
- Other fields are optional
- Place video file in
raw_moviesvolume
Option B: Add Video File Manually
Copy a video to the raw movies volume:
# Find the volume name
docker volume ls | grep raw_movies
# Copy your video
docker run --rm -v scheduler_raw_movies:/data -v $(pwd):/host alpine \
cp /host/your-movie.mp4 /data/
Then add the entry in NocoDB with matching Title.
Testing Restart & Recovery
Test Overdue Job Processing
- Add a movie scheduled for 15 minutes from now
- Stop the scheduler:
docker compose stop scheduler - Wait 20 minutes (past the prep time)
- Restart the scheduler:
docker compose start scheduler docker compose logs -f scheduler - Watch it immediately process the overdue prep job
Test 15-Minute Grace Period for Streaming
- Add a movie scheduled for 5 minutes from now (with prep already done)
- Stop the scheduler after prep completes:
docker compose stop scheduler - Wait 10 minutes (past streaming time but within 15-min grace period)
- Restart and watch logs:
docker compose start scheduler docker compose logs -f scheduler - Stream should start immediately with "Starting stream X.X minutes late" message
Test Skipping Late Streams (>15 minutes)
- Add a movie scheduled for 5 minutes from now
- Let prep complete, then stop the scheduler:
docker compose stop scheduler - Wait 20 minutes (past the 15-minute grace period)
- Restart and watch logs:
docker compose start scheduler docker compose logs -f scheduler - Job should be marked as 'skipped' with "more than 15 minutes late"
Test Skipping Unprepared Expired Jobs
- Add a movie scheduled for 5 minutes from now
- Stop the scheduler before prep starts:
docker compose stop scheduler - Wait 10 minutes (past both prep and streaming time)
- Restart and watch logs:
docker compose start scheduler docker compose logs -f scheduler - Job should be marked as 'skipped' (too late to prep)
Test Recovery from Crash During Processing
- Start processing a large video file
- Kill the scheduler during encoding:
docker compose kill scheduler - Restart:
docker compose start scheduler - Watch it retry the entire operation from the beginning
Testing Stream Watchdog
Test Stream Crash and Auto-Restart
-
Start a stream:
docker compose logs -f scheduler -
Find the streaming ffmpeg process and kill it:
# In another terminal docker compose exec scheduler ps aux | grep ffmpeg docker compose exec scheduler kill -9 <PID> -
Watch the scheduler logs - within 10 seconds it should:
- Detect the crash
- Calculate elapsed playback time
- Restart with seek to correct position
- Log: "Restarting stream at position X.Xs"
Test Stream Restart with Correct Position
- Start a test stream with a longer video
- Let it run for 2-3 minutes
- Kill the ffmpeg process
- Watch logs confirm restart with seek:
Restarting stream for job XXX at position 180.0s (attempt 2) - Use VLC to confirm playback resumed at correct position
Test Stream Completion Detection
- Use a short test video (1-2 minutes)
- Watch stream until completion
- Check logs - should show:
Stream completed successfully for job XXX - Check database - play_status should be 'done'
Test Retry Limit
- Break the RTMP server or use invalid RTMP URL
- Start a stream - it will crash immediately
- Watch the scheduler attempt 10 restarts
- After 10 attempts, should mark as 'failed':
Stream retry limit exceeded for job XXX ERROR: Stream failed after 10 restart attempts
Test Network Interruption Recovery
- Start a stream
- Stop the RTMP server:
docker compose stop rtmp - Watch stream fail and retry
- Restart RTMP:
docker compose start rtmp - Stream should resume at correct position
Testing Error Handling
Test Retry Logic
-
Stop the RTMP server:
docker compose stop rtmp -
Watch the scheduler handle the failure and retry:
docker compose logs -f scheduler -
Restart RTMP:
docker compose start rtmp
Test Missing File
- Add a movie entry in NocoDB with a title that doesn't match any file
- Set the Date to trigger immediately
- Watch the scheduler log the error and mark it as failed
Test Subtitle Generation Failure
- Add an invalid video file (corrupted or wrong format)
- Watch the scheduler attempt retries with exponential backoff
Viewing Results
Processed Videos
List final videos with burned-in subtitles:
docker run --rm -v scheduler_final_movies:/data alpine ls -lh /data
Raw Videos
List source videos:
docker run --rm -v scheduler_raw_movies:/data alpine ls -lh /data
RTMP Recordings (if enabled)
Recordings are saved to the rtmp_recordings volume:
docker run --rm -v scheduler_rtmp_recordings:/data alpine ls -lh /data/recordings
Customization
Change Test Video Scheduling
Edit init-data.sh before starting, around line 130:
"Date": (datetime.now() + timedelta(minutes=5)).isoformat(),
Change minutes=5 to adjust when the test movie is scheduled.
Use Different NocoDB Credentials
Edit docker-compose.yml:
environment:
NOCODB_EMAIL: "your@email.com"
NOCODB_PASSWORD: "yourpassword"
Test with Real NocoDB Instance
Comment out the nocodb and postgres services in docker-compose.yml and update the init service environment:
environment:
NOCODB_URL: "https://your-nocodb-instance.com"
NOCODB_EMAIL: "your@email.com"
NOCODB_PASSWORD: "yourpassword"
Troubleshooting
Services Won't Start
Check if ports are already in use:
lsof -i :8080 # NocoDB
lsof -i :1935 # RTMP
lsof -i :8081 # RTMP stats
Initialization Fails
View init logs:
docker compose logs init
Common issues:
- NocoDB not ready yet (increase wait time in init-data.sh)
- Network connectivity issues
- Insufficient disk space
Scheduler Not Processing
Check if it's running:
docker compose ps scheduler
View logs for errors:
docker compose logs scheduler
Restart if needed:
docker compose restart scheduler
Video Download Fails
The init script downloads Big Buck Bunny from Google's test video bucket. If this fails:
- Check internet connectivity
- Manually download and copy to raw_movies volume
- Or use your own test video
VAAPI Not Available
The Docker container runs without GPU access by default (CPU encoding fallback). To enable VAAPI:
Edit docker-compose.yml scheduler service:
scheduler:
devices:
- /dev/dri:/dev/dri
group_add:
- video
Cleanup
Stop Everything
docker compose down
Remove All Data (including volumes)
docker compose down -v
This removes:
- All containers
- All volumes (database, videos, recordings)
- Network
Keep Database, Remove Containers
docker compose down
# Volumes persist - next startup will reuse existing data
Architecture
┌─────────────┐
│ PostgreSQL │
└──────┬──────┘
│
┌──────▼──────┐ ┌─────────────┐
│ NocoDB │◄─────┤ Init │ Downloads test video
└──────┬──────┘ │ Container │ Creates test data
│ └─────────────┘
│
┌──────▼──────┐
│ Scheduler │ Reads from NocoDB
└──────┬──────┘ Generates subtitles
│ Encodes videos
│ Manages streaming
│
┌──────▼──────┐
│ RTMP Server │ Streams processed videos
└─────────────┘
Production Considerations
This test environment uses:
- Embedded PostgreSQL (fine for testing)
- Local volumes (fine for testing)
- Simple authentication (change for production)
- No SSL/TLS (add for production)
- CPU-only encoding (enable VAAPI for production)
For production deployment:
- Use external PostgreSQL database
- Configure proper authentication and secrets
- Enable SSL/TLS for NocoDB
- Mount persistent storage for videos
- Enable GPU acceleration (VAAPI)
- Set up proper monitoring and logging
- Configure backup for NocoDB database
Next Steps
Once you've tested the environment:
- Review the logs to understand the workflow
- Try adding your own movies
- Test error scenarios
- Adjust timing and configuration
- Deploy to production with proper setup
Support
For issues with:
- Scheduler code: Check
agent.pyand logs - Docker setup: Check
docker-compose.ymland service logs - NocoDB: Visit https://docs.nocodb.com
- RTMP streaming: Check nginx-rtmp documentation
License
This test environment is provided as-is for development and testing purposes.