shaheerawan3 commited on
Commit
f8747cf
·
verified ·
1 Parent(s): 88e8aaa

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +64 -30
app.py CHANGED
@@ -757,12 +757,19 @@ class EnhancedVideoGenerator:
757
  return f"{hours:02d}:{minutes:02d}:{secs:02d},{msecs:03d}"
758
 
759
  def create_video(self, script: str, style: str, duration: int, output_path: str, selected_images: List[str]) -> str:
760
- """Create video with selected images"""
761
  try:
762
  # Progress bar
763
  progress_bar = st.progress(0)
764
  status_text = st.empty()
765
 
 
 
 
 
 
 
 
766
  # Generate voice-over (20%)
767
  status_text.text("Creating voice-over...")
768
  audio = self.generate_voice_over(script)
@@ -771,60 +778,87 @@ class EnhancedVideoGenerator:
771
  # Process selected images (40%)
772
  status_text.text("Processing images...")
773
  processed_images = []
 
774
  for img_url in selected_images:
775
- response = requests.get(img_url)
776
- img = Image.open(BytesIO(response.content))
777
- img = img.resize((1920, 1080), Image.Resampling.LANCZOS)
778
- processed_images.append(np.array(img))
779
- progress_bar.progress(40)
 
 
 
 
 
 
 
 
780
 
 
 
781
  # Create frames with transitions
782
  fps = 30
783
  total_frames = int(duration * fps)
784
  frames = []
785
-
786
  status_text.text("Generating frames...")
787
  frames_per_image = total_frames // len(processed_images)
788
-
789
  for idx, img in enumerate(processed_images):
 
790
  for _ in range(frames_per_image):
791
  frames.append(img)
792
-
793
- # Add transition frames
794
  if idx < len(processed_images) - 1:
795
  next_img = processed_images[idx + 1]
796
  for alpha in np.linspace(0, 1, 15):
797
  transition_frame = (1 - alpha) * img + alpha * next_img
798
  frames.append(transition_frame.astype(np.uint8))
799
-
800
- progress_bar.progress(70)
801
-
802
- # Create video clip
803
  status_text.text("Compiling video...")
804
  video = ImageSequenceClip(frames, fps=fps)
 
 
 
 
 
 
 
 
 
 
805
  video = video.set_audio(audio)
806
-
807
  progress_bar.progress(90)
808
-
809
- # Write final video
810
- status_text.text("Saving video...")
811
- video.write_videofile(
812
- output_path,
813
- fps=fps,
814
- codec='libx264',
815
- audio_codec='aac',
816
- threads=4,
817
- preset='ultrafast'
818
- )
819
-
 
 
820
  progress_bar.progress(100)
821
  status_text.text("Video generation complete!")
822
-
823
  return output_path
824
-
825
  except Exception as e:
826
- self.logger.error(f"Video creation failed: {str(e)}")
 
 
827
  raise
 
828
 
829
 
830
  def generate_visual_assets(self, script: str, style: str) -> List[Dict]:
 
757
  return f"{hours:02d}:{minutes:02d}:{secs:02d},{msecs:03d}"
758
 
759
  def create_video(self, script: str, style: str, duration: int, output_path: str, selected_images: List[str]) -> str:
760
+ """Create video with selected images and improved error handling"""
761
  try:
762
  # Progress bar
763
  progress_bar = st.progress(0)
764
  status_text = st.empty()
765
 
766
+ # Validate inputs
767
+ if not selected_images:
768
+ raise ValueError("No images selected. Please select at least one image.")
769
+
770
+ if not script.strip():
771
+ raise ValueError("Script cannot be empty.")
772
+
773
  # Generate voice-over (20%)
774
  status_text.text("Creating voice-over...")
775
  audio = self.generate_voice_over(script)
 
778
  # Process selected images (40%)
779
  status_text.text("Processing images...")
780
  processed_images = []
781
+
782
  for img_url in selected_images:
783
+ try:
784
+ response = requests.get(img_url, timeout=10)
785
+ response.raise_for_status() # Raise exception for bad status codes
786
+ img = Image.open(BytesIO(response.content))
787
+ img = img.convert('RGB') # Ensure RGB format
788
+ img = img.resize((1920, 1080), Image.Resampling.LANCZOS)
789
+ processed_images.append(np.array(img))
790
+ except Exception as e:
791
+ print(f"Error processing image {img_url}: {e}")
792
+ continue
793
+
794
+ if not processed_images:
795
+ raise ValueError("Failed to process any of the selected images.")
796
 
797
+ progress_bar.progress(40)
798
+
799
  # Create frames with transitions
800
  fps = 30
801
  total_frames = int(duration * fps)
802
  frames = []
803
+
804
  status_text.text("Generating frames...")
805
  frames_per_image = total_frames // len(processed_images)
806
+
807
  for idx, img in enumerate(processed_images):
808
+ # Add main frames
809
  for _ in range(frames_per_image):
810
  frames.append(img)
811
+
812
+ # Add transition frames to next image
813
  if idx < len(processed_images) - 1:
814
  next_img = processed_images[idx + 1]
815
  for alpha in np.linspace(0, 1, 15):
816
  transition_frame = (1 - alpha) * img + alpha * next_img
817
  frames.append(transition_frame.astype(np.uint8))
818
+
819
+ progress_bar.progress(70)
820
+
821
+ # Create video clip
822
  status_text.text("Compiling video...")
823
  video = ImageSequenceClip(frames, fps=fps)
824
+
825
+ # Ensure audio duration matches video duration
826
+ audio_duration = audio.duration
827
+ video_duration = len(frames) / fps
828
+
829
+ if audio_duration > video_duration:
830
+ audio = audio.subclip(0, video_duration)
831
+ elif audio_duration < video_duration:
832
+ video = video.subclip(0, audio_duration)
833
+
834
  video = video.set_audio(audio)
835
+
836
  progress_bar.progress(90)
837
+
838
+ # Write final video with error handling
839
+ try:
840
+ video.write_videofile(
841
+ output_path,
842
+ fps=fps,
843
+ codec='libx264',
844
+ audio_codec='aac',
845
+ threads=4,
846
+ preset='ultrafast'
847
+ )
848
+ except Exception as e:
849
+ raise RuntimeError(f"Failed to write video file: {str(e)}")
850
+
851
  progress_bar.progress(100)
852
  status_text.text("Video generation complete!")
853
+
854
  return output_path
855
+
856
  except Exception as e:
857
+ error_msg = f"Video creation failed: {str(e)}"
858
+ self.logger.error(error_msg)
859
+ st.error(error_msg)
860
  raise
861
+
862
 
863
 
864
  def generate_visual_assets(self, script: str, style: str) -> List[Dict]: