Files
usda-vision/management-dashboard-web-app/API Documentations/docs/WEB_AI_AGENT_VIDEO_INTEGRATION.md

7.8 KiB
Executable File

🤖 Web AI Agent - Video Integration Guide

This guide provides the essential information for integrating USDA Vision Camera video streaming into your web application.

🎯 Quick Start

Video Streaming Status: READY

  • Progressive streaming implemented - Videos play in browsers (no download)
  • 86 MP4 files available - All properly indexed and streamable
  • HTTP range requests supported - Seeking and progressive playback work
  • Memory efficient - 8KB chunked delivery

🚀 API Endpoints

Base URL

http://localhost:8000

1. List Available Videos

GET /videos/?camera_name={camera}&limit={limit}

Example:

curl "http://localhost:8000/videos/?camera_name=camera1&limit=10"

Response:

{
  "videos": [
    {
      "file_id": "camera1_auto_blower_separator_20250805_123329.mp4",
      "camera_name": "camera1",
      "file_size_bytes": 1072014489,
      "format": "mp4",
      "status": "completed",
      "is_streamable": true,
      "created_at": "2025-08-05T12:43:12.631210"
    }
  ],
  "total_count": 1
}

2. Stream Video (Progressive)

GET /videos/{file_id}/stream

Example:

curl "http://localhost:8000/videos/camera1_auto_blower_separator_20250805_123329.mp4/stream"

Features:

  • Progressive streaming (8KB chunks)
  • HTTP range requests (206 Partial Content)
  • Browser compatible (HTML5 video)
  • Seeking support
  • No authentication required

3. Get Video Thumbnail

GET /videos/{file_id}/thumbnail?timestamp={seconds}&width={px}&height={px}

Example:

curl "http://localhost:8000/videos/camera1_auto_blower_separator_20250805_123329.mp4/thumbnail?timestamp=5.0&width=320&height=240"

🌐 Web Integration

HTML5 Video Player

<video controls width="100%" preload="metadata">
  <source src="http://localhost:8000/videos/{file_id}/stream" type="video/mp4">
  Your browser does not support video playback.
</video>

React Component

function VideoPlayer({ fileId, width = "100%" }) {
  const streamUrl = `http://localhost:8000/videos/${fileId}/stream`;
  const thumbnailUrl = `http://localhost:8000/videos/${fileId}/thumbnail`;
  
  return (
    <video 
      controls 
      width={width}
      preload="metadata"
      poster={thumbnailUrl}
      style={{ maxWidth: '800px', borderRadius: '8px' }}
    >
      <source src={streamUrl} type="video/mp4" />
      Your browser does not support video playback.
    </video>
  );
}

Video List Component

function VideoList({ cameraName = null, limit = 20 }) {
  const [videos, setVideos] = useState([]);
  const [loading, setLoading] = useState(true);
  
  useEffect(() => {
    const params = new URLSearchParams();
    if (cameraName) params.append('camera_name', cameraName);
    params.append('limit', limit.toString());
    
    fetch(`http://localhost:8000/videos/?${params}`)
      .then(response => response.json())
      .then(data => {
        // Filter only streamable MP4 videos
        const streamableVideos = data.videos.filter(
          v => v.format === 'mp4' && v.is_streamable
        );
        setVideos(streamableVideos);
        setLoading(false);
      })
      .catch(error => {
        console.error('Error loading videos:', error);
        setLoading(false);
      });
  }, [cameraName, limit]);
  
  if (loading) return <div>Loading videos...</div>;
  
  return (
    <div className="video-grid">
      {videos.map(video => (
        <div key={video.file_id} className="video-card">
          <h3>{video.file_id}</h3>
          <p>Camera: {video.camera_name}</p>
          <p>Size: {(video.file_size_bytes / 1024 / 1024).toFixed(1)} MB</p>
          <VideoPlayer fileId={video.file_id} width="100%" />
        </div>
      ))}
    </div>
  );
}

📊 Available Data

