abhishekjoel commited on
Commit
f224e73
·
verified ·
1 Parent(s): 8a4a13a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +99 -50
app.py CHANGED
@@ -7,6 +7,8 @@ from dotenv import load_dotenv
7
  from pydub import AudioSegment
8
  import tempfile
9
  import math
 
 
10
 
11
  # Load environment variables
12
  load_dotenv()
@@ -18,21 +20,35 @@ client = openai.OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
18
  MAX_FILE_SIZE = 25 * 1024 * 1024 # 25MB in bytes
19
  CHUNK_LENGTH = 10 * 60 * 1000 # 10 minutes in milliseconds
20
 
21
- def process_audio_file(uploaded_file):
22
- """Process and potentially chunk the audio file"""
23
- # Create a temporary directory
24
- with tempfile.TemporaryDirectory() as temp_dir:
 
 
 
 
 
 
 
25
  # Save uploaded file
26
- temp_input_path = os.path.join(temp_dir, "input_audio")
27
- with open(temp_input_path, "wb") as f:
28
  f.write(uploaded_file.getvalue())
29
-
 
 
 
 
 
 
 
 
30
  # Load audio file
31
- audio = AudioSegment.from_file(temp_input_path)
32
 
33
  # If file is small enough, return it as is
34
- if os.path.getsize(temp_input_path) <= MAX_FILE_SIZE:
35
- return [temp_input_path]
36
 
37
  # Otherwise, chunk the audio
38
  chunks = []
@@ -45,18 +61,32 @@ def process_audio_file(uploaded_file):
45
 
46
  chunk = audio[start_time:end_time]
47
  chunk_path = os.path.join(temp_dir, f"chunk_{i}.mp3")
48
- chunk.export(chunk_path, format="mp3", parameters=["-ac", "1"]) # Convert to mono
 
 
 
 
 
49
  chunks.append(chunk_path)
 
 
 
 
50
 
51
  return chunks
 
 
 
52
 
53
  def transcribe_audio_chunks(chunks):
54
  """Transcribe audio chunks and combine transcriptions"""
55
  all_segments = []
56
  current_time_offset = 0
57
 
58
- for chunk_path in chunks:
59
  try:
 
 
60
  with open(chunk_path, "rb") as audio:
61
  transcript = client.audio.transcriptions.create(
62
  model="whisper-1",
@@ -75,13 +105,15 @@ def transcribe_audio_chunks(chunks):
75
  current_time_offset += len(AudioSegment.from_file(chunk_path)) / 1000 # Convert to seconds
76
 
77
  except Exception as e:
78
- st.error(f"Error in transcription: {str(e)}")
79
  return None
80
 
81
  # Combine all transcriptions
82
- full_transcript = transcript
83
- full_transcript.segments = all_segments
84
- return full_transcript
 
 
85
 
86
  def format_timestamp(seconds):
87
  """Convert seconds to HH:MM:SS format"""
@@ -124,6 +156,14 @@ def format_transcript_with_timestamps(transcript_data):
124
  formatted_text += f"**[{start_time}]** {segment.text}\n\n"
125
  return formatted_text
126
 
 
 
 
 
 
 
 
 
127
  # Streamlit UI
128
  def main():
129
  st.set_page_config(page_title="Lecture Notes Generator", layout="wide")
@@ -149,41 +189,50 @@ def main():
149
  tab1, tab2 = st.tabs(["📝 Transcript", "📋 Lesson Plan"])
150
 
151
  with st.spinner("Processing audio..."):
152
- # Process and potentially chunk the audio file
153
- chunks = process_audio_file(uploaded_file)
154
-
155
- # Transcribe chunks
156
- transcript_data = transcribe_audio_chunks(chunks)
157
 
158
- if transcript_data:
159
- # Format transcript with timestamps
160
- formatted_transcript = format_transcript_with_timestamps(transcript_data)
161
-
162
- # Generate lesson plan
163
- lesson_plan = generate_lesson_plan(transcript_data.text)
164
-
165
- # Display transcript in first tab
166
- with tab1:
167
- st.markdown(formatted_transcript)
168
- # Download button for transcript
169
- st.download_button(
170
- label="Download Transcript",
171
- data=formatted_transcript,
172
- file_name=f"transcript_{datetime.now().strftime('%Y%m%d_%H%M%S')}.md",
173
- mime="text/markdown"
174
- )
175
-
176
- # Display lesson plan in second tab
177
- with tab2:
178
- if lesson_plan:
179
- st.markdown(lesson_plan)
180
- # Download button for lesson plan
181
- st.download_button(
182
- label="Download Lesson Plan",
183
- data=lesson_plan,
184
- file_name=f"lesson_plan_{datetime.now().strftime('%Y%m%d_%H%M%S')}.md",
185
- mime="text/markdown"
186
- )
 
 
 
 
 
 
 
 
 
 
 
 
187
 
188
  # Right column instructions when no file is uploaded
189
  if not uploaded_file:
 
7
  from pydub import AudioSegment
8
  import tempfile
9
  import math
10
+ from pathlib import Path
11
+ import shutil
12
 
13
  # Load environment variables
14
  load_dotenv()
 
20
  MAX_FILE_SIZE = 25 * 1024 * 1024 # 25MB in bytes
21
  CHUNK_LENGTH = 10 * 60 * 1000 # 10 minutes in milliseconds
22
 
23
+ @st.cache_data
24
+ def save_uploaded_file(uploaded_file):
25
+ """Save uploaded file to a temporary directory and return the path"""
26
+ try:
27
+ # Create a temporary directory that persists
28
+ temp_dir = tempfile.mkdtemp()
29
+ # Get the file extension
30
+ file_extension = Path(uploaded_file.name).suffix
31
+ # Create full path with original extension
32
+ temp_path = os.path.join(temp_dir, f"input_audio{file_extension}")
33
+
34
  # Save uploaded file
35
+ with open(temp_path, "wb") as f:
 
36
  f.write(uploaded_file.getvalue())
37
+
38
+ return temp_path, temp_dir
39
+ except Exception as e:
40
+ st.error(f"Error saving file: {str(e)}")
41
+ return None, None
42
+
43
+ def process_audio_file(file_path, temp_dir):
44
+ """Process and potentially chunk the audio file"""
45
+ try:
46
  # Load audio file
47
+ audio = AudioSegment.from_file(file_path)
48
 
49
  # If file is small enough, return it as is
50
+ if os.path.getsize(file_path) <= MAX_FILE_SIZE:
51
+ return [file_path]
52
 
53
  # Otherwise, chunk the audio
54
  chunks = []
 
61
 
62
  chunk = audio[start_time:end_time]
63
  chunk_path = os.path.join(temp_dir, f"chunk_{i}.mp3")
64
+
65
+ # Export with specific parameters for better compatibility
66
+ chunk = chunk.set_channels(1) # Convert to mono
67
+ chunk = chunk.set_frame_rate(16000) # Set sample rate to 16kHz
68
+ chunk.export(chunk_path, format="mp3", parameters=["-q:a", "0"])
69
+
70
  chunks.append(chunk_path)
71
+
72
+ # Verify file exists and has size
73
+ if not os.path.exists(chunk_path) or os.path.getsize(chunk_path) == 0:
74
+ raise Exception(f"Failed to create chunk {i}")
75
 
76
  return chunks
77
+ except Exception as e:
78
+ st.error(f"Error processing audio: {str(e)}")
79
+ return None
80
 
81
  def transcribe_audio_chunks(chunks):
82
  """Transcribe audio chunks and combine transcriptions"""
83
  all_segments = []
84
  current_time_offset = 0
85
 
86
+ for i, chunk_path in enumerate(chunks):
87
  try:
88
+ st.write(f"Processing chunk {i+1} of {len(chunks)}...")
89
+
90
  with open(chunk_path, "rb") as audio:
91
  transcript = client.audio.transcriptions.create(
92
  model="whisper-1",
 
105
  current_time_offset += len(AudioSegment.from_file(chunk_path)) / 1000 # Convert to seconds
106
 
107
  except Exception as e:
108
+ st.error(f"Error in transcription of chunk {i+1}: {str(e)}")
109
  return None
110
 
111
  # Combine all transcriptions
112
+ if transcript and all_segments:
113
+ full_transcript = transcript
114
+ full_transcript.segments = all_segments
115
+ return full_transcript
116
+ return None
117
 
118
  def format_timestamp(seconds):
119
  """Convert seconds to HH:MM:SS format"""
 
156
  formatted_text += f"**[{start_time}]** {segment.text}\n\n"
157
  return formatted_text
158
 
159
+ def cleanup_files(temp_dir):
160
+ """Safely clean up temporary files"""
161
+ try:
162
+ if temp_dir and os.path.exists(temp_dir):
163
+ shutil.rmtree(temp_dir)
164
+ except Exception as e:
165
+ st.warning(f"Warning: Could not clean up temporary files: {str(e)}")
166
+
167
  # Streamlit UI
168
  def main():
169
  st.set_page_config(page_title="Lecture Notes Generator", layout="wide")
 
189
  tab1, tab2 = st.tabs(["📝 Transcript", "📋 Lesson Plan"])
190
 
191
  with st.spinner("Processing audio..."):
192
+ # Save uploaded file and get temporary paths
193
+ temp_path, temp_dir = save_uploaded_file(uploaded_file)
 
 
 
194
 
195
+ if temp_path and temp_dir:
196
+ try:
197
+ # Process and potentially chunk the audio file
198
+ chunks = process_audio_file(temp_path, temp_dir)
199
+
200
+ if chunks:
201
+ # Transcribe chunks
202
+ transcript_data = transcribe_audio_chunks(chunks)
203
+
204
+ if transcript_data:
205
+ # Format transcript with timestamps
206
+ formatted_transcript = format_transcript_with_timestamps(transcript_data)
207
+
208
+ # Generate lesson plan
209
+ lesson_plan = generate_lesson_plan(transcript_data.text)
210
+
211
+ # Display transcript in first tab
212
+ with tab1:
213
+ st.markdown(formatted_transcript)
214
+ # Download button for transcript
215
+ st.download_button(
216
+ label="Download Transcript",
217
+ data=formatted_transcript,
218
+ file_name=f"transcript_{datetime.now().strftime('%Y%m%d_%H%M%S')}.md",
219
+ mime="text/markdown"
220
+ )
221
+
222
+ # Display lesson plan in second tab
223
+ with tab2:
224
+ if lesson_plan:
225
+ st.markdown(lesson_plan)
226
+ # Download button for lesson plan
227
+ st.download_button(
228
+ label="Download Lesson Plan",
229
+ data=lesson_plan,
230
+ file_name=f"lesson_plan_{datetime.now().strftime('%Y%m%d_%H%M%S')}.md",
231
+ mime="text/markdown"
232
+ )
233
+ finally:
234
+ # Clean up temporary files
235
+ cleanup_files(temp_dir)
236
 
237
  # Right column instructions when no file is uploaded
238
  if not uploaded_file: