Enhance media API with video file validation and Docker configuration update

- Added a function to check if video files are complete and valid using ffprobe, preventing errors during thumbnail generation.
- Updated thumbnail generation logic to skip incomplete or corrupted files, improving robustness.
- Modified docker-compose.yml to include a restart policy for the camera management API service, ensuring better container reliability.
This commit is contained in:
salirezav
2025-12-03 14:56:18 -05:00
parent d454c64168
commit 2bce817b4e
2 changed files with 41 additions and 2 deletions

View File

@@ -5,6 +5,7 @@ services:
context: ./camera-management-api
dockerfile: Dockerfile
working_dir: /app
restart: unless-stopped # Automatically restart container if it fails or exits
volumes:
- ./camera-management-api:/app
- /mnt/nfs_share:/mnt/nfs_share

View File

@@ -138,13 +138,45 @@ def file_id_from_path(p: pathlib.Path) -> str:
def path_from_file_id(fid: str) -> pathlib.Path:
rel = urllib.parse.unquote_plus(fid)
# Handle double-encoding: decode until no more changes
rel = fid
while True:
decoded = urllib.parse.unquote_plus(rel)
if decoded == rel:
break
rel = decoded
p = (MEDIA_DIR / rel).resolve()
if not p.is_file() or MEDIA_DIR not in p.parents:
raise HTTPException(status_code=404, detail="Video not found")
return p
def is_video_file_complete(p: pathlib.Path) -> bool:
"""
Check if video file is complete and valid using ffprobe.
Returns True if file is complete and can be processed, False otherwise.
"""
try:
# Quick check: use ffprobe to verify file is valid
cmd = [
"ffprobe",
"-v", "error",
"-show_entries", "format=duration",
"-of", "default=noprint_wrappers=1:nokey=1",
str(p)
]
result = subprocess.run(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
timeout=5
)
# If ffprobe succeeds, file is valid
return result.returncode == 0
except (subprocess.TimeoutExpired, subprocess.CalledProcessError, Exception):
return False
def generate_thumbnail_background(p: pathlib.Path, width: int = 320, height: int = 180) -> bool:
"""
Generate thumbnail in background (non-blocking, doesn't raise exceptions).
@@ -188,13 +220,19 @@ def generate_thumbnail_background(p: pathlib.Path, width: int = 320, height: int
except OSError:
return False
# Check if video file is complete and valid before attempting thumbnail generation
# This prevents errors with incomplete/corrupted files
if not is_video_file_complete(p):
return False # File is incomplete or corrupted, skip
# Try to generate thumbnail - try 1s first, then 0s if that fails
for seek_time in [1.0, 0.0]:
cmd = [
"ffmpeg", "-y",
"-ss", str(seek_time),
"-i", str(p),
"-vframes", "1",
"-frames:v", "1",
"-update", "1", # Required for single image output with image2 muxer
"-vf", f"scale='min({width},iw)':-2,scale={width}:{height}:force_original_aspect_ratio=decrease,pad={width}:{height}:(ow-iw)/2:(oh-ih)/2",
str(out)
]