shaheerawan3 commited on
Commit
65487da
·
verified ·
1 Parent(s): 39e56b1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +190 -190
app.py CHANGED
@@ -796,145 +796,145 @@ class EnhancedVideoGenerator:
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:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
822
  try:
823
- response = requests.get(img_url, timeout=10)
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)
843
- frames_per_image = total_frames // len(processed_images)
844
-
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
869
- transition_frame = cv2.addWeighted(
870
- img_array, 1 - alpha,
871
- next_img_array, alpha, 0
872
- )
873
- frames.append(transition_frame)
874
- frame_count += 1
875
-
876
- progress_bar.progress(70)
877
-
878
- # Create video with 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
-
886
- if audio_duration > video_duration:
887
- audio = audio.subclip(0, video_duration)
888
- elif audio_duration < video_duration:
889
- clip = clip.subclip(0, audio_duration)
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!")
917
-
918
- return output_path
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
926
- try:
927
- if 'clip' in locals():
928
- clip.close()
929
- if 'final_clip' in locals():
930
- final_clip.close()
931
- if 'audio' in locals():
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:
@@ -1178,65 +1178,65 @@ class VideoGeneratorUI:
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")
1183
-
1184
- col1, col2 = st.columns(2)
1185
- with col1:
1186
- style = st.selectbox(
1187
- "Choose style",
1188
- options=["Professional", "Creative", "Educational"],
1189
- index=0
1190
- )
1191
- with col2:
1192
- duration = st.slider(
1193
- "Video duration (seconds)",
1194
- min_value=30,
1195
- max_value=180,
1196
- value=60,
1197
- step=30
1198
- )
1199
-
1200
- if st.button("🎬 Generate Video", type="primary"):
1201
- if not selected_images:
1202
- st.error("Please select at least one image before generating the video.")
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
1222
- with open(video_path, 'rb') as video_file:
1223
- video_bytes = video_file.read()
1224
- st.video(video_bytes)
1225
-
1226
- # Download button
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:
1234
- st.error("Video generation failed. Please try again.")
1235
 
1236
- except Exception as e:
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:
 
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:
822
+ try:
823
+ response = requests.get(img_url, timeout=10)
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)
843
+ frames_per_image = total_frames // len(processed_images)
844
+
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
869
+ transition_frame = cv2.addWeighted(
870
+ img_array, 1 - alpha,
871
+ next_img_array, alpha, 0
872
+ )
873
+ frames.append(transition_frame)
874
+ frame_count += 1
875
+
876
+ progress_bar.progress(70)
877
+
878
+ # Create video with 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
+
886
+ if audio_duration > video_duration:
887
+ audio = audio.subclip(0, video_duration)
888
+ elif audio_duration < video_duration:
889
+ clip = clip.subclip(0, audio_duration)
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!")
917
+
918
+ return output_path
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
926
+ try:
927
+ if 'clip' in locals():
928
+ clip.close()
929
+ if 'final_clip' in locals():
930
+ final_clip.close()
931
+ if 'audio' in locals():
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:
 
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")
1183
+
1184
+ col1, col2 = st.columns(2)
1185
+ with col1:
1186
+ style = st.selectbox(
1187
+ "Choose style",
1188
+ options=["Professional", "Creative", "Educational"],
1189
+ index=0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1190
  )
1191
+ with col2:
1192
+ duration = st.slider(
1193
+ "Video duration (seconds)",
1194
+ min_value=30,
1195
+ max_value=180,
1196
+ value=60,
1197
+ step=30
1198
+ )
1199
+
1200
+ if st.button("🎬 Generate Video", type="primary"):
1201
+ if not selected_images:
1202
+ st.error("Please select at least one image before generating the video.")
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
1222
+ with open(video_path, 'rb') as video_file:
1223
+ video_bytes = video_file.read()
1224
+ st.video(video_bytes)
1225
+
1226
+ # Download button
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:
1234
+ st.error("Video generation failed. Please try again.")
1235
+
1236
+ except Exception as e:
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: