syed7 commited on
Commit
18ac61e
·
verified ·
1 Parent(s): 533ac21

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +79 -66
app.py CHANGED
@@ -1,95 +1,108 @@
1
  import streamlit as st
 
2
  import numpy as np
3
- from io import BytesIO
4
- import tempfile
5
- import os
6
- from pydub import AudioSegment
7
  import time
8
 
 
 
 
 
 
 
 
 
 
 
9
  def main():
10
  st.title("Audio Recorder App")
11
 
12
- # Add a description
13
- st.write("Click the microphone button below to start recording")
14
 
15
  # Create a placeholder for status messages
16
  status_placeholder = st.empty()
17
 
18
- # Add the audio recorder
19
- audio_bytes = st.audio_recorder(
20
- pause_threshold=2.0, # Automatically stops recording after 2 seconds of silence
21
- sample_rate=44100
22
- )
 
23
 
24
- if audio_bytes:
25
- try:
26
- # Show success message
27
- status_placeholder.success("Recording captured successfully!")
28
-
29
- # Create a temporary file to store the audio
30
- with tempfile.NamedTemporaryFile(delete=False, suffix='.wav') as tmp_file:
31
- tmp_file.write(audio_bytes)
32
- tmp_path = tmp_file.name
33
-
34
- # Display the audio player
35
- st.audio(audio_bytes, format='audio/wav')
36
-
37
- # Add download button
38
- st.download_button(
39
- label="Download Recording",
40
- data=audio_bytes,
41
- file_name="recording.wav",
42
- mime="audio/wav"
43
- )
44
 
45
- # Convert to AudioSegment for analysis
46
- audio = AudioSegment.from_wav(tmp_path)
47
-
48
- # Display audio information
49
- st.subheader("Audio Information")
50
- col1, col2, col3 = st.columns(3)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
- with col1:
53
- st.metric("Duration", f"{len(audio)/1000:.2f} seconds")
54
- with col2:
55
- st.metric("Channels", audio.channels)
56
- with col3:
57
- st.metric("Sample Rate", f"{audio.frame_rate} Hz")
58
 
59
- # Clean up temporary file
60
- os.unlink(tmp_path)
61
 
62
- # Add processing options
63
- st.subheader("Audio Processing Options")
64
- if st.button("Normalize Audio"):
65
- normalized_audio = audio.normalize()
66
- normalized_bytes = normalized_audio.export(format='wav').read()
67
- st.audio(normalized_bytes, format='audio/wav')
68
  st.download_button(
69
- label="Download Normalized Audio",
70
- data=normalized_bytes,
71
- file_name="normalized_recording.wav",
72
- mime="audio/wav"
73
  )
74
-
75
- except Exception as e:
76
- status_placeholder.error(f"Error processing audio: {str(e)}")
77
- st.stop()
78
 
79
  # Add instructions
80
  with st.expander("How to use"):
81
  st.markdown("""
82
- 1. Click the microphone button to start recording
83
- 2. Speak into your microphone
84
- 3. Click the button again to stop recording
85
- 4. Your recording will appear above with playback controls
86
  5. Use the download button to save your recording
87
- 6. Optional: Use the Normalize Audio button to improve audio quality
 
88
  """)
89
 
90
- # Add footer
91
  st.markdown("---")
92
- st.caption("Note: Recording quality depends on your microphone and browser settings")
93
 
94
  if __name__ == "__main__":
95
  main()
 
1
  import streamlit as st
2
+ from streamlit_webrtc import webrtc_streamer, WebRtcMode
3
  import numpy as np
4
+ import av
5
+ import queue
6
+ import threading
7
+ from typing import List, NamedTuple
8
  import time
9
 
10
+ # Audio recording class
11
+ class AudioFrame(NamedTuple):
12
+ data: np.ndarray
13
+ timestamp: float
14
+
15
+ # Global variables for recording state
16
+ AUDIO_BUFFER: queue.Queue = queue.Queue()
17
+ RECORDING = False
18
+ AUDIO_FRAMES: List[AudioFrame] = []
19
+
20
  def main():
21
  st.title("Audio Recorder App")
22
 
23
+ # Add description
24
+ st.write("Click 'Start' to begin recording audio")
25
 
26
  # Create a placeholder for status messages
27
  status_placeholder = st.empty()
28
 
29
+ # Recording controls
30
+ col1, col2 = st.columns(2)
31
+ with col1:
32
+ start_button = st.button("Start Recording")
33
+ with col2:
34
+ stop_button = st.button("Stop Recording")
35
 
36
+ def audio_callback(frame: av.AudioFrame) -> av.AudioFrame:
37
+ global RECORDING, AUDIO_FRAMES
38
+
39
+ if RECORDING:
40
+ # Convert audio frame to numpy array
41
+ audio_data = frame.to_ndarray()
42
+ timestamp = time.time()
43
+ AUDIO_FRAMES.append(AudioFrame(audio_data, timestamp))
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
+ # Update status
46
+ status_placeholder.info(f"Recording... Duration: {len(AUDIO_FRAMES) * 0.02:.1f}s")
47
+
48
+ return frame
49
+
50
+ # Initialize WebRTC component
51
+ ctx = webrtc_streamer(
52
+ key="audio-recorder",
53
+ mode=WebRtcMode.SENDONLY,
54
+ audio_receiver_size=256,
55
+ rtc_configuration={
56
+ "iceServers": [{"urls": ["stun:stun.l.google.com:19302"]}]
57
+ },
58
+ media_stream_constraints={"video": False, "audio": True},
59
+ audio_callback=audio_callback,
60
+ )
61
+
62
+ # Handle recording controls
63
+ if start_button:
64
+ RECORDING = True
65
+ AUDIO_FRAMES.clear()
66
+ status_placeholder.info("Starting recording...")
67
+
68
+ if stop_button:
69
+ RECORDING = False
70
+ if len(AUDIO_FRAMES) > 0:
71
+ # Combine all audio frames
72
+ all_audio = np.concatenate([frame.data for frame in AUDIO_FRAMES])
73
 
74
+ # Save as numpy array
75
+ np.save("recorded_audio.npy", all_audio)
 
 
 
 
76
 
77
+ # Show success message
78
+ status_placeholder.success(f"Recording saved! Duration: {len(AUDIO_FRAMES) * 0.02:.1f} seconds")
79
 
80
+ # Add download button for the numpy array
81
+ with open("recorded_audio.npy", "rb") as file:
 
 
 
 
82
  st.download_button(
83
+ label="Download Recording",
84
+ data=file,
85
+ file_name="recorded_audio.npy",
86
+ mime="application/octet-stream"
87
  )
88
+ else:
89
+ status_placeholder.warning("No audio recorded")
 
 
90
 
91
  # Add instructions
92
  with st.expander("How to use"):
93
  st.markdown("""
94
+ 1. Allow microphone access when prompted
95
+ 2. Click 'Start Recording' to begin
96
+ 3. Speak into your microphone
97
+ 4. Click 'Stop Recording' when finished
98
  5. Use the download button to save your recording
99
+
100
+ Note: You may need to click 'Start' in the WebRTC player above first.
101
  """)
102
 
103
+ # Add requirements info
104
  st.markdown("---")
105
+ st.caption("Required packages: streamlit-webrtc, numpy, av")
106
 
107
  if __name__ == "__main__":
108
  main()