shaheerawan3 commited on
Commit
25fc568
·
verified ·
1 Parent(s): 303853e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +91 -421
app.py CHANGED
@@ -21,43 +21,6 @@ from typing import Optional, List, Dict, Tuple
21
  from bs4 import BeautifulSoup
22
  import requests
23
  from io import BytesIO
24
- import docx
25
- import PyPDF2
26
- import pptx
27
- import cv2
28
- from PIL import ImageEnhance
29
-
30
- class FileProcessor:
31
- @staticmethod
32
- def read_txt(file):
33
- return file.read().decode('utf-8')
34
-
35
- @staticmethod
36
- def read_pdf(file):
37
- pdf_reader = PyPDF2.PdfReader(file)
38
- text = ""
39
- for page in pdf_reader.pages:
40
- text += page.extract_text() + "\n"
41
- return text
42
-
43
- @staticmethod
44
- def read_docx(file):
45
- doc = docx.Document(file)
46
- text = ""
47
- for para in doc.paragraphs:
48
- text += para.text + "\n"
49
- return text
50
-
51
- @staticmethod
52
- def read_pptx(file):
53
- prs = pptx.Presentation(file)
54
- text = ""
55
- for slide in prs.slides:
56
- for shape in slide.shapes:
57
- if hasattr(shape, "text"):
58
- text += shape.text + "\n"
59
- return text
60
-
61
 
62
  class ImageScraper:
63
  def __init__(self):
@@ -833,28 +796,26 @@ class EnhancedVideoGenerator:
833
  return f"{hours:02d}:{minutes:02d}:{secs:02d},{msecs:03d}"
834
 
835
  def create_video(self, script: str, style: str, duration: int, output_path: str, selected_images: List[str]) -> str:
836
- """Create video with enhanced features and proper error handling"""
837
  try:
838
  # Initialize progress tracking
839
  progress_bar = st.progress(0)
840
  status_text = st.empty()
841
 
842
- # Create output directory if it doesn't exist
843
- os.makedirs(os.path.dirname(output_path), exist_ok=True)
844
-
845
- # Validate inputs and paths
846
- if not output_path:
847
- raise ValueError("Output path cannot be empty")
848
  if not selected_images:
849
- raise ValueError("No images selected")
850
-
851
- # Generate voice-over with progress tracking
 
 
 
852
  status_text.text("Creating voice-over...")
853
- audio = self.generate_voice_over(script)
854
  progress_bar.progress(20)
855
 
856
- # Process images with effects
857
- status_text.text("Processing images with effects...")
858
  processed_images = []
859
 
860
  for img_url in selected_images:
@@ -863,30 +824,19 @@ class EnhancedVideoGenerator:
863
  response.raise_for_status()
864
  img = Image.open(BytesIO(response.content))
865
  img = img.convert('RGB')
866
-
867
- # Apply image effects based on style
868
- if style == "Creative":
869
- # Add creative effects
870
- enhancer = ImageEnhance.Contrast(img)
871
- img = enhancer.enhance(1.2)
872
- enhancer = ImageEnhance.Brightness(img)
873
- img = enhancer.enhance(1.1)
874
- elif style == "Professional":
875
- # Add professional effects
876
- enhancer = ImageEnhance.Sharpness(img)
877
- img = enhancer.enhance(1.3)
878
-
879
  img = img.resize((1920, 1080), Image.Resampling.LANCZOS)
880
  processed_images.append(img)
881
-
882
  except Exception as e:
883
  print(f"Error processing image {img_url}: {e}")
884
  continue
885
 
 
 
 
886
  progress_bar.progress(40)
887
 
888
- # Generate frames with transitions
889
- status_text.text("Creating frames with transitions...")
890
  frames = []
891
  fps = 30
892
  total_frames = int(duration * fps)
@@ -895,36 +845,24 @@ class EnhancedVideoGenerator:
895
  # Convert images to numpy arrays
896
  image_arrays = [np.array(img) for img in processed_images]
897
 
898
- # Add transition effects
899
  frame_count = 0
900
  for idx, img_array in enumerate(image_arrays):
901
- # Calculate frames for this image
902
  if idx == len(image_arrays) - 1:
903
  n_frames = total_frames - frame_count
