# YouTube Live Streamer - API Guide ## Architecture ``` ┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐ │ Vercel │ ──▶ │ Hugging Face │ ──▶ │ YouTube │ │ (Dashboard) │ API │ (Streaming API) │ RTMP │ (Live Stream) │ └─────────────────┘ └──────────────────┘ └─────────────────┘ │ ▼ ┌──────────────────┐ │ Google Drive │ │ (Videos) │ └──────────────────┘ ``` ## API Endpoints ### 1. Get Status ``` GET /api/status ``` **Response:** ```json { "is_running": true, "status": "streaming", "current_video": { "name": "video1.mp4", "id": "drive_file_id", "started_at": "2026-05-07T10:30:00" }, "videos_queue": [ {"id": "id1", "name": "video1.mp4"}, {"id": "id2", "name": "video2.mp4"} ], "videos_played": 5, "session_start": "2026-05-07T10:00:00", "session_end": "2026-05-07T16:00:00", "total_stream_time": 18000, "remaining_time_minutes": 120 } ``` ### 2. Start Stream ``` POST /api/start ``` **Body:** ```json { "duration_hours": 6.5, "shuffle": true, "youtube_stream_key": "xxxx-xxxx-xxxx" // optional, can use env var } ``` **Response:** ```json { "success": true, "message": "Stream started for 6.5 hours", "duration_hours": 6.5, "shuffle": true } ``` ### 3. Stop Stream ``` POST /api/stop ``` **Response:** ```json { "success": true, "message": "Stop signal sent. Stream will end after current video." } ``` ### 4. Get Available Videos ``` GET /api/videos ``` **Response:** ```json { "count": 10, "videos": [ {"id": "drive_id_1", "name": "video1.mp4"}, {"id": "drive_id_2", "name": "video2.mp4"} ] } ``` ## Environment Variables | Variable | Required | Default | Description | |----------|----------|---------|-------------| | `YOUTUBE_STREAM_KEY` | Yes | - | YouTube stream key | | `GOOGLE_OAUTH_CLIENT_ID` | Yes | - | Google OAuth client ID | | `GOOGLE_OAUTH_CLIENT_SECRET` | Yes | - | Google OAuth client secret | | `GOOGLE_DRIVE_REFRESH_TOKEN` | Yes | - | Drive refresh token | | `GOOGLE_DRIVE_FOLDER_ID` | Yes | - | Drive folder with videos | | `API_MODE` | No | `true` | Run as API server | | `SESSION_DURATION_HOURS` | No | `6` | Default stream duration | | `SHUFFLE_VIDEOS` | No | `true` | Shuffle video order | ## Frontend Example (React/Next.js) ```typescript const API_URL = process.env.NEXT_PUBLIC_STREAMER_API_URL; // Get status const status = await fetch(`${API_URL}/api/status`).then(r => r.json()); // Start stream await fetch(`${API_URL}/api/start`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ duration_hours: 6, shuffle: true }) }); // Stop stream await fetch(`${API_URL}/api/stop`, { method: 'POST' }); ``` ## Running Locally ```bash # Install dependencies pip install -r requirements.txt # Set environment variables export YOUTUBE_STREAM_KEY=xxxx export GOOGLE_OAUTH_CLIENT_ID=xxxx export GOOGLE_OAUTH_CLIENT_SECRET=xxxx export GOOGLE_DRIVE_REFRESH_TOKEN=xxxx export GOOGLE_DRIVE_FOLDER_ID=xxxx # Run API server python app.py # Or with explicit env API_MODE=true python app.py ``` ## Deployment ### Hugging Face Space 1. Create new Space with Docker SDK 2. Upload this code 3. Set environment variables in Space Settings 4. Space will auto-run API on port 7860 ### Vercel Frontend 1. Create Next.js app 2. Call HF API endpoints 3. Show live status, current video, queue 4. Add start/stop controls ## Important Notes - Stream stops gracefully after current video when `stop` is called - Videos are downloaded to `/tmp` and cleaned up after streaming - Each session shuffles videos (if enabled) for variety - Session auto-stops after `duration_hours` even if videos remain