amirjamali commited on
Commit
6f0cad3
·
unverified ·
1 Parent(s): ccf2172

Update Dockerfile and Streamlit app; add additional system dependencies and improve audio processing error handling

Browse files
Files changed (2) hide show
  1. Dockerfile +4 -0
  2. src/streamlit_app.py +64 -20
Dockerfile CHANGED
@@ -21,6 +21,10 @@ RUN apt-get update && \
21
  git \
22
  ffmpeg \
23
  libsndfile1 \
 
 
 
 
24
  && apt-get clean \
25
  && rm -rf /var/lib/apt/lists/*
26
 
 
21
  git \
22
  ffmpeg \
23
  libsndfile1 \
24
+ libgl1-mesa-glx \
25
+ python3-tk \
26
+ libavcodec-extra \
27
+ libavformat-dev \
28
  && apt-get clean \
29
  && rm -rf /var/lib/apt/lists/*
30
 
src/streamlit_app.py CHANGED
@@ -491,10 +491,17 @@ def process_uploaded_audio(file_input):
491
  Args:
492
  file_input: Either a StreamlitUploadedFile object or a string path to a file
493
  """
 
 
 
494
  try:
495
  # Create a unique filename based on timestamp
496
  timestamp = str(int(time.time()))
497
 
 
 
 
 
498
  # Handle different input types
499
  if isinstance(file_input, str):
500
  # If it's already a file path
@@ -505,15 +512,12 @@ def process_uploaded_audio(file_input):
505
  # If it's a StreamlitUploadedFile
506
  file_extension = os.path.splitext(file_input.name)[1].lower()
507
 
508
- # Create an uploads directory if it doesn't exist
509
- uploads_dir = os.path.join(os.getcwd(), "uploads")
510
- os.makedirs(uploads_dir, exist_ok=True)
511
-
512
  # Write the uploaded file to disk with proper extension in the uploads directory
513
  temp_input_path = os.path.join(uploads_dir, f"uploaded_audio_{timestamp}{file_extension}")
514
  with open(temp_input_path, "wb") as f:
515
  f.write(file_input.getbuffer())
516
- # For MP4 files, extract the audio using ffmpeg
 
517
  if file_extension == ".mp4":
518
  st.info("Extracting audio from video file...")
519
  audio_path = os.path.join(uploads_dir, f"extracted_audio_{timestamp}.wav")
@@ -527,7 +531,8 @@ def process_uploaded_audio(file_input):
527
  os.remove(temp_input_path)
528
  except subprocess.CalledProcessError as e:
529
  st.error(f"Error extracting audio: {e}")
530
- st.error(f"ffmpeg output: {e.stderr.decode('utf-8')}")
 
531
  raise
532
  else:
533
  # For audio files, process based on format
@@ -535,14 +540,23 @@ def process_uploaded_audio(file_input):
535
  # Convert to WAV for better compatibility
536
  audio_path = os.path.join(uploads_dir, f"converted_audio_{timestamp}.wav")
537
  try:
538
- subprocess.run(
539
- ['ffmpeg', '-i', temp_input_path, '-ar', '16000', '-ac', '1', '-c:a', 'pcm_s16le', audio_path],
 
540
  check=True,
541
  capture_output=True
542
  )
543
- # Keep original file for reference but continue with WAV
 
 
 
 
 
544
  except subprocess.CalledProcessError as e:
545
- st.warning(f"Conversion warning: {e}. Using original file.")
 
 
 
546
  audio_path = temp_input_path
547
  else:
548
  # For already WAV files, use them directly
@@ -552,18 +566,47 @@ def process_uploaded_audio(file_input):
552
  results = detector.analyze_audio(audio_path)
553
 
554
  # Clean up
555
- if os.path.exists(audio_path):
556
  os.remove(audio_path)
557
 
558
  return results
559
 
560
  except Exception as e:
561
- st.error(f"Error processing audio: {str(e)}")
562
- if 'temp_input_path' in locals() and os.path.exists(temp_input_path):
 
 
 
 
 
 
 
 
563
  os.remove(temp_input_path)
564
- if 'audio_path' in locals() and os.path.exists(audio_path):
 
 
 
 
 
565
  os.remove(audio_path)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
566
  raise
 
567
  return results
568
 
569
  # --- Streamlit App ---
@@ -690,14 +733,15 @@ with tab1:
690
  # Show explanation in a box
691
  st.markdown("### Expert Analysis")
692
  st.info(results['explanation'])
693
-
694
- with col2:
695
  if results['audio_viz']:
696
  try:
697
  st.pyplot(results['audio_viz'])
698
  except Exception as viz_error:
699
  st.warning("Could not display visualization due to torchvision issue.")
700
- st.info("Audio analysis was successful even though visualization failed.") # Show audio playback
 
 
701
  st.audio(audio_path)
702
 
703
  # Clean up files
@@ -763,15 +807,15 @@ with tab2:
763
  # First save the file to a known location to bypass 403 errors
764
  # Create an uploads directory if it doesn't exist
765
  uploads_dir = os.path.join(os.getcwd(), "uploads")
766
- os.makedirs(uploads_dir, exist_ok=True)
767
- # Save the file first to avoid streaming it multiple times
768
  temp_file_path = os.path.join(uploads_dir, f"temp_{int(time.time())}_{uploaded_file.name}")
769
  with open(temp_file_path, "wb") as f:
770
  f.write(uploaded_file.getbuffer())
771
 
772
  progress_bar.progress(50, text="Analyzing audio...")
773
 
774
- # Process using the saved file path directly results = process_uploaded_audio(temp_file_path)
 
775
 
776
  progress_bar.progress(100, text="Analysis complete!")
777
  # Display results
 
491
  Args:
492
  file_input: Either a StreamlitUploadedFile object or a string path to a file
493
  """
494
+ audio_path = None
495
+ temp_input_path = None
496
+
497
  try:
498
  # Create a unique filename based on timestamp
499
  timestamp = str(int(time.time()))
500
 
501
+ # Create an uploads directory if it doesn't exist - we'll need this regardless
502
+ uploads_dir = os.path.join(os.getcwd(), "uploads")
503
+ os.makedirs(uploads_dir, exist_ok=True)
504
+
505
  # Handle different input types
506
  if isinstance(file_input, str):
507
  # If it's already a file path
 
512
  # If it's a StreamlitUploadedFile
513
  file_extension = os.path.splitext(file_input.name)[1].lower()
514
 
 
 
 
 
515
  # Write the uploaded file to disk with proper extension in the uploads directory
516
  temp_input_path = os.path.join(uploads_dir, f"uploaded_audio_{timestamp}{file_extension}")
517
  with open(temp_input_path, "wb") as f:
518
  f.write(file_input.getbuffer())
519
+
520
+ # For MP4 files, extract the audio using ffmpeg
521
  if file_extension == ".mp4":
522
  st.info("Extracting audio from video file...")
523
  audio_path = os.path.join(uploads_dir, f"extracted_audio_{timestamp}.wav")
 
531
  os.remove(temp_input_path)
532
  except subprocess.CalledProcessError as e:
533
  st.error(f"Error extracting audio: {e}")
534
+ if e.stderr:
535
+ st.error(f"FFmpeg output: {e.stderr.decode('utf-8')}")
536
  raise
537
  else:
538
  # For audio files, process based on format
 
540
  # Convert to WAV for better compatibility
541
  audio_path = os.path.join(uploads_dir, f"converted_audio_{timestamp}.wav")
542
  try:
543
+ # Use a verbose ffmpeg command with detailed logging
544
+ process = subprocess.run(
545
+ ['ffmpeg', '-i', temp_input_path, '-ar', '16000', '-ac', '1', '-c:a', 'pcm_s16le', '-y', audio_path],
546
  check=True,
547
  capture_output=True
548
  )
549
+
550
+ # Verify the file was created
551
+ if not os.path.exists(audio_path) or os.path.getsize(audio_path) == 0:
552
+ st.warning("Conversion produced an empty file. Using original file.")
553
+ audio_path = temp_input_path
554
+
555
  except subprocess.CalledProcessError as e:
556
+ st.warning(f"Conversion warning: {e}")
557
+ if e.stderr:
558
+ st.warning(f"FFmpeg error: {e.stderr.decode('utf-8')}")
559
+ st.info("Using original file instead.")
560
  audio_path = temp_input_path
561
  else:
562
  # For already WAV files, use them directly
 
566
  results = detector.analyze_audio(audio_path)
567
 
568
  # Clean up
569
+ if audio_path and audio_path != temp_input_path and os.path.exists(audio_path):
570
  os.remove(audio_path)
571
 
572
  return results
573
 
574
  except Exception as e:
575
+ error_msg = str(e)
576
+ st.error(f"Error processing audio: {error_msg}")
577
+
578
+ # Add detailed debugging info
579
+ import traceback
580
+ st.error(f"Error details: {traceback.format_exc()}")
581
+
582
+ # Show file info if available
583
+ if temp_input_path and os.path.exists(temp_input_path):
584
+ st.info(f"Input file exists: {temp_input_path}, size: {os.path.getsize(temp_input_path)} bytes")
585
  os.remove(temp_input_path)
586
+ else:
587
+ if temp_input_path:
588
+ st.warning(f"Input file does not exist: {temp_input_path}")
589
+
590
+ if audio_path and os.path.exists(audio_path):
591
+ st.info(f"Audio file exists: {audio_path}, size: {os.path.getsize(audio_path)} bytes")
592
  os.remove(audio_path)
593
+ else:
594
+ if audio_path:
595
+ st.warning(f"Audio file does not exist: {audio_path}")
596
+
597
+ # Check for common error types
598
+ if "ffmpeg" in error_msg.lower():
599
+ st.warning("FFmpeg error detected. The audio conversion failed.")
600
+ st.info("Try a different audio format or check if FFmpeg is installed correctly.")
601
+ elif "permission" in error_msg.lower():
602
+ st.warning("Permission error detected.")
603
+ st.info("Check that the uploads directory is writable.")
604
+ elif "no such file" in error_msg.lower():
605
+ st.warning("File not found error detected.")
606
+ st.info("The file may have been moved, deleted, or not saved correctly.")
607
+
608
  raise
609
+
610
  return results
611
 
612
  # --- Streamlit App ---
 
733
  # Show explanation in a box
734
  st.markdown("### Expert Analysis")
735
  st.info(results['explanation'])
736
+ with col2:
 
737
  if results['audio_viz']:
738
  try:
739
  st.pyplot(results['audio_viz'])
740
  except Exception as viz_error:
741
  st.warning("Could not display visualization due to torchvision issue.")
742
+ st.info("Audio analysis was successful even though visualization failed.")
743
+
744
+ # Show audio playback
745
  st.audio(audio_path)
746
 
747
  # Clean up files
 
807
  # First save the file to a known location to bypass 403 errors
808
  # Create an uploads directory if it doesn't exist
809
  uploads_dir = os.path.join(os.getcwd(), "uploads")
810
+ os.makedirs(uploads_dir, exist_ok=True) # Save the file first to avoid streaming it multiple times
 
811
  temp_file_path = os.path.join(uploads_dir, f"temp_{int(time.time())}_{uploaded_file.name}")
812
  with open(temp_file_path, "wb") as f:
813
  f.write(uploaded_file.getbuffer())
814
 
815
  progress_bar.progress(50, text="Analyzing audio...")
816
 
817
+ # Process using the saved file path directly
818
+ results = process_uploaded_audio(temp_file_path)
819
 
820
  progress_bar.progress(100, text="Analysis complete!")
821
  # Display results