Commit ·
fba411c
1
Parent(s): 3d4874c
Fix fact_creator: correct API signatures (NVIDIA/CF/Pexels), ensure 9:16 video output
Browse files
modules/fact_image/services/fact_creator.py
CHANGED
|
@@ -179,32 +179,40 @@ class FactCreator:
|
|
| 179 |
full_prompt = IMAGE_SYSTEM_PROMPT.format(image_prompt=job["image_prompt"])
|
| 180 |
|
| 181 |
if job["model"] == ImageModel.nvidia and self.nvidia:
|
|
|
|
| 182 |
self.nvidia.generate_and_save(
|
| 183 |
prompt=full_prompt,
|
| 184 |
-
output_path=image_path
|
| 185 |
-
width=self.TARGET_WIDTH,
|
| 186 |
-
height=self.TARGET_HEIGHT
|
| 187 |
)
|
| 188 |
elif job["model"] == ImageModel.cloudflare and self.cloudflare:
|
|
|
|
| 189 |
self.cloudflare.generate_and_save(
|
| 190 |
prompt=full_prompt,
|
| 191 |
output_path=image_path,
|
| 192 |
-
width=
|
| 193 |
-
height=
|
| 194 |
)
|
| 195 |
elif job["model"] == ImageModel.pexels and self.pexels:
|
| 196 |
-
# Pexels
|
| 197 |
-
self.pexels.
|
| 198 |
query=job["image_prompt"],
|
| 199 |
-
output_path=image_path,
|
| 200 |
orientation="portrait"
|
| 201 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 202 |
else:
|
| 203 |
# Fallback to any available client
|
| 204 |
if self.nvidia:
|
| 205 |
-
self.nvidia.generate_and_save(full_prompt, image_path
|
| 206 |
elif self.cloudflare:
|
| 207 |
-
self.cloudflare.generate_and_save(full_prompt, image_path,
|
| 208 |
else:
|
| 209 |
raise Exception("No image generation client available!")
|
| 210 |
|
|
@@ -265,12 +273,15 @@ class FactCreator:
|
|
| 265 |
shutil.rmtree(temp_dir, ignore_errors=True)
|
| 266 |
|
| 267 |
async def _create_video(self, image_path: Path, output_path: Path, duration: int):
|
| 268 |
-
"""Create video from single image with fade effects"""
|
| 269 |
from moviepy.editor import ImageClip
|
| 270 |
|
| 271 |
# Create image clip
|
| 272 |
clip = ImageClip(str(image_path)).set_duration(duration)
|
| 273 |
|
|
|
|
|
|
|
|
|
|
| 274 |
# Add fade in/out
|
| 275 |
clip = clip.fadein(self.FADE_DURATION)
|
| 276 |
clip = clip.fadeout(self.FADE_DURATION)
|
|
|
|
| 179 |
full_prompt = IMAGE_SYSTEM_PROMPT.format(image_prompt=job["image_prompt"])
|
| 180 |
|
| 181 |
if job["model"] == ImageModel.nvidia and self.nvidia:
|
| 182 |
+
# NVIDIA: uses aspect_ratio "9:16" internally (no width/height params)
|
| 183 |
self.nvidia.generate_and_save(
|
| 184 |
prompt=full_prompt,
|
| 185 |
+
output_path=image_path
|
|
|
|
|
|
|
| 186 |
)
|
| 187 |
elif job["model"] == ImageModel.cloudflare and self.cloudflare:
|
| 188 |
+
# Cloudflare: supports width/height (1080x1920)
|
| 189 |
self.cloudflare.generate_and_save(
|
| 190 |
prompt=full_prompt,
|
| 191 |
output_path=image_path,
|
| 192 |
+
width=1080,
|
| 193 |
+
height=1920
|
| 194 |
)
|
| 195 |
elif job["model"] == ImageModel.pexels and self.pexels:
|
| 196 |
+
# Pexels: find_photo returns {id, url}, then download
|
| 197 |
+
photo = self.pexels.find_photo(
|
| 198 |
query=job["image_prompt"],
|
|
|
|
| 199 |
orientation="portrait"
|
| 200 |
)
|
| 201 |
+
if photo and photo.get("url"):
|
| 202 |
+
import requests
|
| 203 |
+
response = requests.get(photo["url"], timeout=30)
|
| 204 |
+
response.raise_for_status()
|
| 205 |
+
image_path.parent.mkdir(parents=True, exist_ok=True)
|
| 206 |
+
image_path.write_bytes(response.content)
|
| 207 |
+
logger.info(f"Downloaded Pexels photo ID {photo['id']}")
|
| 208 |
+
else:
|
| 209 |
+
raise Exception("No suitable Pexels photo found")
|
| 210 |
else:
|
| 211 |
# Fallback to any available client
|
| 212 |
if self.nvidia:
|
| 213 |
+
self.nvidia.generate_and_save(full_prompt, image_path)
|
| 214 |
elif self.cloudflare:
|
| 215 |
+
self.cloudflare.generate_and_save(full_prompt, image_path, width=1080, height=1920)
|
| 216 |
else:
|
| 217 |
raise Exception("No image generation client available!")
|
| 218 |
|
|
|
|
| 273 |
shutil.rmtree(temp_dir, ignore_errors=True)
|
| 274 |
|
| 275 |
async def _create_video(self, image_path: Path, output_path: Path, duration: int):
|
| 276 |
+
"""Create video from single image with fade effects (9:16 = 1080x1920)"""
|
| 277 |
from moviepy.editor import ImageClip
|
| 278 |
|
| 279 |
# Create image clip
|
| 280 |
clip = ImageClip(str(image_path)).set_duration(duration)
|
| 281 |
|
| 282 |
+
# Ensure 9:16 aspect ratio (1080x1920)
|
| 283 |
+
clip = clip.resize((self.TARGET_WIDTH, self.TARGET_HEIGHT))
|
| 284 |
+
|
| 285 |
# Add fade in/out
|
| 286 |
clip = clip.fadein(self.FADE_DURATION)
|
| 287 |
clip = clip.fadeout(self.FADE_DURATION)
|