Current Video Inventory

  • Total Videos: 161 files
  • MP4 Files: 86 (all streamable )
  • AVI Files: 75 (legacy format, not prioritized)
  • Cameras: camera1, camera2
  • Date Range: July 29 - August 5, 2025

Video File Naming Convention

{camera}_{trigger}_{machine}_{YYYYMMDD}_{HHMMSS}.mp4

Examples:

  • camera1_auto_blower_separator_20250805_123329.mp4
  • camera2_auto_vibratory_conveyor_20250805_123042.mp4
  • 20250804_161305_manual_camera1_2025-08-04T20-13-09-634Z.mp4

Machine Triggers

  • auto_blower_separator - Automatic recording triggered by blower separator
  • auto_vibratory_conveyor - Automatic recording triggered by vibratory conveyor
  • manual - Manual recording initiated by user

🔧 Technical Details

Streaming Implementation

  • Method: FastAPI StreamingResponse with async generators
  • Chunk Size: 8KB for optimal performance
  • Range Requests: Full HTTP/1.1 range request support
  • Status Codes: 200 (full), 206 (partial), 404 (not found)
  • CORS: Enabled for all origins
  • Caching: Server-side byte-range caching

Browser Compatibility

  • Chrome/Chromium
  • Firefox
  • Safari
  • Edge
  • Mobile browsers

Performance Characteristics

  • Memory Usage: Low (8KB chunks, no large file loading)
  • Seeking: Instant (HTTP range requests)
  • Startup Time: Fast (metadata preload)
  • Bandwidth: Adaptive (only downloads viewed portions)

🛠️ Error Handling

Common Scenarios

// Check if video is streamable
const checkVideo = async (fileId) => {
  try {
    const response = await fetch(`http://localhost:8000/videos/${fileId}`);
    const video = await response.json();
    
    if (!video.is_streamable) {
      console.warn(`Video ${fileId} is not streamable`);
      return false;
    }
    
    return true;
  } catch (error) {
    console.error(`Error checking video ${fileId}:`, error);
    return false;
  }
};

// Handle video loading errors
const VideoPlayerWithErrorHandling = ({ fileId }) => {
  const [error, setError] = useState(null);
  
  const handleError = (e) => {
    console.error('Video playback error:', e);
    setError('Failed to load video. Please try again.');
  };
  
  if (error) {
    return <div className="error"> {error}</div>;
  }
  
  return (
    <video 
      controls 
      onError={handleError}
      src={`http://localhost:8000/videos/${fileId}/stream`}
    />
  );
};

HTTP Status Codes

  • 200 OK - Video streaming successfully
  • 206 Partial Content - Range request successful
  • 404 Not Found - Video not found or not streamable
  • 416 Range Not Satisfiable - Invalid range request
  • 500 Internal Server Error - Server error reading video

🔐 Security Notes

Current Configuration

  • Authentication: None (open access)
  • CORS: Enabled for all origins
  • Network: Designed for internal use
  • HTTPS: Not required (HTTP works)

For Production Use

Consider implementing:

  • Authentication/authorization
  • Rate limiting
  • HTTPS/TLS encryption
  • Network access controls

🧪 Testing

Quick Test

# Test video listing
curl "http://localhost:8000/videos/?limit=5"

# Test video streaming
curl -I "http://localhost:8000/videos/camera1_auto_blower_separator_20250805_123329.mp4/stream"

# Test range request
curl -H "Range: bytes=0-1023" "http://localhost:8000/videos/camera1_auto_blower_separator_20250805_123329.mp4/stream" -o test_chunk.mp4

Browser Test

Open: file:///home/alireza/USDA-vision-cameras/test_video_streaming.html

📞 Support

Service Management

# Restart video service
sudo systemctl restart usda-vision-camera

# Check service status
sudo systemctl status usda-vision-camera

# View logs
sudo journalctl -u usda-vision-camera -f

Health Check

curl http://localhost:8000/health

Ready for Integration: The video streaming system is fully operational and ready for web application integration. All MP4 files are streamable with progressive playback support.