904
  else:
905
  n_frames = min(frames_per_image, total_frames - frame_count)
906
 
907
- # Add effects and transitions
908
- for frame_idx in range(n_frames):
909
- # Apply fade in/out effect
910
- alpha = 1.0
911
- if frame_idx < 15: # Fade in
912
- alpha = frame_idx / 15
913
- elif frame_idx > n_frames - 15: # Fade out
914
- alpha = (n_frames - frame_idx) / 15
915
-
916
- frame = img_array * alpha
917
- frames.append(frame.astype(np.uint8))
918
  frame_count += 1
919
-
920
- # Update progress
921
- progress = int(40 + (frame_count / total_frames * 30))
922
- progress_bar.progress(progress)
923
 
924
- # Add transition to next image
925
  if idx < len(image_arrays) - 1:
926
  next_img_array = image_arrays[idx + 1]
927
- transition_frames = 15
928
  for t in range(transition_frames):
929
  if frame_count < total_frames:
930
  alpha = t / transition_frames
@@ -941,7 +879,7 @@ class EnhancedVideoGenerator:
941
  status_text.text("Compiling video...")
942
  clip = ImageSequenceClip(frames, fps=fps)
943
 
944
- # Add audio with proper synchronization
945
  audio_duration = audio.duration
946
  video_duration = len(frames) / fps
947
 
@@ -952,37 +890,27 @@ class EnhancedVideoGenerator:
952
 
953
  final_clip = clip.set_audio(audio)
954
 
955
- # Write video with progress caching
956
- status_text.text("Saving video...")
957
- cache_dir = os.path.join(os.path.dirname(output_path), ".cache")
958
- os.makedirs(cache_dir, exist_ok=True)
 
 
959
 
 
 
960
  try:
961
  final_clip.write_videofile(
962
  output_path,
963
  fps=fps,
964
  codec='libx264',
965
  audio_codec='aac',
966
- ffmpeg_params=['-pix_fmt', 'yuv420p'],
967
- temp_audiofile=os.path.join(cache_dir, "temp-audio.m4a"),
968
  verbose=False,
969
  logger=None
970
  )
971
  except Exception as e:
972
- # Attempt error recovery
973
- status_text.text("Attempting error recovery...")
974
- try:
975
- # Try alternative codec settings
976
- final_clip.write_videofile(
977
- output_path,
978
- fps=fps,
979
- codec='libx264',
980
- audio_codec='mp3',
981
- verbose=False,
982
- logger=None
983
- )
984
- except Exception as recovery_e:
985
- raise RuntimeError(f"Video creation failed even with recovery attempt: {str(recovery_e)}")
986
 
987
  progress_bar.progress(100)
988
  status_text.text("Video generation complete!")
@@ -991,7 +919,7 @@ class EnhancedVideoGenerator:
991
 
992
  except Exception as e:
993
  error_msg = f"Video creation failed: {str(e)}"
994
- print(error_msg)
995
  raise RuntimeError(error_msg)
996
  finally:
997
  # Cleanup
@@ -1004,9 +932,9 @@ class EnhancedVideoGenerator:
1004
  audio.close()
1005
  except Exception as e:
1006
  print(f"Cleanup error: {e}")
 
1007
 
1008
 
1009
-
1010
  def generate_visual_assets(self, script: str, style: str) -> List[Dict]:
1011
  """Generate relevant visual assets based on script content"""
1012
  try:
@@ -1119,7 +1047,7 @@ class EnhancedVideoGenerator:
1119
  # Streamlit UI Class
1120
  class VideoGeneratorUI:
1121
  def __init__(self):
1122
- self.generator = VideoGenerator()
1123
  self.setup_ui()
1124
 
1125
  def setup_ui(self):
@@ -1248,8 +1176,7 @@ class VideoGeneratorUI:
1248
  )
1249
  except Exception as e:
1250
  print(f"Error displaying image: {e}")
1251
- pass
1252
-
1253
  def show_video_settings(self, prompt: str, selected_images: List[str]):
1254
  """Show video generation settings and controls"""
1255
  st.subheader("Video Settings")
@@ -1276,29 +1203,19 @@ class VideoGeneratorUI:
1276
  return
1277
 
1278
  try:
1279
- # Generate a unique filename with timestamp
1280
- timestamp = int(time.time())
1281
- output_filename = f"vaultgenix_video_{timestamp}.mp4"
1282
-
1283
- # Create absolute output path
1284
- output_path = os.path.abspath(os.path.join(
1285
- self.generator.base_dir,
1286
- output_filename
1287
- ))
1288
 
1289
- # Show progress message
1290
- progress_message = st.empty()
1291
- progress_message.text("🎥 Generating your video... This may take a few minutes.")
1292
-
1293
- video_path = self.generator.generate_video(
1294
  prompt,
1295
- selected_images,
1296
  duration,
1297
- output_path
 
1298
  )
1299
 
1300
  if os.path.exists(video_path):
1301
- progress_message.empty()
1302
  st.success("✨ Video generated successfully!")
1303
 
1304
  # Display video
@@ -1310,7 +1227,7 @@ class VideoGeneratorUI:
1310
  st.download_button(
1311
  label="⬇️ Download Video",
1312
  data=video_bytes,
1313
- file_name=output_filename,
1314
  mime="video/mp4"
1315
  )
1316
  else:
@@ -1320,308 +1237,61 @@ class VideoGeneratorUI:
1320
  st.error(f"Error generating video: {str(e)}")
1321
  print(f"Video generation error: {str(e)}") # For debugging
1322
 
1323
- class VideoGenerator:
1324
- def __init__(self):
1325
- # Create base directories
1326
- self.base_dir = os.path.abspath("generated_videos")
1327
- self.temp_dir = os.path.abspath(tempfile.mkdtemp())
1328
-
1329
- # Ensure directories exist
1330
- os.makedirs(self.base_dir, exist_ok=True)
1331
- os.makedirs(self.temp_dir, exist_ok=True)
1332
-
1333
- self.setup_resources()
1334
-
1335
- def setup_resources(self):
1336
- # Initialize font
1337
- try:
1338
- font_options = [
1339
- "arial.ttf",
1340
- "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf",
1341
- "/System/Library/Fonts/Helvetica.ttc"
1342
- ]
1343
- for font_path in font_options:
1344
- try:
1345
- self.font = ImageFont.truetype(font_path, 40)
1346
- break
1347
- except OSError:
1348
- continue
1349
- else:
1350
- self.font = ImageFont.load_default()
1351
- except Exception as e:
1352
- print(f"Font loading error: {e}")
1353
- self.font = ImageFont.load_default()
1354
-
1355
- def create_video_frame(self, image, text, frame_number, total_frames, size=(1920, 1080)):
1356
- try:
1357
- # Resize and pad image to maintain aspect ratio
1358
- img_aspect = image.size[0] / image.size[1]
1359
- target_aspect = size[0] / size[1]
1360
 
1361
- if img_aspect > target_aspect:
1362
- new_height = size[1]
1363
- new_width = int(new_height * img_aspect)
1364
- else:
1365
- new_width = size[0]
1366
- new_height = int(new_width / img_aspect)
1367
 
