84 lines
2.8 KiB
Python
84 lines
2.8 KiB
Python
from django.conf import settings
|
|
from django.core.files.base import ContentFile
|
|
from django.apps import apps
|
|
|
|
from celery import shared_task
|
|
from PIL import Image
|
|
from io import BytesIO
|
|
|
|
import subprocess
|
|
import tempfile
|
|
import pathlib
|
|
|
|
import uuid
|
|
|
|
|
|
@shared_task
|
|
def create_image_resolutions(image: "OriginalImage"):
|
|
OriginalImage = apps.get_model("tours", "OriginalImage")
|
|
|
|
if isinstance(image, (str, uuid.UUID)):
|
|
image = OriginalImage.objects.get(id=image)
|
|
|
|
with Image.open(image.file) as img:
|
|
resolutions = settings.QUACKSCAPE_CONTENT_RESOLUTIONS
|
|
|
|
for width, height in resolutions:
|
|
if width > image.width:
|
|
continue
|
|
|
|
if not image.resolutions.filter(width=width, height=height).exists():
|
|
img_resized = img.resize((width, height))
|
|
img_resized = img_resized.convert("RGB")
|
|
|
|
new_image_path = f"{width}x{height}_{image.file.name}"
|
|
|
|
bio = BytesIO()
|
|
img_resized.save(bio, format="JPEG")
|
|
|
|
resolution = image.resolutions.create(
|
|
file=ContentFile(BytesIO.getvalue(bio), name=new_image_path),
|
|
width=width,
|
|
height=height,
|
|
)
|
|
|
|
|
|
@shared_task
|
|
def create_video_resolutions(video: "OriginalVideo"):
|
|
OriginalVideo = apps.get_model("tours", "OriginalVideo")
|
|
|
|
if isinstance(video, (str, uuid.UUID)):
|
|
video = OriginalVideo.objects.get(id=video)
|
|
|
|
resolutions = settings.QUACKSCAPE_CONTENT_RESOLUTIONS
|
|
ffmpeg_options = settings.FFMPEG_OPTIONS[settings.FFMPEG_DEFAULT_OPTION]
|
|
|
|
for width, height in resolutions:
|
|
if width > video.width:
|
|
continue
|
|
|
|
if not video.resolutions.filter(width=width, height=height).exists():
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
input_path = pathlib.Path(tmpdir) / video.file.name
|
|
with open(input_path, "wb") as f:
|
|
f.write(video.file.read())
|
|
|
|
output_path = (
|
|
pathlib.Path(tmpdir) / f"{width}x{height}_{video.file.name}"
|
|
)
|
|
|
|
cmd = f"ffmpeg {ffmpeg_options['global_options']} {ffmpeg_options['input_options']} -i {input_path} -s {width}x{height} {ffmpeg_options['output_options']} {output_path}".split()
|
|
|
|
try:
|
|
subprocess.run(cmd, check=True)
|
|
except subprocess.CalledProcessError as e:
|
|
print(f"Error processing video {video_path} to {resolution}: {e}")
|
|
|
|
with open(output_path, "rb") as f:
|
|
resolution = video.resolutions.create(
|
|
file=ContentFile(f.read(), name=output_path.name),
|
|
width=width,
|
|
height=height,
|
|
)
|
|
|
|
output_path.unlink()
|