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"
|