gnosticdev commited on
Commit
2b26186
·
verified ·
1 Parent(s): 52c5b8e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +64 -49
app.py CHANGED
@@ -34,6 +34,7 @@ logger.info("="*80)
34
  PEXELS_API_KEY = os.environ.get("PEXELS_API_KEY")
35
  if not PEXELS_API_KEY:
36
  logger.critical("PEXELS_API_KEY environment variable not found.")
 
37
  # raise ValueError("Pexels API key not configured")
38
 
39
  # Model Initialization
@@ -618,7 +619,7 @@ def crear_video(prompt_type, input_text, musica_file=None):
618
  # 6. Handle background music
619
  logger.info("Processing audio...")
620
 
621
- final_audio = audio_tts_original # Start with the original valid TTS audio
622
 
623
  musica_audio_looped = None
624
 
@@ -649,7 +650,6 @@ def crear_video(prompt_type, input_text, musica_file=None):
649
 
650
 
651
  if musica_audio_looped:
652
- # Use the looped music and the current audio_tts (which is the original)
653
  composite_audio = CompositeAudioClip([
654
  musica_audio_looped.volumex(0.2),
655
  audio_tts_original.volumex(1.0)
@@ -659,12 +659,11 @@ def crear_video(prompt_type, input_text, musica_file=None):
659
  logger.warning("Composite audio clip is invalid (None or zero duration). Using voice audio only.")
660
  try: composite_audio.close()
661
  except: pass
662
- # Components were likely closed by composite_audio.close() or will be in main finally
663
- final_audio = audio_tts_original # Fallback
664
  else:
665
  logger.info("Audio mix completed (voice + music).")
666
- final_audio = composite_audio # Use the valid composite audio
667
- musica_audio = musica_audio_looped # Assign for cleanup
668
 
669
  except Exception as e:
670
  logger.warning(f"Error processing background music: {str(e)}", exc_info=True)
@@ -692,13 +691,13 @@ def crear_video(prompt_type, input_text, musica_file=None):
692
  logger.warning(f"Error adjusting final audio duration: {str(e)}")
693
 
694
 
695
- # Final check on video_final before writing
696
  video_final = video_base.set_audio(final_audio)
697
 
698
  if video_final is None or video_final.duration is None or video_final.duration <= 0:
699
  logger.critical("Final video clip (with audio) is invalid before writing (None or zero duration).")
700
  raise ValueError("Final video clip is invalid before writing.")
701
 
 
702
  output_filename = "final_video.mp4"
703
  output_path = os.path.join(temp_dir_intermediate, output_filename)
704
  logger.info(f"Writing final video to: {output_path}")
@@ -728,33 +727,60 @@ def crear_video(prompt_type, input_text, musica_file=None):
728
  logger.info("Starting cleanup of clips and intermediate temporary files...")
729
 
730
  for clip in source_clips:
731
- try: clip.close()
732
- except Exception as e: logger.warning(f"Error closing source video clip in finally: {str(e)}")
 
 
733
 
734
  for clip_segment in clips_to_concatenate:
735
- try: clip_segment.close()
736
- except Exception as e: logger.warning(f"Error closing video segment clip in finally: {str(e)}")
 
 
737
 
738
- try:
739
- # Close audio clips: looped music, original music, then final audio (which might close its components)
740
- if musica_audio is not None: try: musica_audio.close() except Exception as e: logger.warning(f"Error closing musica_audio in finally: {str(e)}")
741
- if musica_audio_original is not None and musica_audio_original is not musica_audio: try: musica_audio_original.close() except Exception as e: logger.warning(f"Error closing musica_audio_original in finally: {str(e)}")
742
-
743
- # Close TTS clips: potentially modified/trimmed TTS, then original TTS
744
- if audio_tts is not None and audio_tts is not audio_tts_original: try: audio_tts.close() except Exception as e: logger.warning(f"Error closing audio_tts (modified) in finally: {str(e)}")
745
- if audio_tts_original is not None: try: audio_tts_original.close() except Exception as e: logger.warning(f"Error closing audio_tts_original in finally: {str(e)}")
746
-
747
- # Close video clips: final video (should cascade), then video base if it wasn't the final
748
- if video_final is not None:
749
- try: video_final.close()
750
- except Exception as e: logger.warning(f"Error closing video_final in finally: {str(e)}")
751
- elif video_base is not None:
752
- try: video_base.close()
753
- except Exception as e: logger.warning(f"Error closing video_base in finally: {str(e)}")
754
 
755
- except Exception as e:
756
- logger.warning(f"Error during final clip closing in finally: {str(e)}")
 
 
 
 
 
757
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
758
  if temp_dir_intermediate and os.path.exists(temp_dir_intermediate):
759
  final_output_in_temp = os.path.join(temp_dir_intermediate, "final_video.mp4")
760
 
@@ -775,14 +801,12 @@ def run_app(prompt_type, prompt_ia, prompt_manual, musica_file):
775
 
776
  input_text = prompt_ia if prompt_type == "Generar Guion con IA" else prompt_manual
777
 
778
- # Initialize outputs to None and default status
779
  output_video = None
780
  output_file = None
781
  status_msg = gr.update(value="⏳ Procesando...", interactive=False)
782
 
783
  if not input_text or not input_text.strip():
784
  logger.warning("Empty input text.")
785
- # Return None for video and file, update status
786
  return None, None, gr.update(value="⚠️ Por favor, ingresa texto para el guion o el tema.", interactive=False)
787
 
788
  logger.info(f"Input Type: {prompt_type}")
@@ -799,25 +823,21 @@ def run_app(prompt_type, prompt_ia, prompt_manual, musica_file):
799
  if video_path and os.path.exists(video_path):
800
  logger.info(f"crear_video returned path: {video_path}")
801
  logger.info(f"Size of returned video file: {os.path.getsize(video_path)} bytes")
802
- output_video = video_path # Set video component value
803
- output_file = video_path # Set file component value for download
804
  status_msg = gr.update(value="✅ Video generado exitosamente.", interactive=False)
805
  else:
806
  logger.error(f"crear_video did not return a valid path or file does not exist: {video_path}")
807
- # Leave video and file outputs as None
808
  status_msg = gr.update(value="❌ Error: La generación del video falló o el archivo no se creó correctamente.", interactive=False)
809
 
810
  except ValueError as ve:
811
  logger.warning(f"Validation error during video creation: {str(ve)}")
812
- # Leave video and file outputs as None
813
  status_msg = gr.update(value=f"⚠️ Error de validación: {str(ve)}", interactive=False)
814
  except Exception as e:
815
  logger.critical(f"Critical error during video creation: {str(e)}", exc_info=True)
816
- # Leave video and file outputs as None
817
  status_msg = gr.update(value=f"❌ Error inesperado: {str(e)}", interactive=False)
818
  finally:
819
  logger.info("End of run_app handler.")
820
- # Return all three outputs
821
  return output_video, output_file, status_msg
822
 
823
 
@@ -867,15 +887,14 @@ with gr.Blocks(title="Generador de Videos con IA", theme=gr.themes.Soft(), css="
867
 
868
  with gr.Column():
869
  video_output = gr.Video(
870
- label="Generated Video Preview", # Changed label
871
  interactive=False,
872
  height=400
873
  )
874
- # Add the File component for download
875
  file_output = gr.File(
876
  label="Download Video",
877
- interactive=False, # Not interactive for user upload
878
- visible=False # Hide initially
879
  )
880
  status_output = gr.Textbox(
881
  label="Status",
@@ -892,22 +911,18 @@ with gr.Blocks(title="Generador de Videos con IA", theme=gr.themes.Soft(), css="
892
  outputs=[ia_guion_column, manual_guion_column]
893
  )
894
 
895
- # Modify the click event to return 3 outputs
896
  generate_btn.click(
897
- # Action 1: Reset outputs and set status to processing
898
  lambda: (None, None, gr.update(value="⏳ Procesando... Esto puede tomar 2-5 minutos.", interactive=False)),
899
  outputs=[video_output, file_output, status_output],
900
  queue=True,
901
  ).then(
902
- # Action 2: Call the main processing function
903
  run_app,
904
  inputs=[prompt_type, prompt_ia, prompt_manual, musica_input],
905
- outputs=[video_output, file_output, status_output] # Match the 3 outputs
906
  ).then(
907
- # Action 3: Make the download link visible if a file was returned
908
- lambda video_path: gr.update(visible=video_path is not None), # Check if video_output has a value
909
- inputs=[video_output], # Use video_output as input to check if generation was successful
910
- outputs=[file_output] # Update visibility of file_output
911
  )
912
 
913
 
 
34
  PEXELS_API_KEY = os.environ.get("PEXELS_API_KEY")
35
  if not PEXELS_API_KEY:
36
  logger.critical("PEXELS_API_KEY environment variable not found.")
37
+ # Uncomment to force fail if not set:
38
  # raise ValueError("Pexels API key not configured")
39
 
40
  # Model Initialization
 
619
  # 6. Handle background music
620
  logger.info("Processing audio...")
621
 
622
+ final_audio = audio_tts_original
623
 
624
  musica_audio_looped = None
625
 
 
650
 
651
 
652
  if musica_audio_looped:
 
653
  composite_audio = CompositeAudioClip([
654
  musica_audio_looped.volumex(0.2),
655
  audio_tts_original.volumex(1.0)
 
659
  logger.warning("Composite audio clip is invalid (None or zero duration). Using voice audio only.")
660
  try: composite_audio.close()
661
  except: pass
662
+ final_audio = audio_tts_original
 
663
  else:
664
  logger.info("Audio mix completed (voice + music).")
665
+ final_audio = composite_audio
666
+ musica_audio = musica_audio_looped
667
 
668
  except Exception as e:
669
  logger.warning(f"Error processing background music: {str(e)}", exc_info=True)
 
691
  logger.warning(f"Error adjusting final audio duration: {str(e)}")
692
 
693
 
 
694
  video_final = video_base.set_audio(final_audio)
695
 
696
  if video_final is None or video_final.duration is None or video_final.duration <= 0:
697
  logger.critical("Final video clip (with audio) is invalid before writing (None or zero duration).")
698
  raise ValueError("Final video clip is invalid before writing.")
699
 
700
+
701
  output_filename = "final_video.mp4"
702
  output_path = os.path.join(temp_dir_intermediate, output_filename)
703
  logger.info(f"Writing final video to: {output_path}")
 
727
  logger.info("Starting cleanup of clips and intermediate temporary files...")
728
 
729
  for clip in source_clips:
730
+ try:
731
+ clip.close()
732
+ except Exception as e:
733
+ logger.warning(f"Error closing source video clip in finally: {str(e)}")
734
 
735
  for clip_segment in clips_to_concatenate:
736
+ try:
737
+ clip_segment.close()
738
+ except Exception as e:
739
+ logger.warning(f"Error closing video segment clip in finally: {str(e)}")
740
 
741
+ # Close audio clips: looped music, original music, then final audio (which might close its components)
742
+ if musica_audio is not None:
743
+ try:
744
+ musica_audio.close()
745
+ except Exception as e:
746
+ logger.warning(f"Error closing musica_audio (processed) in finally: {str(e)}")
747
+
748
+ if musica_audio_original is not None and musica_audio_original is not musica_audio:
749
+ try:
750
+ musica_audio_original.close()
751
+ except Exception as e:
752
+ logger.warning(f"Error closing musica_audio_original in finally: {str(e)}")
 
 
 
 
753
 
754
+ # Close TTS clips: potentially modified/trimmed TTS, then original TTS
755
+ # Note: audio_tts variable is only assigned audio_tts_original in this code, but keep structure for safety
756
+ if audio_tts is not None and audio_tts is not audio_tts_original:
757
+ try:
758
+ audio_tts.close()
759
+ except Exception as e:
760
+ logger.warning(f"Error closing audio_tts (processed) in finally: {str(e)}")
761
 
762
+ if audio_tts_original is not None:
763
+ try:
764
+ audio_tts_original.close()
765
+ except Exception as e:
766
+ logger.warning(f"Error closing audio_tts_original in finally: {str(e)}")
767
+
768
+
769
+ # Close video clips: final video (should cascade), then video base if it wasn't the final
770
+ if video_final is not None:
771
+ try:
772
+ video_final.close()
773
+ except Exception as e:
774
+ logger.warning(f"Error closing video_final in finally: {str(e)}")
775
+ # Note: video_base variable is reassigned to final_video_base. Close only if it exists and is different from video_final
776
+ elif video_base is not None and video_base is not video_final: # Check if video_base holds a different clip
777
+ try:
778
+ video_base.close()
779
+ except Exception as e:
780
+ logger.warning(f"Error closing video_base in finally: {str(e)}")
781
+
782
+
783
+ # Clean up intermediate files, but NOT the final video file
784
  if temp_dir_intermediate and os.path.exists(temp_dir_intermediate):
785
  final_output_in_temp = os.path.join(temp_dir_intermediate, "final_video.mp4")
786
 
 
801
 
802
  input_text = prompt_ia if prompt_type == "Generar Guion con IA" else prompt_manual
803
 
 
804
  output_video = None
805
  output_file = None
806
  status_msg = gr.update(value="⏳ Procesando...", interactive=False)
807
 
808
  if not input_text or not input_text.strip():
809
  logger.warning("Empty input text.")
 
810
  return None, None, gr.update(value="⚠️ Por favor, ingresa texto para el guion o el tema.", interactive=False)
811
 
812
  logger.info(f"Input Type: {prompt_type}")
 
823
  if video_path and os.path.exists(video_path):
824
  logger.info(f"crear_video returned path: {video_path}")
825
  logger.info(f"Size of returned video file: {os.path.getsize(video_path)} bytes")
826
+ output_video = video_path
827
+ output_file = video_path
828
  status_msg = gr.update(value="✅ Video generado exitosamente.", interactive=False)
829
  else:
830
  logger.error(f"crear_video did not return a valid path or file does not exist: {video_path}")
 
831
  status_msg = gr.update(value="❌ Error: La generación del video falló o el archivo no se creó correctamente.", interactive=False)
832
 
833
  except ValueError as ve:
834
  logger.warning(f"Validation error during video creation: {str(ve)}")
 
835
  status_msg = gr.update(value=f"⚠️ Error de validación: {str(ve)}", interactive=False)
836
  except Exception as e:
837
  logger.critical(f"Critical error during video creation: {str(e)}", exc_info=True)
 
838
  status_msg = gr.update(value=f"❌ Error inesperado: {str(e)}", interactive=False)
839
  finally:
840
  logger.info("End of run_app handler.")
 
841
  return output_video, output_file, status_msg
842
 
843
 
 
887
 
888
  with gr.Column():
889
  video_output = gr.Video(
890
+ label="Generated Video Preview",
891
  interactive=False,
892
  height=400
893
  )
 
894
  file_output = gr.File(
895
  label="Download Video",
896
+ interactive=False,
897
+ visible=False
898
  )
899
  status_output = gr.Textbox(
900
  label="Status",
 
911
  outputs=[ia_guion_column, manual_guion_column]
912
  )
913
 
 
914
  generate_btn.click(
 
915
  lambda: (None, None, gr.update(value="⏳ Procesando... Esto puede tomar 2-5 minutos.", interactive=False)),
916
  outputs=[video_output, file_output, status_output],
917
  queue=True,
918
  ).then(
 
919
  run_app,
920
  inputs=[prompt_type, prompt_ia, prompt_manual, musica_input],
921
+ outputs=[video_output, file_output, status_output]
922
  ).then(
923
+ lambda video_path, file_path: gr.update(visible=video_path is not None or file_path is not None), # Show download if either video or file path is returned
924
+ inputs=[video_output, file_output],
925
+ outputs=[file_output]
 
926
  )
927
 
928