Update Docker configuration, enhance error handling, and improve logging

- Added health check to the camera management API service in docker-compose.yml for better container reliability.
- Updated installation scripts in Dockerfile to check for existing dependencies before installation, improving efficiency.
- Enhanced error handling in the USDAVisionSystem class to allow partial operation if some components fail to start, preventing immediate shutdown.
- Improved logging throughout the application, including more detailed error messages and critical error handling in the main loop.
- Refactored WebSocketManager and CameraMonitor classes to use debug logging for connection events, reducing log noise.
This commit is contained in:
salirezav
2025-12-03 17:23:31 -05:00
parent 2bce817b4e
commit 933d4417a5
30 changed files with 4314 additions and 220 deletions

View File

@@ -1,4 +1,4 @@
import React, { useRef, useEffect } from 'react'
import React, { useRef, useEffect, useState } from 'react'
import videojs from 'video.js'
import 'video.js/dist/video-js.css'
@@ -12,20 +12,43 @@ type Props = {
export const VideoModal: React.FC<Props> = ({ fileId, onClose }) => {
const videoRef = useRef<HTMLVideoElement>(null)
const playerRef = useRef<any>(null)
// Use transcoded endpoint for browser compatibility (H.264)
const src = fileId ? `${BASE}/videos/stream-transcoded?file_id=${encodeURIComponent(fileId)}` : null
const [useTranscoded, setUseTranscoded] = useState(false)
// Try regular stream first (works for downloads), fallback to transcoded if needed
const regularSrc = fileId ? `${BASE}/videos/stream?file_id=${encodeURIComponent(fileId)}` : null
const transcodedSrc = fileId ? `${BASE}/videos/stream-transcoded?file_id=${encodeURIComponent(fileId)}` : null
const src = useTranscoded ? transcodedSrc : regularSrc
// Reset transcoded flag when fileId changes
useEffect(() => {
setUseTranscoded(false)
}, [fileId])
useEffect(() => {
if (!fileId || !src || !videoRef.current) return
// Dispose existing player if any
if (playerRef.current) {
playerRef.current.dispose()
playerRef.current = null
}
// Initialize Video.js player
const player = videojs(videoRef.current, {
controls: true,
autoplay: true,
preload: 'auto',
autoplay: false, // Don't autoplay - let user control
preload: 'metadata', // Load metadata first, then data on play
fluid: false, // Disable fluid mode to respect container boundaries
responsive: false, // Disable responsive mode to prevent overflow
playbackRates: [0.5, 1, 1.25, 1.5, 2],
html5: {
vhs: {
overrideNative: true
},
nativeVideoTracks: false,
nativeAudioTracks: false,
nativeTextTracks: false
},
sources: [
{
src: src,
@@ -36,14 +59,38 @@ export const VideoModal: React.FC<Props> = ({ fileId, onClose }) => {
playerRef.current = player
player.on('error', () => {
let errorHandled = false
const handleError = () => {
const error = player.error()
if (error) {
if (error && !errorHandled) {
errorHandled = true
console.error('Video.js error:', error)
console.error('Error code:', error.code)
console.error('Error message:', error.message)
// If regular stream fails and we haven't tried transcoded yet, switch to transcoded
if (!useTranscoded && transcodedSrc) {
console.log('Switching to transcoded endpoint...')
// Clear the player ref to prevent double disposal
playerRef.current = null
// Dispose player before switching
try {
player.dispose()
} catch (e) {
// Ignore disposal errors
}
// Use setTimeout to allow cleanup to complete before switching
setTimeout(() => {
setUseTranscoded(true)
}, 100)
} else {
// Show user-friendly error
console.error('Video playback failed. Please try downloading the video instead.')
}
}
})
}
player.on('error', handleError)
player.on('loadedmetadata', () => {
console.log('Video metadata loaded, duration:', player.duration())
@@ -60,7 +107,7 @@ export const VideoModal: React.FC<Props> = ({ fileId, onClose }) => {
playerRef.current = null
}
}
}, [fileId, src])
}, [fileId, src, useTranscoded, transcodedSrc])
if (!fileId || !src) return null
@@ -127,7 +174,7 @@ export const VideoModal: React.FC<Props> = ({ fileId, onClose }) => {
ref={videoRef}
className="video-js vjs-default-skin w-full h-full"
playsInline
key={fileId}
key={`${fileId}-${useTranscoded ? 'transcoded' : 'regular'}`}
/>
</div>
</div>