siddhartharyaai commited on
Commit
657a1e4
·
verified ·
1 Parent(s): fb75dfe

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +48 -22
app.py CHANGED
@@ -20,12 +20,23 @@ from utils import (
20
  DialogueItem
21
  )
22
  from prompts import SYSTEM_PROMPT
23
- # Q&A
 
24
  from qa import transcribe_audio_deepgram, handle_qa_exchange
25
 
26
- MAX_QA_QUESTIONS = 5
27
 
28
  def parse_user_edited_transcript(edited_text: str, host_name: str, guest_name: str):
 
 
 
 
 
 
 
 
 
 
29
  pattern = r"\*\*(.+?)\*\*:\s*(.+)"
30
  matches = re.findall(pattern, edited_text)
31
 
@@ -60,9 +71,14 @@ def parse_user_edited_transcript(edited_text: str, host_name: str, guest_name: s
60
  return items
61
 
62
  def regenerate_audio_from_dialogue(dialogue_items, custom_bg_music_path=None):
 
 
 
 
 
63
  audio_segments = []
64
  transcript = ""
65
- crossfade_duration = 50
66
 
67
  for item in dialogue_items:
68
  audio_file = generate_audio_mp3(item.text, item.speaker)
@@ -106,6 +122,12 @@ def generate_podcast(
106
  sponsor_style,
107
  custom_bg_music_path
108
  ):
 
 
 
 
 
 
109
  sources = [bool(file), bool(url), bool(video_url), bool(research_topic_input)]
110
  if sum(sources) > 1:
111
  return None, "Provide only one input (PDF, URL, YouTube, or Topic)."
@@ -143,6 +165,7 @@ def generate_podcast(
143
  except Exception as e:
144
  return None, f"Error researching topic: {str(e)}"
145
 
 
146
  text = truncate_text(text)
147
 
148
  extra_instructions = []
@@ -154,13 +177,10 @@ def generate_podcast(
154
  if user_specs.strip():
155
  extra_instructions.append(f"Additional User Instructions: {user_specs}")
156
 
157
- # If user provided sponsor content, we pass it along; otherwise skip
158
- sponsor_instructions_present = False
159
  if sponsor_content.strip():
160
  extra_instructions.append(
161
  f"Sponsor Content Provided (should be under ~30 seconds):\n{sponsor_content}"
162
  )
163
- sponsor_instructions_present = True
164
 
165
  from prompts import SYSTEM_PROMPT
166
  combined_instructions = "\n\n".join(extra_instructions).strip()
@@ -177,7 +197,7 @@ def generate_podcast(
177
  f"{length_minutes} Mins",
178
  host_name=host_name or "Jane",
179
  guest_name=guest_name or "John",
180
- sponsor_style=sponsor_style # If sponsor is empty, no sponsor lines appended
181
  )
182
  except Exception as e:
183
  return None, f"Error generating script: {str(e)}"
@@ -230,7 +250,7 @@ def highlight_differences(original: str, edited: str) -> str:
230
 
231
  def main():
232
  st.set_page_config(
233
- page_title="MyPod v2: AI-based Podcast Generator",
234
  layout="centered"
235
  )
236
 
@@ -238,7 +258,7 @@ def main():
238
  with logo_col:
239
  st.image("logomypod.jpg", width=60)
240
  with title_col:
241
- st.markdown("## MyPod v2: AI powered Podcast Generator")
242
 
243
  st.markdown(
244
  "Welcome to **MyPod**, your go-to AI-powered podcast generator! 🎉\n\n"
@@ -246,7 +266,7 @@ def main():
246
  "conversational podcast.\n"
247
  "Select a tone and a duration range. The script will be on-topic, concise, and respect your chosen length.\n\n"
248
  "### How to use:\n"
249
- "1. **Provide one source:** PDF Files, Website URL, YouTube link or a Topic to Research.\n"
250
  "2. **Choose the tone and the target duration.**\n"
251
  "3. **Click 'Generate Podcast'** to produce your podcast. After the audio is generated, "
252
  " you can edit the transcript and re-generate the audio with your edits if needed.\n\n"
@@ -271,14 +291,17 @@ def main():
271
  st.markdown("### Customize Your Podcast (New Features)")
272
 
273
  with st.expander("Set Host & Guest Names/Descriptions (Optional)"):
274
- host_name = st.text_input("Female Host Name (leave blank for 'Jane')")
275
- host_desc = st.text_input("Female Host Description (Optional)")
276
- guest_name = st.text_input("Male Guest Name (leave blank for 'John')")
277
- guest_desc = st.text_input("Male Guest Description (Optional)")
278
 
279
  user_specs = st.text_area("Any special instructions or prompts for the script? (Optional)", "")
280
  sponsor_content = st.text_area("Sponsored Content / Ad (Optional)", "")
281
- sponsor_style = st.selectbox("Sponsor Integration Style", ["Separate Break", "Blended"])
 
 
 
282
 
283
  custom_bg_music_file = st.file_uploader("Upload Custom Background Music (Optional)", type=["mp3", "wav"])
284
  custom_bg_music_path = None
@@ -293,6 +316,7 @@ def main():
293
  st.session_state["transcript"] = None
294
  if "transcript_original" not in st.session_state:
295
  st.session_state["transcript_original"] = None
 
296
  if "qa_count" not in st.session_state:
297
  st.session_state["qa_count"] = 0
298
  if "conversation_history" not in st.session_state:
@@ -357,6 +381,7 @@ def main():
357
  st.session_state["audio_bytes"] = audio_bytes
358
  st.session_state["transcript"] = transcript
359
  st.session_state["transcript_original"] = transcript
 
360
  st.session_state["qa_count"] = 0
361
  st.session_state["conversation_history"] = ""
362
 
@@ -381,6 +406,7 @@ def main():
381
  st.session_state["transcript_original"],
382
  edited_text
383
  )
 
384
  st.markdown("### **Edited Transcript Highlights**", unsafe_allow_html=True)
385
  st.markdown(highlighted_transcript, unsafe_allow_html=True)
386
 
@@ -428,9 +454,9 @@ def main():
428
  st.markdown("### Updated Transcript")
429
  st.markdown(new_transcript)
430
 
431
- # -------------------------------------------
432
- # Post-Podcast Q&A using st.audio_input():
433
- # -------------------------------------------
434
  st.markdown("## Post-Podcast Q&A")
435
  used_questions = st.session_state["qa_count"]
436
  remaining = MAX_QA_QUESTIONS - used_questions
@@ -439,7 +465,6 @@ def main():
439
  st.write(f"You can ask up to {remaining} more question(s).")
440
 
441
  typed_q = st.text_input("Type your follow-up question:")
442
- # Replacing file_uploader with st.audio_input (Streamlit >= 1.41)
443
  audio_q = st.audio_input("Or record an audio question (WAV)")
444
 
445
  if st.button("Submit Q&A"):
@@ -448,8 +473,9 @@ def main():
448
  else:
449
  question_text = typed_q.strip()
450
  if audio_q is not None:
451
- with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmp:
452
- tmp.write(audio_q.getvalue())
 
453
  local_audio_path = tmp.name
454
  st.write("Transcribing your audio question...")
455
  audio_transcript = transcribe_audio_deepgram(local_audio_path)
@@ -472,4 +498,4 @@ def main():
472
 
473
 
474
  if __name__ == "__main__":
475
- main()
 
20
  DialogueItem
21
  )
22
  from prompts import SYSTEM_PROMPT
23
+
24
+ # NEW: For Q&A
25
  from qa import transcribe_audio_deepgram, handle_qa_exchange
26
 
27
+ MAX_QA_QUESTIONS = 5 # up to 5 voice/text questions
28
 
29
  def parse_user_edited_transcript(edited_text: str, host_name: str, guest_name: str):
30
+ """
31
+ Looks for lines like:
32
+ **Angela**: Hello
33
+ **Dimitris**: Great topic...
34
+ We treat 'Angela' as the raw display_speaker, 'Hello' as text.
35
+ Then we map 'Angela' -> speaker='Jane' (if it matches host_name),
36
+ 'Dimitris' -> speaker='John' (if it matches guest_name), etc.
37
+
38
+ Returns a list of DialogueItem.
39
+ """
40
  pattern = r"\*\*(.+?)\*\*:\s*(.+)"
41
  matches = re.findall(pattern, edited_text)
42
 
 
71
  return items
72
 
73
  def regenerate_audio_from_dialogue(dialogue_items, custom_bg_music_path=None):
74
+ """
75
+ Re-generates multi-speaker audio from user-edited DialogueItems,
76
+ then mixes with background music or custom music.
77
+ Returns (audio_bytes, transcript_str).
78
+ """
79
  audio_segments = []
80
  transcript = ""
81
+ crossfade_duration = 50 # ms
82
 
83
  for item in dialogue_items:
84
  audio_file = generate_audio_mp3(item.text, item.speaker)
 
122
  sponsor_style,
123
  custom_bg_music_path
124
  ):
125
+ """
126
+ Creates a multi-speaker podcast from PDF, URL, YouTube, or a research topic.
127
+ Ensures female voice for host (Jane), male voice for guest (John).
128
+ Sponsor content is either separate or blended based on sponsor_style.
129
+ Returns (audio_bytes, transcript_str).
130
+ """
131
  sources = [bool(file), bool(url), bool(video_url), bool(research_topic_input)]
132
  if sum(sources) > 1:
133
  return None, "Provide only one input (PDF, URL, YouTube, or Topic)."
 
165
  except Exception as e:
166
  return None, f"Error researching topic: {str(e)}"
167
 
168
+ from utils import truncate_text
169
  text = truncate_text(text)
170
 
171
  extra_instructions = []
 
177
  if user_specs.strip():
178
  extra_instructions.append(f"Additional User Instructions: {user_specs}")
179
 
 
 
180
  if sponsor_content.strip():
181
  extra_instructions.append(
182
  f"Sponsor Content Provided (should be under ~30 seconds):\n{sponsor_content}"
183
  )
 
184
 
185
  from prompts import SYSTEM_PROMPT
186
  combined_instructions = "\n\n".join(extra_instructions).strip()
 
197
  f"{length_minutes} Mins",
198
  host_name=host_name or "Jane",
199
  guest_name=guest_name or "John",
200
+ sponsor_style=sponsor_style
201
  )
202
  except Exception as e:
203
  return None, f"Error generating script: {str(e)}"
 
250
 
251
  def main():
252
  st.set_page_config(
253
+ page_title="MyPod - AI-based Podcast Generator",
254
  layout="centered"
255
  )
256
 
 
258
  with logo_col:
259
  st.image("logomypod.jpg", width=60)
260
  with title_col:
261
+ st.markdown("## MyPod - AI powered Podcast Generator")
262
 
263
  st.markdown(
264
  "Welcome to **MyPod**, your go-to AI-powered podcast generator! 🎉\n\n"
 
266
  "conversational podcast.\n"
267
  "Select a tone and a duration range. The script will be on-topic, concise, and respect your chosen length.\n\n"
268
  "### How to use:\n"
269
+ "1. **Provide one source:** PDF Files, Website URL, YouTube videos, or a Topic to Research.\n"
270
  "2. **Choose the tone and the target duration.**\n"
271
  "3. **Click 'Generate Podcast'** to produce your podcast. After the audio is generated, "
272
  " you can edit the transcript and re-generate the audio with your edits if needed.\n\n"
 
291
  st.markdown("### Customize Your Podcast (New Features)")
292
 
293
  with st.expander("Set Host & Guest Names/Descriptions (Optional)"):
294
+ host_name = st.text_input("Host Name (leave blank for 'Jane')")
295
+ host_desc = st.text_input("Host Description (Optional)")
296
+ guest_name = st.text_input("Guest Name (leave blank for 'John')")
297
+ guest_desc = st.text_input("Guest Description (Optional)")
298
 
299
  user_specs = st.text_area("Any special instructions or prompts for the script? (Optional)", "")
300
  sponsor_content = st.text_area("Sponsored Content / Ad (Optional)", "")
301
+ sponsor_style = st.selectbox(
302
+ "Sponsor Integration Style",
303
+ ["Separate Break", "Blended"]
304
+ )
305
 
306
  custom_bg_music_file = st.file_uploader("Upload Custom Background Music (Optional)", type=["mp3", "wav"])
307
  custom_bg_music_path = None
 
316
  st.session_state["transcript"] = None
317
  if "transcript_original" not in st.session_state:
318
  st.session_state["transcript_original"] = None
319
+ # For Q&A
320
  if "qa_count" not in st.session_state:
321
  st.session_state["qa_count"] = 0
322
  if "conversation_history" not in st.session_state:
 
381
  st.session_state["audio_bytes"] = audio_bytes
382
  st.session_state["transcript"] = transcript
383
  st.session_state["transcript_original"] = transcript
384
+ # Reset Q&A
385
  st.session_state["qa_count"] = 0
386
  st.session_state["conversation_history"] = ""
387
 
 
406
  st.session_state["transcript_original"],
407
  edited_text
408
  )
