You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

55 lines
1.6 KiB
Python

2 months ago
import os, hashlib, subprocess
from concurrent.futures import ThreadPoolExecutor
# pull constants from app.py
from app import THUMB_DIR, THUMB_WIDTH, FF_QUALITY
def _hashed_thumb_path(video_id: str):
h = hashlib.md5(video_id.encode()).hexdigest()
sub1, sub2 = h[:2], h[2:4]
path = os.path.join(THUMB_DIR, sub1, sub2)
os.makedirs(path, exist_ok=True)
return os.path.join(path, f"{video_id}.webp")
def _gen_thumb_cmd(src: str, dest: str):
return [
"ffmpeg", "-y", "-loglevel", "error",
"-ss", "0", "-i", src,
"-vframes", "1",
"-vf", f"thumbnail,scale={THUMB_WIDTH}:-1",
"-q:v", FF_QUALITY,
dest
]
def generate_thumbnails_for_videos(videos):
tasks = []
for v in videos:
video_id = v.get("video_id")
2 months ago
filepath = v.get("filepath")
thumb_path = _hashed_thumb_path(video_id)
if not filepath:
print(f"⚠️ Skipping {video_id}: missing filepath")
continue
if not os.path.exists(filepath):
print(f"⚠️ Skipping {video_id}: file not found → {filepath}")
continue
if not os.path.exists(thumb_path):
tasks.append((filepath, thumb_path))
v["thumbnail"] = thumb_path
if tasks:
with ThreadPoolExecutor(max_workers=os.cpu_count() * 2) as exe:
2 months ago
list(exe.map(
lambda t: subprocess.run(
_gen_thumb_cmd(*t),
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL
),
tasks
))