Update app.py
Browse files
app.py
CHANGED
@@ -13,6 +13,8 @@ import spaces
|
|
13 |
import gc
|
14 |
from huggingface_hub import hf_hub_download
|
15 |
import threading
|
|
|
|
|
16 |
|
17 |
# ZeroGPU-compatible imports
|
18 |
from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
|
@@ -1147,13 +1149,17 @@ class ProfessionalCartoonFilmGenerator:
|
|
1147 |
"scenes": [],
|
1148 |
"style": "Model loading failed"
|
1149 |
}
|
1150 |
-
return None, error_info, "β Failed to load AI models", [], []
|
1151 |
|
1152 |
# Step 1: Generate professional script
|
1153 |
print("π Creating professional script structure...")
|
1154 |
script_data = self.generate_professional_script(script)
|
1155 |
print(f"β
Script generated with {len(script_data['scenes'])} scenes")
|
1156 |
|
|
|
|
|
|
|
|
|
1157 |
# Step 2: Generate high-quality characters
|
1158 |
print("π Creating professional character designs...")
|
1159 |
character_images = self.generate_professional_character_images(script_data['characters'])
|
@@ -1193,10 +1199,22 @@ class ProfessionalCartoonFilmGenerator:
|
|
1193 |
char_files = list(character_images.values()) if character_images else []
|
1194 |
bg_files = list(background_images.values()) if background_images else []
|
1195 |
|
1196 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1197 |
else:
|
1198 |
print("β οΈ Video merging failed")
|
1199 |
-
return None, script_data, "β οΈ Video merging failed", [], []
|
1200 |
else:
|
1201 |
print("β No videos to merge - video generation failed")
|
1202 |
print("π Creating emergency fallback video...")
|
@@ -1211,12 +1229,25 @@ class ProfessionalCartoonFilmGenerator:
|
|
1211 |
download_info = self.create_download_url(emergency_video, "emergency_fallback_video")
|
1212 |
print(f"β
Emergency fallback video created")
|
1213 |
print(download_info)
|
1214 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1215 |
else:
|
1216 |
-
return None, script_data, "β No videos generated - all methods failed", [], []
|
1217 |
except Exception as e:
|
1218 |
print(f"β Emergency fallback also failed: {e}")
|
1219 |
-
return None, script_data, "β No videos generated - all methods failed", [], []
|
1220 |
|
1221 |
except Exception as e:
|
1222 |
print(f"β Generation failed: {e}")
|
@@ -1229,7 +1260,7 @@ class ProfessionalCartoonFilmGenerator:
|
|
1229 |
"scenes": [],
|
1230 |
"style": "Error occurred during generation"
|
1231 |
}
|
1232 |
-
return None, error_info, f"β Generation failed: {str(e)}", [], []
|
1233 |
|
1234 |
def _create_lightweight_animated_video(self, scene: Dict, character_images: Dict, background_images: Dict) -> str:
|
1235 |
"""Create lightweight animated video with character/background compositing"""
|
@@ -1402,6 +1433,67 @@ class ProfessionalCartoonFilmGenerator:
|
|
1402 |
print(f"β οΈ Character overlay failed: {e}")
|
1403 |
return background
|
1404 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1405 |
# Initialize professional generator
|
1406 |
generator = ProfessionalCartoonFilmGenerator()
|
1407 |
|
@@ -1416,7 +1508,7 @@ def create_professional_cartoon_film(script):
|
|
1416 |
"scenes": [],
|
1417 |
"style": "Please enter a script"
|
1418 |
}
|
1419 |
-
return None, empty_response, "β Please enter a script", [], []
|
1420 |
|
1421 |
# Check if another generation is in progress
|
1422 |
if not generation_lock.acquire(blocking=False):
|
@@ -1427,7 +1519,7 @@ def create_professional_cartoon_film(script):
|
|
1427 |
"scenes": [],
|
1428 |
"style": "Please wait for current generation to complete"
|
1429 |
}
|
1430 |
-
return None, busy_response, "β³ Generation already in progress - please wait", [], []
|
1431 |
|
1432 |
try:
|
1433 |
return generator.generate_professional_cartoon_film(script)
|
@@ -1476,6 +1568,8 @@ with gr.Blocks(
|
|
1476 |
- **Cinematic backgrounds** with professional lighting
|
1477 |
- **Advanced animation effects** based on scene mood
|
1478 |
- **4K video output** with 24fps cinematic quality
|
|
|
|
|
1479 |
|
1480 |
**π― Perfect for:**
|
1481 |
- Content creators seeking professional results
|
@@ -1486,10 +1580,11 @@ with gr.Blocks(
|
|
1486 |
---
|
1487 |
|
1488 |
**β οΈ Current Status:**
|
1489 |
-
- β
**Storage System:** Fixed for Hugging Face Spaces
|
|
|
|
|
1490 |
- β οΈ **FLUX Models:** Require authentication token (using Stable Diffusion fallback)
|
1491 |
- β οΈ **Open-Sora:** Using static video fallback for stability
|
1492 |
-
- β
**File Downloads:** Available through Gradio galleries below
|
1493 |
|
1494 |
**π‘ To unlock full FLUX quality:**
|
1495 |
1. Get token from [Hugging Face Settings](https://huggingface.co/settings/tokens)
|
@@ -1533,8 +1628,9 @@ The more details you provide about characters, setting, and emotion, the better
|
|
1533 |
**β οΈ Important Notes:**
|
1534 |
- Only **ONE generation at a time** - multiple clicks will be queued
|
1535 |
- **Processing takes 8-12 minutes** - please be patient
|
1536 |
-
- **Files
|
1537 |
-
- **
|
|
|
1538 |
""")
|
1539 |
|
1540 |
video_output = gr.Video(
|
@@ -1557,6 +1653,25 @@ The more details you provide about characters, setting, and emotion, the better
|
|
1557 |
allow_preview=True
|
1558 |
)
|
1559 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1560 |
status_output = gr.Textbox(
|
1561 |
label="π Generation Status",
|
1562 |
lines=3
|
@@ -1571,7 +1686,7 @@ The more details you provide about characters, setting, and emotion, the better
|
|
1571 |
generate_btn.click(
|
1572 |
fn=create_professional_cartoon_film,
|
1573 |
inputs=[script_input],
|
1574 |
-
outputs=[video_output, script_details, status_output, character_gallery, background_gallery],
|
1575 |
show_progress=True
|
1576 |
)
|
1577 |
|
|
|
13 |
import gc
|
14 |
from huggingface_hub import hf_hub_download
|
15 |
import threading
|
16 |
+
import datetime
|
17 |
+
import time
|
18 |
|
19 |
# ZeroGPU-compatible imports
|
20 |
from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
|
|
|
1149 |
"scenes": [],
|
1150 |
"style": "Model loading failed"
|
1151 |
}
|
1152 |
+
return None, error_info, "β Failed to load AI models", [], [], None, None, []
|
1153 |
|
1154 |
# Step 1: Generate professional script
|
1155 |
print("π Creating professional script structure...")
|
1156 |
script_data = self.generate_professional_script(script)
|
1157 |
print(f"β
Script generated with {len(script_data['scenes'])} scenes")
|
1158 |
|
1159 |
+
# Save script to file
|
1160 |
+
print("π Saving script to file...")
|
1161 |
+
script_file_path = self.save_script_to_file(script_data, script)
|
1162 |
+
|
1163 |
# Step 2: Generate high-quality characters
|
1164 |
print("π Creating professional character designs...")
|
1165 |
character_images = self.generate_professional_character_images(script_data['characters'])
|
|
|
1199 |
char_files = list(character_images.values()) if character_images else []
|
1200 |
bg_files = list(background_images.values()) if background_images else []
|
1201 |
|
1202 |
+
# Create download links for all files
|
1203 |
+
all_files = {}
|
1204 |
+
if script_file_path:
|
1205 |
+
all_files["script"] = script_file_path
|
1206 |
+
if final_video:
|
1207 |
+
all_files["video"] = final_video
|
1208 |
+
all_files.update(character_images)
|
1209 |
+
all_files.update(background_images)
|
1210 |
+
|
1211 |
+
download_links = self.create_download_links(all_files)
|
1212 |
+
script_file, video_file = self.get_download_files(all_files)
|
1213 |
+
|
1214 |
+
return final_video, script_data, f"β
Professional cartoon film generated successfully! ({file_size:.1f} MB)", char_files, bg_files, script_file, video_file, download_links
|
1215 |
else:
|
1216 |
print("β οΈ Video merging failed")
|
1217 |
+
return None, script_data, "β οΈ Video merging failed", [], [], None, None, []
|
1218 |
else:
|
1219 |
print("β No videos to merge - video generation failed")
|
1220 |
print("π Creating emergency fallback video...")
|
|
|
1229 |
download_info = self.create_download_url(emergency_video, "emergency_fallback_video")
|
1230 |
print(f"β
Emergency fallback video created")
|
1231 |
print(download_info)
|
1232 |
+
|
1233 |
+
# Create download links for emergency files
|
1234 |
+
all_files = {}
|
1235 |
+
if script_file_path:
|
1236 |
+
all_files["script"] = script_file_path
|
1237 |
+
if emergency_video:
|
1238 |
+
all_files["video"] = emergency_video
|
1239 |
+
all_files.update(character_images)
|
1240 |
+
all_files.update(background_images)
|
1241 |
+
|
1242 |
+
download_links = self.create_download_links(all_files)
|
1243 |
+
script_file, video_file = self.get_download_files(all_files)
|
1244 |
+
|
1245 |
+
return emergency_video, script_data, f"β οΈ Emergency fallback video created ({file_size:.1f} MB)", [], [], script_file, video_file, download_links
|
1246 |
else:
|
1247 |
+
return None, script_data, "β No videos generated - all methods failed", [], [], None, None, []
|
1248 |
except Exception as e:
|
1249 |
print(f"β Emergency fallback also failed: {e}")
|
1250 |
+
return None, script_data, "β No videos generated - all methods failed", [], [], None, None, []
|
1251 |
|
1252 |
except Exception as e:
|
1253 |
print(f"β Generation failed: {e}")
|
|
|
1260 |
"scenes": [],
|
1261 |
"style": "Error occurred during generation"
|
1262 |
}
|
1263 |
+
return None, error_info, f"β Generation failed: {str(e)}", [], [], None, None, []
|
1264 |
|
1265 |
def _create_lightweight_animated_video(self, scene: Dict, character_images: Dict, background_images: Dict) -> str:
|
1266 |
"""Create lightweight animated video with character/background compositing"""
|
|
|
1433 |
print(f"β οΈ Character overlay failed: {e}")
|
1434 |
return background
|
1435 |
|
1436 |
+
def save_script_to_file(self, script_data: Dict[str, Any], original_script: str) -> str:
|
1437 |
+
"""Save script data to a JSON file in tmp folder"""
|
1438 |
+
try:
|
1439 |
+
# Create a comprehensive script file with all data
|
1440 |
+
script_file_data = {
|
1441 |
+
"original_script": original_script,
|
1442 |
+
"generated_script": script_data,
|
1443 |
+
"timestamp": str(datetime.datetime.now()),
|
1444 |
+
"version": "1.0"
|
1445 |
+
}
|
1446 |
+
|
1447 |
+
# Save to tmp folder
|
1448 |
+
script_path = f"{self.output_dir}/cartoon_script_{int(time.time())}.json"
|
1449 |
+
|
1450 |
+
with open(script_path, 'w', encoding='utf-8') as f:
|
1451 |
+
json.dump(script_file_data, f, indent=2, ensure_ascii=False)
|
1452 |
+
|
1453 |
+
if os.path.exists(script_path):
|
1454 |
+
file_size = os.path.getsize(script_path) / 1024 # KB
|
1455 |
+
print(f"π Script saved: {script_path} ({file_size:.1f} KB)")
|
1456 |
+
return script_path
|
1457 |
+
else:
|
1458 |
+
print(f"β Failed to save script: {script_path}")
|
1459 |
+
return None
|
1460 |
+
|
1461 |
+
except Exception as e:
|
1462 |
+
print(f"β Error saving script: {e}")
|
1463 |
+
return None
|
1464 |
+
|
1465 |
+
def create_download_links(self, files_dict: Dict[str, str]) -> List[Dict[str, str]]:
|
1466 |
+
"""Create download links for files"""
|
1467 |
+
download_links = []
|
1468 |
+
|
1469 |
+
for file_type, file_path in files_dict.items():
|
1470 |
+
if os.path.exists(file_path):
|
1471 |
+
file_name = os.path.basename(file_path)
|
1472 |
+
file_size = os.path.getsize(file_path) / (1024*1024) # MB
|
1473 |
+
|
1474 |
+
download_links.append({
|
1475 |
+
"name": file_name,
|
1476 |
+
"path": file_path,
|
1477 |
+
"size": f"{file_size:.1f} MB",
|
1478 |
+
"type": file_type
|
1479 |
+
})
|
1480 |
+
|
1481 |
+
return download_links
|
1482 |
+
|
1483 |
+
def get_download_files(self, files_dict: Dict[str, str]) -> tuple:
|
1484 |
+
"""Get file objects for Gradio download components"""
|
1485 |
+
script_file = None
|
1486 |
+
video_file = None
|
1487 |
+
|
1488 |
+
for file_type, file_path in files_dict.items():
|
1489 |
+
if os.path.exists(file_path):
|
1490 |
+
if file_type == "script":
|
1491 |
+
script_file = file_path
|
1492 |
+
elif file_type == "video":
|
1493 |
+
video_file = file_path
|
1494 |
+
|
1495 |
+
return script_file, video_file
|
1496 |
+
|
1497 |
# Initialize professional generator
|
1498 |
generator = ProfessionalCartoonFilmGenerator()
|
1499 |
|
|
|
1508 |
"scenes": [],
|
1509 |
"style": "Please enter a script"
|
1510 |
}
|
1511 |
+
return None, empty_response, "β Please enter a script", [], [], None, None, []
|
1512 |
|
1513 |
# Check if another generation is in progress
|
1514 |
if not generation_lock.acquire(blocking=False):
|
|
|
1519 |
"scenes": [],
|
1520 |
"style": "Please wait for current generation to complete"
|
1521 |
}
|
1522 |
+
return None, busy_response, "β³ Generation already in progress - please wait", [], [], None, None, []
|
1523 |
|
1524 |
try:
|
1525 |
return generator.generate_professional_cartoon_film(script)
|
|
|
1568 |
- **Cinematic backgrounds** with professional lighting
|
1569 |
- **Advanced animation effects** based on scene mood
|
1570 |
- **4K video output** with 24fps cinematic quality
|
1571 |
+
- **π Script downloads** - Full JSON with story analysis
|
1572 |
+
- **π File management** - All files saved in /tmp with download links
|
1573 |
|
1574 |
**π― Perfect for:**
|
1575 |
- Content creators seeking professional results
|
|
|
1580 |
---
|
1581 |
|
1582 |
**β οΈ Current Status:**
|
1583 |
+
- β
**Storage System:** Fixed for Hugging Face Spaces (/tmp folder)
|
1584 |
+
- β
**Script Downloads:** JSON files with complete story analysis
|
1585 |
+
- β
**File Downloads:** Direct download buttons for all generated content
|
1586 |
- β οΈ **FLUX Models:** Require authentication token (using Stable Diffusion fallback)
|
1587 |
- β οΈ **Open-Sora:** Using static video fallback for stability
|
|
|
1588 |
|
1589 |
**π‘ To unlock full FLUX quality:**
|
1590 |
1. Get token from [Hugging Face Settings](https://huggingface.co/settings/tokens)
|
|
|
1628 |
**β οΈ Important Notes:**
|
1629 |
- Only **ONE generation at a time** - multiple clicks will be queued
|
1630 |
- **Processing takes 8-12 minutes** - please be patient
|
1631 |
+
- **Files saved in /tmp folder** with download links below
|
1632 |
+
- **Script saved as JSON** with full story analysis
|
1633 |
+
- **Images and videos** available for download
|
1634 |
""")
|
1635 |
|
1636 |
video_output = gr.Video(
|
|
|
1653 |
allow_preview=True
|
1654 |
)
|
1655 |
|
1656 |
+
# Add download buttons for scripts and other files
|
1657 |
+
script_download = gr.File(
|
1658 |
+
label="π Download Script (JSON)",
|
1659 |
+
file_types=[".json"],
|
1660 |
+
visible=True
|
1661 |
+
)
|
1662 |
+
|
1663 |
+
video_download = gr.File(
|
1664 |
+
label="π¬ Download Video (MP4)",
|
1665 |
+
file_types=[".mp4"],
|
1666 |
+
visible=True
|
1667 |
+
)
|
1668 |
+
|
1669 |
+
# Download links display
|
1670 |
+
download_links_output = gr.JSON(
|
1671 |
+
label="π₯ Download Links",
|
1672 |
+
visible=True
|
1673 |
+
)
|
1674 |
+
|
1675 |
status_output = gr.Textbox(
|
1676 |
label="π Generation Status",
|
1677 |
lines=3
|
|
|
1686 |
generate_btn.click(
|
1687 |
fn=create_professional_cartoon_film,
|
1688 |
inputs=[script_input],
|
1689 |
+
outputs=[video_output, script_details, status_output, character_gallery, background_gallery, script_download, video_download, download_links_output],
|
1690 |
show_progress=True
|
1691 |
)
|
1692 |
|