409
+
410
  st.markdown("### **Edited Transcript Highlights**", unsafe_allow_html=True)
411
  st.markdown(highlighted_transcript, unsafe_allow_html=True)
412
 
 
454
  st.markdown("### Updated Transcript")
455
  st.markdown(new_transcript)
456
 
457
+ # -----------------------
458
+ # POST-PODCAST Q&A Logic
459
+ # -----------------------
460
  st.markdown("## Post-Podcast Q&A")
461
  used_questions = st.session_state["qa_count"]
462
  remaining = MAX_QA_QUESTIONS - used_questions
 
465
  st.write(f"You can ask up to {remaining} more question(s).")
466
 
467
  typed_q = st.text_input("Type your follow-up question:")
 
468
  audio_q = st.audio_input("Or record an audio question (WAV)")
469
 
470
  if st.button("Submit Q&A"):
 
473
  else:
474
  question_text = typed_q.strip()
475
  if audio_q is not None:
476
+ suffix = ".wav"
477
+ with tempfile.NamedTemporaryFile(delete=False, suffix=suffix) as tmp:
478
+ tmp.write(audio_q.read())
479
  local_audio_path = tmp.name
480
  st.write("Transcribing your audio question...")
481
  audio_transcript = transcribe_audio_deepgram(local_audio_path)
 
498
 
499
 
500
  if __name__ == "__main__":
501
+ main()