Files
usda-vision/API Documentations/docs/VIDEO_STREAMING.md
Alireza Vaezi 1aaac68edd feat(video): Implement MP4 format support across frontend and backend
- Updated VideoModal to display web compatibility status for video formats.
- Enhanced VideoPlayer to dynamically fetch video MIME types and handle MP4 streaming.
- Introduced video file utilities for better handling of video formats and MIME types.
- Modified CameraConfig interface to include new video recording settings (format, codec, quality).
- Created comprehensive documentation for MP4 format integration and frontend implementation.
- Ensured backward compatibility with existing AVI files while promoting MP4 as the preferred format.
- Added validation and error handling for video format configurations.
2025-08-04 16:21:22 -04:00

6.1 KiB

🎬 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

🏗️ 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

GET /videos/

Query Parameters:

  • camera_name - Filter by camera
  • start_date - Filter by date range
  • end_date - Filter by date range
  • limit - Maximum results (default: 50)
  • include_metadata - Include video metadata

Response:

{
  "videos": [
    {
      "file_id": "camera1_recording_20250804_143022.mp4",
      "camera_name": "camera1",
      "filename": "camera1_recording_20250804_143022.mp4",
      "file_size_bytes": 31457280,
      "format": "mp4",
      "status": "completed",
      "created_at": "2025-08-04T14:30:22",
      "is_streamable": true,
      "needs_conversion": true
    }
  ],
  "total_count": 1
}

Stream Video

GET /videos/{file_id}/stream

Headers:

  • Range: bytes=0-1023 - Request specific byte range

Features:

  • Supports HTTP range requests for seeking
  • Returns 206 Partial Content for range requests
  • Automatic format conversion for web compatibility
  • Intelligent caching for performance

Get Video Info

GET /videos/{file_id}

Response includes metadata:

{
  "file_id": "camera1_recording_20250804_143022.avi",
  "metadata": {
    "duration_seconds": 120.5,
    "width": 1920,
    "height": 1080,
    "fps": 30.0,
    "codec": "XVID",
    "aspect_ratio": 1.777
  }
}

Get Thumbnail

GET /videos/{file_id}/thumbnail?timestamp=5.0&width=320&height=240

Returns JPEG thumbnail image.

Streaming Info

GET /videos/{file_id}/info

Returns technical streaming details:

{
  "file_id": "camera1_recording_20250804_143022.avi",
  "file_size_bytes": 52428800,
  "content_type": "video/x-msvideo",
  "supports_range_requests": true,
  "chunk_size_bytes": 262144
}

🌐 React Integration

Basic Video Player

function VideoPlayer({ fileId }) {
  return (
    <video controls width="100%">
      <source 
        src={`${API_BASE_URL}/videos/${fileId}/stream`} 
        type="video/mp4" 
      />
      Your browser does not support video playback.
    </video>
  );
}

Advanced Player with Thumbnail

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 controls width="100%" poster={thumbnail}>
      <source 
        src={`${API_BASE_URL}/videos/${fileId}/stream`} 
        type="video/mp4" 
      />
    </video>
  );
}

Video List Component

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 (
    <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
      {videos.map(video => (
        <VideoCard key={video.file_id} video={video} />
      ))}
    </div>
  );
}

🔧 Configuration

The video module is automatically initialized when the API server starts. Configuration options:

# 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
)

📊 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

sudo systemctl restart usda-vision-camera

Check Status

# Check video module status
curl http://localhost:8000/system/video-module

# Check available videos
curl http://localhost:8000/videos/

Logs

sudo journalctl -u usda-vision-camera -f

🧪 Testing

Run the video module tests:

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}
  2. Verify streaming info: GET /videos/{file_id}/info
  3. Test direct stream: GET /videos/{file_id}/stream

Performance Issues

  1. Check cache status: GET /admin/videos/cache/cleanup
  2. Monitor system resources
  3. Adjust cache size in configuration

Format Issues

  • AVI files are automatically converted to MP4 for web compatibility
  • Conversion requires FFmpeg (optional, graceful fallback)

🎯 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! 🚀