added video import and playback functionality
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
# app/utils/image_importer.py
|
||||
|
||||
from datetime import datetime
|
||||
import os, shutil, hashlib, time
|
||||
from PIL import Image
|
||||
@@ -7,6 +6,7 @@ import exifread
|
||||
import mimetypes
|
||||
import imagehash
|
||||
import uuid
|
||||
import subprocess
|
||||
|
||||
from app import db
|
||||
from app.models import ImageRecord
|
||||
@@ -29,7 +29,7 @@ def import_images_task(source_dir, dest_dir):
|
||||
|
||||
for root, _, files in os.walk(artist_path):
|
||||
for file in files:
|
||||
if file.lower().endswith(('.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff')):
|
||||
if file.lower().endswith(('.jpg', '.jpeg', '.jfif', '.png', '.gif', '.bmp', '.tiff', '.webp', '.mp4', '.mov')):
|
||||
full_path = os.path.join(root, file)
|
||||
filename = os.path.basename(full_path)
|
||||
|
||||
@@ -61,7 +61,12 @@ def import_images_task(source_dir, dest_dir):
|
||||
shutil.copy2(full_path, dest_path)
|
||||
|
||||
try:
|
||||
thumb_path = generate_thumbnail(dest_path)
|
||||
if dest_path.lower().endswith(('.mp4', '.mov')):
|
||||
thumb_filename = f"{uuid.uuid4().hex}.jpg"
|
||||
thumb_path = os.path.join("/images/thumbs", thumb_filename)
|
||||
thumb_path = generate_video_thumbnail(dest_path, thumb_path)
|
||||
else:
|
||||
thumb_path = generate_thumbnail(dest_path)
|
||||
except Exception as e:
|
||||
print(f"[WARN] Failed to generate thumbnail for {filename}: {e}")
|
||||
thumb_path = None
|
||||
@@ -128,6 +133,24 @@ def generate_thumbnail(image_path, size=(400, 400), overwrite=False):
|
||||
|
||||
return str(thumb_path)
|
||||
|
||||
def generate_video_thumbnail(video_path, output_path, time_position="00:00:01"):
|
||||
os.makedirs(os.path.dirname(output_path), exist_ok=True)
|
||||
|
||||
command = [
|
||||
"ffmpeg",
|
||||
"-i", video_path,
|
||||
"-ss", time_position,
|
||||
"-vframes", "1",
|
||||
"-vf", f"scale={THUMB_SIZE[0]}:-1",
|
||||
output_path
|
||||
]
|
||||
|
||||
try:
|
||||
subprocess.run(command, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
return output_path
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"[WARN] Failed to extract video thumbnail for {video_path}: {e}")
|
||||
return None
|
||||
|
||||
def calculate_hash(file_path):
|
||||
hash_func = hashlib.sha256()
|
||||
@@ -165,6 +188,29 @@ def extract_metadata(file_path):
|
||||
'taken_at': None
|
||||
}
|
||||
|
||||
metadata['file_size'] = os.path.getsize(file_path)
|
||||
ext = os.path.splitext(file_path)[1].lower()
|
||||
|
||||
if ext in ('.mp4', '.mov'):
|
||||
# Handle video dimensions using ffprobe
|
||||
try:
|
||||
import subprocess, json
|
||||
cmd = [
|
||||
"ffprobe", "-v", "error",
|
||||
"-select_streams", "v:0",
|
||||
"-show_entries", "stream=width,height",
|
||||
"-of", "json", file_path
|
||||
]
|
||||
result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, text=True)
|
||||
data = json.loads(result.stdout)
|
||||
stream = data.get("streams", [{}])[0]
|
||||
metadata['width'] = stream.get('width')
|
||||
metadata['height'] = stream.get('height')
|
||||
metadata['format'] = 'mp4'
|
||||
except Exception as e:
|
||||
print(f"[WARN] Failed to extract video metadata: {file_path} – {e}")
|
||||
return metadata
|
||||
|
||||
try:
|
||||
metadata['file_size'] = os.path.getsize(file_path)
|
||||
with Image.open(file_path) as img:
|
||||
|
||||
Reference in New Issue
Block a user