Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -59,12 +59,24 @@ class ProfessionalCartoonFilmGenerator:
|
|
| 59 |
try:
|
| 60 |
# 1. FLUX pipeline for superior image generation
|
| 61 |
print("π¨ Loading FLUX pipeline...")
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
|
| 69 |
# Load cartoon/anime LoRA for character generation
|
| 70 |
print("π Loading cartoon LoRA models...")
|
|
@@ -109,13 +121,29 @@ class ProfessionalCartoonFilmGenerator:
|
|
| 109 |
# Fallback to Stable Diffusion
|
| 110 |
try:
|
| 111 |
from diffusers import StableDiffusionPipeline
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
|
| 120 |
# Enable memory optimizations
|
| 121 |
self.flux_pipe.enable_vae_slicing()
|
|
@@ -173,6 +201,25 @@ class ProfessionalCartoonFilmGenerator:
|
|
| 173 |
words = prompt.split()
|
| 174 |
return " ".join(words[:50])
|
| 175 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 176 |
def generate_professional_script(self, user_input: str) -> Dict[str, Any]:
|
| 177 |
"""Generate a professional cartoon script with detailed character development"""
|
| 178 |
|
|
@@ -507,7 +554,11 @@ class ProfessionalCartoonFilmGenerator:
|
|
| 507 |
char_path = f"{self.temp_dir}/character_{character['name'].replace(' ', '_')}.png"
|
| 508 |
image.save(char_path)
|
| 509 |
character_images[character['name']] = char_path
|
|
|
|
|
|
|
|
|
|
| 510 |
print(f"β
Generated high-quality character: {character['name']}")
|
|
|
|
| 511 |
|
| 512 |
self.clear_gpu_memory()
|
| 513 |
|
|
@@ -601,7 +652,11 @@ class ProfessionalCartoonFilmGenerator:
|
|
| 601 |
bg_path = f"{self.temp_dir}/background_scene_{scene['scene_number']}.png"
|
| 602 |
image.save(bg_path)
|
| 603 |
background_images[scene['scene_number']] = bg_path
|
|
|
|
|
|
|
|
|
|
| 604 |
print(f"β
Created cinematic background for scene {scene['scene_number']}")
|
|
|
|
| 605 |
|
| 606 |
self.clear_gpu_memory()
|
| 607 |
|
|
@@ -688,8 +743,11 @@ class ProfessionalCartoonFilmGenerator:
|
|
| 688 |
|
| 689 |
if video_path and os.path.exists(video_path):
|
| 690 |
scene_videos.append(video_path)
|
| 691 |
-
|
| 692 |
-
|
|
|
|
|
|
|
|
|
|
| 693 |
else:
|
| 694 |
print(f"β No video generated for scene {scene_num}")
|
| 695 |
|
|
@@ -1102,8 +1160,11 @@ class ProfessionalCartoonFilmGenerator:
|
|
| 1102 |
|
| 1103 |
if final_video and os.path.exists(final_video):
|
| 1104 |
file_size = os.path.getsize(final_video) / (1024*1024)
|
|
|
|
|
|
|
|
|
|
| 1105 |
print(f"β
Professional cartoon film generation complete!")
|
| 1106 |
-
print(
|
| 1107 |
return final_video, script_data, f"β
Professional cartoon film generated successfully! ({file_size:.1f} MB)"
|
| 1108 |
else:
|
| 1109 |
print("β οΈ Video merging failed")
|
|
@@ -1117,7 +1178,11 @@ class ProfessionalCartoonFilmGenerator:
|
|
| 1117 |
emergency_video = self._create_emergency_fallback_video(script_data)
|
| 1118 |
if emergency_video and os.path.exists(emergency_video):
|
| 1119 |
file_size = os.path.getsize(emergency_video) / (1024*1024)
|
| 1120 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1121 |
return emergency_video, script_data, f"β οΈ Emergency fallback video created ({file_size:.1f} MB)"
|
| 1122 |
else:
|
| 1123 |
return None, script_data, "β No videos generated - all methods failed"
|
|
|
|
| 59 |
try:
|
| 60 |
# 1. FLUX pipeline for superior image generation
|
| 61 |
print("π¨ Loading FLUX pipeline...")
|
| 62 |
+
try:
|
| 63 |
+
self.flux_pipe = FluxPipeline.from_pretrained(
|
| 64 |
+
"black-forest-labs/FLUX.1-dev",
|
| 65 |
+
torch_dtype=torch.bfloat16,
|
| 66 |
+
variant="fp16",
|
| 67 |
+
use_safetensors=True
|
| 68 |
+
).to(self.device)
|
| 69 |
+
except Exception as flux_error:
|
| 70 |
+
if "401" in str(flux_error) or "authentication" in str(flux_error).lower():
|
| 71 |
+
print("π FLUX authentication failed - model requires Hugging Face token")
|
| 72 |
+
print("π‘ To use FLUX, you need to:")
|
| 73 |
+
print(" 1. Get a Hugging Face token from https://huggingface.co/settings/tokens")
|
| 74 |
+
print(" 2. Accept the FLUX model license at https://huggingface.co/black-forest-labs/FLUX.1-dev")
|
| 75 |
+
print(" 3. Set your token: huggingface-cli login")
|
| 76 |
+
print("π Falling back to Stable Diffusion...")
|
| 77 |
+
raise flux_error
|
| 78 |
+
else:
|
| 79 |
+
raise flux_error
|
| 80 |
|
| 81 |
# Load cartoon/anime LoRA for character generation
|
| 82 |
print("π Loading cartoon LoRA models...")
|
|
|
|
| 121 |
# Fallback to Stable Diffusion
|
| 122 |
try:
|
| 123 |
from diffusers import StableDiffusionPipeline
|
| 124 |
+
print("π Loading Stable Diffusion fallback model...")
|
| 125 |
+
|
| 126 |
+
# Try a more accessible model first
|
| 127 |
+
try:
|
| 128 |
+
self.flux_pipe = StableDiffusionPipeline.from_pretrained(
|
| 129 |
+
"CompVis/stable-diffusion-v1-4",
|
| 130 |
+
torch_dtype=torch.float16,
|
| 131 |
+
use_safetensors=True,
|
| 132 |
+
safety_checker=None,
|
| 133 |
+
requires_safety_checker=False
|
| 134 |
+
).to(self.device)
|
| 135 |
+
print("β
Loaded Stable Diffusion v1.4")
|
| 136 |
+
except Exception as sd_error:
|
| 137 |
+
print(f"β οΈ SD v1.4 failed: {sd_error}")
|
| 138 |
+
# Try the original model
|
| 139 |
+
self.flux_pipe = StableDiffusionPipeline.from_pretrained(
|
| 140 |
+
"runwayml/stable-diffusion-v1-5",
|
| 141 |
+
torch_dtype=torch.float16,
|
| 142 |
+
use_safetensors=True,
|
| 143 |
+
safety_checker=None,
|
| 144 |
+
requires_safety_checker=False
|
| 145 |
+
).to(self.device)
|
| 146 |
+
print("β
Loaded Stable Diffusion v1.5")
|
| 147 |
|
| 148 |
# Enable memory optimizations
|
| 149 |
self.flux_pipe.enable_vae_slicing()
|
|
|
|
| 201 |
words = prompt.split()
|
| 202 |
return " ".join(words[:50])
|
| 203 |
|
| 204 |
+
def create_download_url(self, file_path: str, file_type: str = "file") -> str:
|
| 205 |
+
"""Create a download URL for generated content"""
|
| 206 |
+
try:
|
| 207 |
+
# For Hugging Face Spaces, we can create a simple download link
|
| 208 |
+
# In a real deployment, this would point to your actual file hosting service
|
| 209 |
+
file_name = os.path.basename(file_path)
|
| 210 |
+
|
| 211 |
+
# Create a simple download URL format
|
| 212 |
+
# In production, replace this with your actual file hosting URL
|
| 213 |
+
download_url = f"π₯ Download {file_type}: {file_name}"
|
| 214 |
+
download_url += f"\n π Local path: {file_path}"
|
| 215 |
+
download_url += f"\n π File size: {os.path.getsize(file_path) / (1024*1024):.1f} MB"
|
| 216 |
+
|
| 217 |
+
return download_url
|
| 218 |
+
|
| 219 |
+
except Exception as e:
|
| 220 |
+
print(f"β οΈ Failed to create download URL: {e}")
|
| 221 |
+
return f"π File saved: {file_path}"
|
| 222 |
+
|
| 223 |
def generate_professional_script(self, user_input: str) -> Dict[str, Any]:
|
| 224 |
"""Generate a professional cartoon script with detailed character development"""
|
| 225 |
|
|
|
|
| 554 |
char_path = f"{self.temp_dir}/character_{character['name'].replace(' ', '_')}.png"
|
| 555 |
image.save(char_path)
|
| 556 |
character_images[character['name']] = char_path
|
| 557 |
+
|
| 558 |
+
# Create download URL for character
|
| 559 |
+
download_info = self.create_download_url(char_path, f"character_{character['name']}")
|
| 560 |
print(f"β
Generated high-quality character: {character['name']}")
|
| 561 |
+
print(download_info)
|
| 562 |
|
| 563 |
self.clear_gpu_memory()
|
| 564 |
|
|
|
|
| 652 |
bg_path = f"{self.temp_dir}/background_scene_{scene['scene_number']}.png"
|
| 653 |
image.save(bg_path)
|
| 654 |
background_images[scene['scene_number']] = bg_path
|
| 655 |
+
|
| 656 |
+
# Create download URL for background
|
| 657 |
+
download_info = self.create_download_url(bg_path, f"background_scene_{scene['scene_number']}")
|
| 658 |
print(f"β
Created cinematic background for scene {scene['scene_number']}")
|
| 659 |
+
print(download_info)
|
| 660 |
|
| 661 |
self.clear_gpu_memory()
|
| 662 |
|
|
|
|
| 743 |
|
| 744 |
if video_path and os.path.exists(video_path):
|
| 745 |
scene_videos.append(video_path)
|
| 746 |
+
|
| 747 |
+
# Create download URL for video
|
| 748 |
+
download_info = self.create_download_url(video_path, f"video_scene_{scene_num}")
|
| 749 |
+
print(f"β
Generated professional video for scene {scene_num}")
|
| 750 |
+
print(download_info)
|
| 751 |
else:
|
| 752 |
print(f"β No video generated for scene {scene_num}")
|
| 753 |
|
|
|
|
| 1160 |
|
| 1161 |
if final_video and os.path.exists(final_video):
|
| 1162 |
file_size = os.path.getsize(final_video) / (1024*1024)
|
| 1163 |
+
|
| 1164 |
+
# Create download URL for final video
|
| 1165 |
+
download_info = self.create_download_url(final_video, "final_cartoon_film")
|
| 1166 |
print(f"β
Professional cartoon film generation complete!")
|
| 1167 |
+
print(download_info)
|
| 1168 |
return final_video, script_data, f"β
Professional cartoon film generated successfully! ({file_size:.1f} MB)"
|
| 1169 |
else:
|
| 1170 |
print("β οΈ Video merging failed")
|
|
|
|
| 1178 |
emergency_video = self._create_emergency_fallback_video(script_data)
|
| 1179 |
if emergency_video and os.path.exists(emergency_video):
|
| 1180 |
file_size = os.path.getsize(emergency_video) / (1024*1024)
|
| 1181 |
+
|
| 1182 |
+
# Create download URL for emergency video
|
| 1183 |
+
download_info = self.create_download_url(emergency_video, "emergency_fallback_video")
|
| 1184 |
+
print(f"β
Emergency fallback video created")
|
| 1185 |
+
print(download_info)
|
| 1186 |
return emergency_video, script_data, f"β οΈ Emergency fallback video created ({file_size:.1f} MB)"
|
| 1187 |
else:
|
| 1188 |
return None, script_data, "β No videos generated - all methods failed"
|