# ๐ŸŽฌ Video Streaming Module The USDA Vision Camera System now includes a modular video streaming system that provides YouTube-like video playback capabilities for your React web application. ## ๐ŸŒŸ Features - **HTTP Range Request Support** - Enables seeking and progressive download - **Native MP4 Support** - Direct streaming of MP4 files with automatic AVI conversion - **Intelligent Caching** - Optimized streaming performance - **Thumbnail Generation** - Extract preview images from videos - **Modular Architecture** - Clean separation of concerns - **No Authentication Required** - Open access for internal network use - **CORS Enabled** - Ready for web browser integration ## ๐Ÿ—๏ธ Architecture The video module follows clean architecture principles: ``` usda_vision_system/video/ โ”œโ”€โ”€ domain/ # Business logic (pure Python) โ”œโ”€โ”€ infrastructure/ # External dependencies (OpenCV, FFmpeg) โ”œโ”€โ”€ application/ # Use cases and orchestration โ”œโ”€โ”€ presentation/ # HTTP controllers and API routes โ””โ”€โ”€ integration.py # Dependency injection and composition ``` ## ๐Ÿš€ API Endpoints ### List Videos ```http GET /videos/ ``` **Query Parameters:** - `camera_name` (optional): Filter by camera name - `start_date` (optional): Filter videos created after this date (ISO format: 2025-08-04T14:30:22) - `end_date` (optional): Filter videos created before this date (ISO format: 2025-08-04T14:30:22) - `limit` (optional): Maximum results (default: 50, max: 1000) - `include_metadata` (optional): Include video metadata (default: false) **Example Request:** ```bash curl "http://localhost:8000/videos/?camera_name=camera1&include_metadata=true&limit=10" ``` **Response:** ```json { "videos": [ { "file_id": "camera1_auto_blower_separator_20250804_143022.mp4", "camera_name": "camera1", "filename": "camera1_auto_blower_separator_20250804_143022.mp4", "file_size_bytes": 31457280, "format": "mp4", "status": "completed", "created_at": "2025-08-04T14:30:22", "start_time": "2025-08-04T14:30:22", "end_time": "2025-08-04T14:32:22", "machine_trigger": "blower_separator", "is_streamable": true, "needs_conversion": false, "metadata": { "duration_seconds": 120.5, "width": 1920, "height": 1080, "fps": 30.0, "codec": "mp4v", "bitrate": 5000000, "aspect_ratio": 1.777 } } ], "total_count": 1 } ``` ### Stream Video ```http GET /videos/{file_id}/stream ``` **Headers:** - `Range: bytes=0-1023` (optional): Request specific byte range for seeking **Example Requests:** ```bash # Stream entire video curl http://localhost:8000/videos/camera1_recording_20250804_143022.avi/stream # Stream specific byte range (for seeking) curl -H "Range: bytes=0-1023" \ http://localhost:8000/videos/camera1_recording_20250804_143022.avi/stream ``` **Response Headers:** - `Accept-Ranges: bytes` - `Content-Length: {size}` - `Content-Range: bytes {start}-{end}/{total}` (for range requests) - `Cache-Control: public, max-age=3600` - `Content-Type: video/mp4` or `video/x-msvideo` **Features:** - โœ… **HTTP Range Requests**: Enables video seeking and progressive download - โœ… **Partial Content**: Returns 206 status for range requests - โœ… **Format Conversion**: Automatic AVI to MP4 conversion for web compatibility - โœ… **Intelligent Caching**: Byte-range caching for optimal performance - โœ… **CORS Enabled**: Ready for web browser integration ### Get Video Info ```http GET /videos/{file_id} ``` **Example Request:** ```bash curl http://localhost:8000/videos/camera1_recording_20250804_143022.avi ``` **Response includes complete metadata:** ```json { "file_id": "camera1_recording_20250804_143022.avi", "camera_name": "camera1", "filename": "camera1_recording_20250804_143022.avi", "file_size_bytes": 52428800, "format": "avi", "status": "completed", "created_at": "2025-08-04T14:30:22", "start_time": "2025-08-04T14:30:22", "end_time": "2025-08-04T14:32:22", "machine_trigger": "vibratory_conveyor", "is_streamable": true, "needs_conversion": true, "metadata": { "duration_seconds": 120.5, "width": 1920, "height": 1080, "fps": 30.0, "codec": "XVID", "bitrate": 5000000, "aspect_ratio": 1.777 } } ``` ### Get Thumbnail ```http GET /videos/{file_id}/thumbnail?timestamp=5.0&width=320&height=240 ``` **Query Parameters:** - `timestamp` (optional): Time position in seconds to extract thumbnail from (default: 1.0) - `width` (optional): Thumbnail width in pixels (default: 320) - `height` (optional): Thumbnail height in pixels (default: 240) **Example Request:** ```bash curl "http://localhost:8000/videos/camera1_recording_20250804_143022.avi/thumbnail?timestamp=5.0&width=320&height=240" \ --output thumbnail.jpg ``` **Response**: JPEG image data with caching headers - `Content-Type: image/jpeg` - `Cache-Control: public, max-age=3600` ### Streaming Info ```http GET /videos/{file_id}/info ``` **Example Request:** ```bash curl http://localhost:8000/videos/camera1_recording_20250804_143022.avi/info ``` **Response**: Technical streaming details ```json { "file_id": "camera1_recording_20250804_143022.avi", "file_size_bytes": 52428800, "content_type": "video/x-msvideo", "supports_range_requests": true, "chunk_size_bytes": 262144 } ``` ### Video Validation ```http POST /videos/{file_id}/validate ``` **Example Request:** ```bash curl -X POST http://localhost:8000/videos/camera1_recording_20250804_143022.avi/validate ``` **Response**: Validation status ```json { "file_id": "camera1_recording_20250804_143022.avi", "is_valid": true } ``` ### Cache Management ```http POST /videos/{file_id}/cache/invalidate ``` **Example Request:** ```bash curl -X POST http://localhost:8000/videos/camera1_recording_20250804_143022.avi/cache/invalidate ``` **Response**: Cache invalidation status ```json { "file_id": "camera1_recording_20250804_143022.avi", "cache_invalidated": true } ``` ### Admin: Cache Cleanup ```http POST /admin/videos/cache/cleanup?max_size_mb=100 ``` **Example Request:** ```bash curl -X POST "http://localhost:8000/admin/videos/cache/cleanup?max_size_mb=100" ``` **Response**: Cache cleanup results ```json { "cache_cleaned": true, "entries_removed": 15, "max_size_mb": 100 } ``` ## ๐ŸŒ React Integration ### Basic Video Player ```jsx function VideoPlayer({ fileId }) { return ( ); } ``` ### Advanced Player with Thumbnail ```jsx function VideoPlayerWithThumbnail({ fileId }) { const [thumbnail, setThumbnail] = useState(null); useEffect(() => { fetch(`${API_BASE_URL}/videos/${fileId}/thumbnail`) .then(response => response.blob()) .then(blob => setThumbnail(URL.createObjectURL(blob))); }, [fileId]); return ( ); } ``` ### Video List Component ```jsx function VideoList({ cameraName }) { const [videos, setVideos] = useState([]); useEffect(() => { const params = new URLSearchParams(); if (cameraName) params.append('camera_name', cameraName); params.append('include_metadata', 'true'); fetch(`${API_BASE_URL}/videos/?${params}`) .then(response => response.json()) .then(data => setVideos(data.videos)); }, [cameraName]); return (
{videos.map(video => ( ))}
); } ``` ## ๐Ÿ”ง Configuration The video module is automatically initialized when the API server starts. Configuration options: ```python # In your API server initialization video_module = create_video_module( config=config, storage_manager=storage_manager, enable_caching=True, # Enable streaming cache enable_conversion=True # Enable format conversion ) ``` ### Configuration Parameters - **`enable_caching`**: Enable/disable intelligent byte-range caching (default: True) - **`cache_size_mb`**: Maximum cache size in MB (default: 100) - **`cache_max_age_minutes`**: Cache entry expiration time (default: 30) - **`enable_conversion`**: Enable/disable automatic AVI to MP4 conversion (default: True) - **`conversion_quality`**: Video conversion quality: "low", "medium", "high" (default: "medium") ### System Requirements - **OpenCV**: Required for thumbnail generation and metadata extraction - **FFmpeg**: Optional, for video format conversion (graceful fallback if not available) - **Storage**: Sufficient disk space for video files and cache - **Memory**: Recommended 2GB+ RAM for caching and video processing ## ๐Ÿ” Authentication & Security ### Current Security Model **โš ๏ธ IMPORTANT: No authentication is currently implemented.** - **Open Access**: All video streaming endpoints are publicly accessible - **CORS Policy**: Currently set to allow all origins (`allow_origins=["*"]`) - **Network Security**: Designed for internal network use only - **No API Keys**: No authentication tokens or API keys required - **No Rate Limiting**: No request rate limiting currently implemented ### Security Considerations for Production #### For Internal Network Deployment ```bash # Current configuration is suitable for: # - Internal corporate networks # - Isolated network segments # - Development and testing environments ``` #### For External Access (Recommendations) If you need to expose the video streaming API externally, consider implementing: 1. **Authentication Layer** ```python # Example: Add JWT authentication from fastapi import Depends, HTTPException from fastapi.security import HTTPBearer security = HTTPBearer() async def verify_token(token: str = Depends(security)): # Implement token verification logic pass ``` 2. **CORS Configuration** ```python # Restrict CORS to specific domains app.add_middleware( CORSMiddleware, allow_origins=["https://yourdomain.com"], allow_credentials=True, allow_methods=["GET", "POST"], allow_headers=["*"] ) ``` 3. **Rate Limiting** ```python # Example: Add rate limiting from slowapi import Limiter limiter = Limiter(key_func=get_remote_address) @app.get("/videos/") @limiter.limit("10/minute") async def list_videos(): pass ``` 4. **Network Security** - Use HTTPS/TLS for encrypted communication - Implement firewall rules to restrict access - Consider VPN access for remote users - Use reverse proxy (nginx) for additional security ### Access Control Summary ``` โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ Current Access Model โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ Authentication: โŒ None โ”‚ โ”‚ Authorization: โŒ None โ”‚ โ”‚ CORS: โœ… Enabled (all origins) โ”‚ โ”‚ Rate Limiting: โŒ None โ”‚ โ”‚ HTTPS: โš ๏ธ Depends on deployment โ”‚ โ”‚ Network Security: โš ๏ธ Firewall/VPN recommended โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ ``` ## ๐Ÿ“Š Performance - **Caching**: Intelligent byte-range caching reduces disk I/O - **Adaptive Chunking**: Optimal chunk sizes based on file size - **Range Requests**: Only download needed portions - **Format Conversion**: Automatic conversion to web-compatible formats ## ๐Ÿ› ๏ธ Service Management ### Restart Service ```bash sudo systemctl restart usda-vision-camera ``` ### Check Status ```bash # Check video module status curl http://localhost:8000/system/video-module # Check available videos curl http://localhost:8000/videos/ ``` ### Logs ```bash sudo journalctl -u usda-vision-camera -f ``` ## ๐Ÿงช Testing Run the video module tests: ```bash cd /home/alireza/USDA-vision-cameras PYTHONPATH=/home/alireza/USDA-vision-cameras python tests/test_video_module.py ``` ## ๐Ÿ” Troubleshooting ### Video Not Playing 1. **Check if file exists**: `GET /videos/{file_id}` ```bash curl http://localhost:8000/videos/camera1_recording_20250804_143022.avi ``` 2. **Verify streaming info**: `GET /videos/{file_id}/info` ```bash curl http://localhost:8000/videos/camera1_recording_20250804_143022.avi/info ``` 3. **Test direct stream**: `GET /videos/{file_id}/stream` ```bash curl -I http://localhost:8000/videos/camera1_recording_20250804_143022.avi/stream ``` 4. **Validate video file**: `POST /videos/{file_id}/validate` ```bash curl -X POST http://localhost:8000/videos/camera1_recording_20250804_143022.avi/validate ``` ### Performance Issues 1. **Check cache status**: Clean up cache if needed ```bash curl -X POST "http://localhost:8000/admin/videos/cache/cleanup?max_size_mb=100" ``` 2. **Monitor system resources**: Check CPU, memory, and disk usage 3. **Adjust cache size**: Modify configuration parameters 4. **Invalidate specific cache**: For updated files ```bash curl -X POST http://localhost:8000/videos/{file_id}/cache/invalidate ``` ### Format Issues - **AVI files**: Automatically converted to MP4 for web compatibility - **Conversion requires FFmpeg**: Optional dependency with graceful fallback - **Supported formats**: AVI (with conversion), MP4 (native), WebM (native) ### Common HTTP Status Codes - **200**: Success - Video streamed successfully - **206**: Partial Content - Range request successful - **404**: Not Found - Video file doesn't exist or isn't streamable - **416**: Range Not Satisfiable - Invalid range request - **500**: Internal Server Error - Failed to read video data or generate thumbnail ### Browser Compatibility - **Chrome/Chromium**: Full support for MP4 and range requests - **Firefox**: Full support for MP4 and range requests - **Safari**: Full support for MP4 and range requests - **Edge**: Full support for MP4 and range requests - **Mobile browsers**: Generally good support for MP4 streaming ### Error Scenarios and Solutions #### Video File Issues ```bash # Problem: Video not found (404) curl http://localhost:8000/videos/nonexistent_video.mp4 # Response: {"detail": "Video nonexistent_video.mp4 not found"} # Solution: Verify file_id exists using list endpoint # Problem: Video not streamable curl http://localhost:8000/videos/corrupted_video.avi/stream # Response: {"detail": "Video corrupted_video.avi not found or not streamable"} # Solution: Use validation endpoint to check file integrity ``` #### Range Request Issues ```bash # Problem: Invalid range request (416) curl -H "Range: bytes=999999999-" http://localhost:8000/videos/small_video.mp4/stream # Response: {"detail": "Invalid range request: Range exceeds file size"} # Solution: Check file size first using /info endpoint # Problem: Malformed range header curl -H "Range: invalid-range" http://localhost:8000/videos/video.mp4/stream # Response: {"detail": "Invalid range request: Malformed range header"} # Solution: Use proper range format: "bytes=start-end" ``` #### Thumbnail Generation Issues ```bash # Problem: Thumbnail generation failed (404) curl http://localhost:8000/videos/audio_only.mp4/thumbnail # Response: {"detail": "Could not generate thumbnail for audio_only.mp4"} # Solution: Verify video has visual content and is not audio-only # Problem: Invalid timestamp curl "http://localhost:8000/videos/short_video.mp4/thumbnail?timestamp=999" # Response: Returns thumbnail from last available frame # Solution: Check video duration first using metadata ``` #### System Resource Issues ```bash # Problem: Cache full or system overloaded (500) curl http://localhost:8000/videos/large_video.mp4/stream # Response: {"detail": "Failed to read video data"} # Solution: Clean cache or wait for system resources curl -X POST "http://localhost:8000/admin/videos/cache/cleanup?max_size_mb=50" ``` ### Debugging Workflow ```bash # Step 1: Check system health curl http://localhost:8000/health # Step 2: Verify video exists and get info curl http://localhost:8000/videos/your_video_id # Step 3: Check streaming capabilities curl http://localhost:8000/videos/your_video_id/info # Step 4: Validate video file curl -X POST http://localhost:8000/videos/your_video_id/validate # Step 5: Test basic streaming curl -I http://localhost:8000/videos/your_video_id/stream # Step 6: Test range request curl -I -H "Range: bytes=0-1023" http://localhost:8000/videos/your_video_id/stream ``` ### Performance Monitoring ```bash # Monitor cache usage curl -X POST "http://localhost:8000/admin/videos/cache/cleanup?max_size_mb=100" # Check system resources curl http://localhost:8000/system/status # Monitor video module status curl http://localhost:8000/videos/ | jq '.total_count' ``` ## ๐ŸŽฏ Next Steps 1. **Restart the usda-vision-camera service** to enable video streaming 2. **Test the endpoints** using curl or your browser 3. **Integrate with your React app** using the provided examples 4. **Monitor performance** and adjust caching as needed The video streaming system is now ready for production use! ๐Ÿš€