initial commit
This commit is contained in:
53
backend/app/services/thumbnails.py
Normal file
53
backend/app/services/thumbnails.py
Normal file
@@ -0,0 +1,53 @@
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from PIL import Image
|
||||
from app.config import THUMBNAIL_DIR
|
||||
|
||||
THUMB_SIZE = (400, 400)
|
||||
|
||||
|
||||
def thumbnail_path(media_id: int) -> Path:
|
||||
return THUMBNAIL_DIR / f"{media_id}.jpg"
|
||||
|
||||
|
||||
def generate_image_thumbnail(src: Path, dest: Path) -> None:
|
||||
with Image.open(src) as img:
|
||||
img.thumbnail(THUMB_SIZE)
|
||||
img = img.convert("RGB")
|
||||
img.save(dest, "JPEG", quality=85)
|
||||
|
||||
|
||||
def generate_video_thumbnail(src: Path, dest: Path) -> None:
|
||||
# Extract frame at 10% of duration
|
||||
subprocess.run(
|
||||
[
|
||||
"ffprobe", "-v", "error", "-show_entries", "format=duration",
|
||||
"-of", "default=noprint_wrappers=1:nokey=1", str(src),
|
||||
],
|
||||
capture_output=True, text=True, check=False,
|
||||
)
|
||||
subprocess.run(
|
||||
[
|
||||
"ffmpeg", "-y", "-ss", "00:00:05", "-i", str(src),
|
||||
"-vframes", "1", "-vf", f"scale={THUMB_SIZE[0]}:-1",
|
||||
str(dest),
|
||||
],
|
||||
capture_output=True, check=False,
|
||||
)
|
||||
|
||||
|
||||
def get_or_create_thumbnail(media_id: int, abs_path: str, media_type: str) -> Path | None:
|
||||
dest = thumbnail_path(media_id)
|
||||
if dest.exists():
|
||||
return dest
|
||||
src = Path(abs_path)
|
||||
if not src.exists():
|
||||
return None
|
||||
try:
|
||||
if media_type == "image":
|
||||
generate_image_thumbnail(src, dest)
|
||||
else:
|
||||
generate_video_thumbnail(src, dest)
|
||||
return dest if dest.exists() else None
|
||||
except Exception:
|
||||
return None
|
||||
Reference in New Issue
Block a user