1368
- image = image.resize((new_width, new_height), Image.LANCZOS)
1369
-
1370
- # Create new background
1371
- frame = Image.new('RGB', size, (0, 0, 0))
1372
-
1373
- # Paste resized image in center
1374
- paste_x = (size[0] - new_width) // 2
1375
- paste_y = (size[1] - new_height) // 2
1376
- frame.paste(image, (paste_x, paste_y))
1377
-
1378
- # Add text overlay
1379
- draw = ImageDraw.Draw(frame)
1380
-
1381
- # Text background
1382
- text = textwrap.fill(text, width=50)
1383
- text_bbox = draw.textbbox((0, 0), text, font=self.font)
1384
- text_width = text_bbox[2] - text_bbox[0]
1385
- text_height = text_bbox[3] - text_bbox[1]
1386
-
1387
- text_x = (size[0] - text_width) // 2
1388
- text_y = size[1] - text_height - 100
1389
-
1390
- # Semi-transparent background
1391
- padding = 20
1392
- draw.rectangle(
1393
- [
1394
- text_x - padding,
1395
- text_y - padding,
1396
- text_x + text_width + padding,
1397
- text_y + text_height + padding
1398
- ],
1399
- fill=(0, 0, 0, 180)
1400
- )
1401
-
1402
- # Draw text
1403
- draw.text((text_x, text_y), text, fill=(255, 255, 255), font=self.font)
1404
-
1405
- # Add progress bar
1406
- self.draw_progress_bar(draw, frame_number, total_frames, size)
1407
-
1408
- return np.array(frame)
1409
-
1410
- except Exception as e:
1411
- print(f"Frame creation error: {e}")
1412
- return np.zeros((*size, 3), dtype=np.uint8)
1413
-
1414
- def draw_progress_bar(self, draw, frame_number, total_frames, size):
1415
- progress = frame_number / total_frames
1416
- bar_width = int(size[0] * 0.8)
1417
- bar_height = 6
1418
- x_offset = (size[0] - bar_width) // 2
1419
- y_position = size[1] - 40
1420
-
1421
- # Background bar
1422
- draw.rectangle(
1423
- [x_offset, y_position, x_offset + bar_width, y_position + bar_height],
1424
- fill=(100, 100, 100, 160)
1425
- )
1426
-
1427
- # Progress bar
1428
- progress_width = int(bar_width * progress)
1429
- draw.rectangle(
1430
- [x_offset, y_position, x_offset + progress_width, y_position + bar_height],
1431
- fill=(255, 255, 255, 200)
1432
- )
1433
-
1434
- def generate_video(self, script: str, images: List[str], duration: int, output_path: str) -> str:
1435
- if not script or not images:
1436
- raise ValueError("Script and images are required")
1437
-
1438
- if not output_path:
1439
- # Generate default output path if none provided
1440
- timestamp = int(time.time())
1441
- output_path = os.path.join(self.base_dir, f"video_{timestamp}.mp4")
1442
-
1443
- # Ensure output directory exists
1444
- os.makedirs(os.path.dirname(os.path.abspath(output_path)), exist_ok=True)
1445
-
1446
- try:
1447
- # Process images
1448
- processed_images = []
1449
- for img_url in images:
1450
- try:
1451
- response = requests.get(img_url)
1452
- img = Image.open(BytesIO(response.content)).convert('RGB')
1453
- processed_images.append(img)
1454
- except Exception as e:
1455
- print(f"Image processing error: {e}")
1456
- continue
1457
-
1458
- if not processed_images:
1459
- raise ValueError("No valid images to process")
1460
-
1461
- # Generate frames
1462
- fps = 30
1463
- total_frames = duration * fps
1464
- frames_per_image = total_frames // len(processed_images)
1465
-
1466
- # Split script into sections
1467
- words = script.split()
1468
- words_per_image = len(words) // len(processed_images)
1469
-
1470
- frames = []
1471
- frame_count = 0
1472
-
1473
- # Generate frames
1474
- for idx, img in enumerate(processed_images):
1475
- start_idx = idx * words_per_image
1476
- end_idx = start_idx + words_per_image if idx < len(processed_images) - 1 else len(words)
1477
- section_text = ' '.join(words[start_idx:end_idx])
1478
 
