Files
LeDiscord/backend/utils/video_utils.py
2025-08-27 18:34:38 +02:00

95 lines
2.5 KiB
Python
Executable File

import cv2
import os
from pathlib import Path
from PIL import Image
import tempfile
def generate_video_thumbnail(video_path: str, output_path: str, frame_time: float = 1.0) -> bool:
"""
Generate a thumbnail from a video at a specific time.
Args:
video_path: Path to the video file
output_path: Path where to save the thumbnail
frame_time: Time in seconds to extract the frame (default: 1 second)
Returns:
bool: True if successful, False otherwise
"""
try:
# Open video file
cap = cv2.VideoCapture(video_path)
if not cap.isOpened():
return False
# Get video properties
fps = cap.get(cv2.CAP_PROP_FPS)
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
if total_frames == 0:
return False
# Calculate frame number for the specified time
frame_number = min(int(fps * frame_time), total_frames - 1)
# Set position to the specified frame
cap.set(cv2.CAP_PROP_POS_FRAMES, frame_number)
# Read the frame
ret, frame = cap.read()
if not ret:
return False
# Convert BGR to RGB
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# Convert to PIL Image
pil_image = Image.fromarray(frame_rgb)
# Resize to thumbnail size (400x400)
pil_image.thumbnail((400, 400), Image.Resampling.LANCZOS)
# Save thumbnail
pil_image.save(output_path, "JPEG", quality=85, optimize=True)
# Release video capture
cap.release()
return True
except Exception as e:
print(f"Error generating thumbnail: {e}")
return False
def get_video_duration(video_path: str) -> float:
"""
Get the duration of a video file in seconds.
Args:
video_path: Path to the video file
Returns:
float: Duration in seconds, or 0 if error
"""
try:
cap = cv2.VideoCapture(video_path)
if not cap.isOpened():
return 0
fps = cap.get(cv2.CAP_PROP_FPS)
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
cap.release()
if fps > 0 and total_frames > 0:
return total_frames / fps
return 0
except Exception as e:
print(f"Error getting video duration: {e}")
return 0