1479
- for frame in range(frames_per_image):
1480
- if frame_count < total_frames:
1481
- frame_img = self.create_video_frame(
1482
- img,
1483
- section_text,
1484
- frame_count,
1485
- total_frames
1486
- )
1487
- frames.append(frame_img)
1488
- frame_count += 1
1489
-
1490
- # Add transitions
1491
- if idx < len(processed_images) - 1:
1492
- next_img = processed_images[idx + 1]
1493
- for t in range(15):
1494
- if frame_count < total_frames:
1495
- alpha = t / 15
1496
- transition_frame = Image.blend(
1497
- img,
1498
- next_img,
1499
- alpha
1500
- )
1501
- frame_img = self.create_video_frame(
1502
- transition_frame,
1503
- section_text,
1504
- frame_count,
1505
- total_frames
1506
- )
1507
- frames.append(frame_img)
1508
- frame_count += 1
1509
-
1510
- # Generate audio
1511
- audio_path = os.path.join(self.temp_dir, "audio.mp3")
1512
- tts = gTTS(text=script, lang='en')
1513
- tts.save(audio_path)
1514
-
1515
- # Create video
1516
- clip = ImageSequenceClip(frames, fps=fps)
1517
- audio_clip = AudioFileClip(audio_path)
1518
-
1519
- # Adjust durations
1520
- if audio_clip.duration < clip.duration:
1521
- clip = clip.subclip(0, audio_clip.duration)
1522
- else:
1523
- audio_clip = audio_clip.subclip(0, clip.duration)
1524
-
1525
- final_clip = clip.set_audio(audio_clip)
1526
-
1527
- # Write video
1528
- final_clip.write_videofile(
1529
- output_path,
1530
- fps=fps,
1531
- codec='libx264',
1532
- audio_codec='aac',
1533
- ffmpeg_params=['-pix_fmt', 'yuv420p']
1534
- )
1535
-
1536
- return output_path
1537
-
1538
- except Exception as e:
1539
- print(f"Video generation error: {e}")
1540
- raise
1541
- finally:
1542
- # Cleanup
1543
- try:
1544
- if 'clip' in locals():
1545
- clip.close()
1546
- if 'final_clip' in locals():
1547
- final_clip.close()
1548
- if 'audio_clip' in locals():
1549
- audio_clip.close()
1550
- except Exception as e:
1551
- print(f"Cleanup error: {e}")
1552
-
1553
- def cleanup(self):
1554
- try:
1555
- import shutil
1556
- shutil.rmtree(self.temp_dir)
1557
- except Exception as e:
1558
- print(f"Cleanup error: {e}")
1559
-
1560
- def create_ui():
1561
- ui = VideoGeneratorUI()
1562
- st.title("VaultGenix Video Generator")
1563
- st.markdown("Create professional videos for your digital legacy management platform")
1564
-
1565
- # File upload section
1566
- st.subheader("Upload Content")
1567
- uploaded_file = st.file_uploader(
1568
- "Upload your content (PDF, DOCX, PPTX, or TXT)",
1569
- type=['pdf', 'docx', 'pptx', 'txt']
1570
- )
1571
-
1572
- # Text input section
1573
- script = ""
1574
- if uploaded_file:
1575
- try:
1576
- file_processor = FileProcessor()
1577
- if uploaded_file.type == "text/plain":
1578
- script = file_processor.read_txt(uploaded_file)
1579
- elif uploaded_file.type == "application/pdf":
1580
- script = file_processor.read_pdf(uploaded_file)
1581
- elif uploaded_file.type == "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
1582
- script = file_processor.read_docx(uploaded_file)
1583
- elif uploaded_file.type == "application/vnd.openxmlformats-officedocument.presentationml.presentation":
1584
- script = file_processor.read_pptx(uploaded_file)
1585
- except Exception as e:
1586
- st.error(f"Error processing file: {str(e)}")
1587
-
1588
- script = st.text_area("Enter or edit your video script", value=script, height=200)
1589
-
1590
- if st.button("Generate Video") and script:
1591
- try:
1592
- # Initialize video generator
1593
- generator = VideoGenerator()
1594
-
1595
- # Get stock images (replace with your image selection logic)
1596
- images = [
1597
- "https://images.pexels.com/photos/60504/security-protection-anti-virus-software-60504.jpeg",
1598
- "https://images.pexels.com/photos/5380642/pexels-photo-5380642.jpeg",
1599
- "https://images.pexels.com/photos/2582937/pexels-photo-2582937.jpeg"
1600
- ]
1601
-
1602
- # Generate video
1603
- output_path = "output_video.mp4"
1604
- with st.spinner("Generating video..."):
1605
- video_path = generator.generate_video(script, images, 30, output_path)
1606
-
1607
- # Display video
1608
- if os.path.exists(video_path):
1609
- st.success("Video generated successfully!")
1610
- with open(video_path, 'rb') as video_file:
1611
  video_bytes = video_file.read()
1612
  st.video(video_bytes)
1613
 
1614
  # Download button
1615
  st.download_button(
1616
- label="Download Video",
1617
  data=video_bytes,
1618
- file_name="vaultgenix_video.mp4",
1619
  mime="video/mp4"
1620
  )
1621
-
1622
- except Exception as e:
1623
- st.error(f"Error generating video: {str(e)}")
1624
- print(f"Error details: {str(e)}")
 
 
 
 
 
 
 
 
 
 
 
 
1625
 
1626
  if __name__ == "__main__":
1627
- create_ui()
 
21
  from bs4 import BeautifulSoup
22
  import requests
23
  from io import BytesIO
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
  class ImageScraper:
26
  def __init__(self):
 
796
  return f"{hours:02d}:{minutes:02d}:{secs:02d},{msecs:03d}"
797
 
798
  def create_video(self, script: str, style: str, duration: int, output_path: str, selected_images: List[str]) -> str:
799
+ """Create video with selected images and improved error handling"""
800
  try:
801
  # Initialize progress tracking
802
  progress_bar = st.progress(0)
803
  status_text = st.empty()
804
 
805
+ # Validate inputs
 
 
 
 
 
806
  if not selected_images:
807
+ raise ValueError("No images selected. Please select at least one image.")
808
+
809
+ if not script.strip():
810
+ raise ValueError("Script cannot be empty.")
811
+
812
+ # Generate voice-over
813
  status_text.text("Creating voice-over...")
814
+ audio = self.generate_fallback_audio(script) # Using fallback audio for reliability
815
  progress_bar.progress(20)
816
 
817
+ # Process images
818
+ status_text.text("Processing images...")
819
  processed_images = []
820
 
821
  for img_url in selected_images:
 
824
  response.raise_for_status()
825
  img = Image.open(BytesIO(response.content))
826
  img = img.convert('RGB')
 
 
 
 
 
 
 
 
 
 
 
 
 
827
  img = img.resize((1920, 1080), Image.Resampling.LANCZOS)
828
  processed_images.append(img)
 
829
  except Exception as e:
830
  print(f"Error processing image {img_url}: {e}")
831
  continue
832
 
833
+ if not processed_images:
834
+ raise ValueError("Failed to process any of the selected images.")
835
+
836
  progress_bar.progress(40)
837
 
838
+ # Create frames
839
+ status_text.text("Generating frames...")
840
  frames = []
841
  fps = 30
842
  total_frames = int(duration * fps)
 
845
  # Convert images to numpy arrays
846
  image_arrays = [np.array(img) for img in processed_images]
847
 
848
+ # Generate frames with transitions
849
  frame_count = 0
850
  for idx, img_array in enumerate(image_arrays):
851
+ # Calculate how many frames this image should appear
852
  if idx == len(image_arrays) - 1:
853
  n_frames = total_frames - frame_count
854
  else:
855
  n_frames = min(frames_per_image, total_frames - frame_count)
856
 
857
+ # Add main frames
858
+ for _ in range(n_frames):
859
+ frames.append(img_array)
 
 
 
 
 
 
 
 
860
  frame_count += 1
 
 
 
 
861
 
862
+ # Add transition frames to next image
863
  if idx < len(image_arrays) - 1:
864
  next_img_array = image_arrays[idx + 1]
865
+ transition_frames = 15 # Number of transition frames
866
  for t in range(transition_frames):
867
  if frame_count < total_frames:
868
  alpha = t / transition_frames
 
879
  status_text.text("Compiling video...")
880
  clip = ImageSequenceClip(frames, fps=fps)
881
 
882
+ # Add audio
883
  audio_duration = audio.duration
884
  video_duration = len(frames) / fps
885
 
 
890
 
891
  final_clip = clip.set_audio(audio)
892
 
893
+ # Ensure output directory exists
894
+ output_dir = os.path.dirname(output_path)
895
+ if output_dir and not os.path.exists(output_dir):
896
+ os.makedirs(output_dir)
897
+
898
+ progress_bar.progress(90)
899
 
900
+ # Write video file
901
+ status_text.text("Saving video...")
902
  try:
903
  final_clip.write_videofile(
904
  output_path,
905
  fps=fps,
906
  codec='libx264',
907
  audio_codec='aac',
908
+ ffmpeg_params=['-pix_fmt', 'yuv420p'], # Ensure compatibility
 
909
  verbose=False,
910
  logger=None
911
  )
912
  except Exception as e:
913
+ raise RuntimeError(f"Failed to write video file: {str(e)}")
 
 
 
 
 
 
 
 
 
 
 
 
 
914
 
915
  progress_bar.progress(100)
916
  status_text.text("Video generation complete!")
 
919
 
920
  except Exception as e:
921
  error_msg = f"Video creation failed: {str(e)}"
922
+ print(error_msg) # For debugging
923
  raise RuntimeError(error_msg)
924
  finally:
925
  # Cleanup
 
932
  audio.close()
933
  except Exception as e:
934
  print(f"Cleanup error: {e}")
935
+
936
 
937
 
 
938
  def generate_visual_assets(self, script: str, style: str) -> List[Dict]:
939
  """Generate relevant visual assets based on script content"""
940
  try:
 
1047
  # Streamlit UI Class
1048
  class VideoGeneratorUI:
1049
  def __init__(self):
1050
+ self.generator = EnhancedVideoGenerator()
1051
  self.setup_ui()
1052
 
1053
  def setup_ui(self):
 
1176
  )
1177
  except Exception as e:
1178
  print(f"Error displaying image: {e}")
1179
+
 
1180
  def show_video_settings(self, prompt: str, selected_images: List[str]):
1181
  """Show video generation settings and controls"""
1182
  st.subheader("Video Settings")
 
1203
  return
1204
 
1205
  try:
1206
+ output_dir = "temp_videos"
1207
+ os.makedirs(output_dir, exist_ok=True)
1208
+ output_path = os.path.join(output_dir, f"vaultgenix_video_{int(time.time())}.mp4")
 
 
 
 
 
 
1209
 
1210
+ video_path = self.generator.create_video(
 
 
 
 
1211
  prompt,
1212
+ style,
1213
  duration,
1214
+ output_path,
1215
+ selected_images
1216
  )
1217
 
1218
  if os.path.exists(video_path):
 
1219
  st.success("✨ Video generated successfully!")
1220
 
1221
  # Display video
 
1227
  st.download_button(
1228
  label="⬇️ Download Video",
1229
  data=video_bytes,
1230
+ file_name=os.path.basename(video_path),
1231
  mime="video/mp4"
1232
  )
1233
  else:
 
1237
  st.error(f"Error generating video: {str(e)}")
1238
  print(f"Video generation error: {str(e)}") # For debugging
1239
 
1240
+ def generate_video(self, prompt: str, style: str, duration: int, selected_images: List[str]):
1241
+ """Handle video generation with improved error handling"""
1242
+ if not selected_images:
1243
+ st.error("Please select at least one image before generating the video.")
1244
+ return
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1245
 
1246
+ with st.spinner("🎥 Generating your video..."):
1247
+ try:
1248
+ # Create temp directory if it doesn't exist
1249
+ temp_dir = Path("temp_videos")
1250
+ temp_dir.mkdir(exist_ok=True)
 
1251
 
1252
+ # Generate unique output path
1253
+ output_path = str(temp_dir / f"vaultgenix_video_{int(time.time())}.mp4")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1254
 
1255
+ # Generate video
1256
+ video_path = self.generator.create_video(
1257
+ prompt,
1258
+ style,
1259
+ duration,
1260
+ output_path,
1261
+ selected_images
1262
+ )
1263
+
1264
+ if video_path and os.path.exists(video_path):
1265
+ st.success("✨ Video generated successfully!")
1266
+
1267
+ # Display video
1268
+ video_file = open(video_path, 'rb')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1269
  video_bytes = video_file.read()
1270
  st.video(video_bytes)
1271
 
1272
  # Download button
1273
  st.download_button(
1274
+ label="⬇️ Download Video",
1275
  data=video_bytes,
1276
+ file_name=os.path.basename(video_path),
1277
  mime="video/mp4"
1278
  )
1279
+
1280
+ video_file.close()
1281
+ else:
1282
+ st.error("Video generation failed. Please try again.")
1283
+
1284
+ except Exception as e:
1285
+ st.error(f"Failed to generate video: {str(e)}")
1286
+ print(f"Video generation error: {str(e)}")
1287
+
1288
+ finally:
1289
+ # Cleanup temporary files
1290
+ try:
1291
+ if 'video_file' in locals():
1292
+ video_file.close()
1293
+ except Exception as e:
1294
+ print(f"Cleanup error: {e}")
1295
 
1296
  if __name__ == "__main__":
1297
+ ui = VideoGeneratorUI()