siddhartharyaai commited on
Commit
aa1b4ab
·
verified ·
1 Parent(s): e7e42ff

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +215 -0
app.py ADDED
@@ -0,0 +1,215 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app.py
2
+
3
+ import streamlit as st
4
+ from utils import (
5
+ generate_script,
6
+ generate_audio_mp3, # Updated import
7
+ truncate_text,
8
+ extract_text_from_url,
9
+ transcribe_youtube_video,
10
+ research_topic
11
+ )
12
+ from prompts import SYSTEM_PROMPT # Ensure this module exists
13
+ import pypdf
14
+ from pydub import AudioSegment
15
+ import tempfile
16
+ import os
17
+
18
+ def generate_podcast(file, url, video_url, research_topic_input, tone, length):
19
+ print("[LOG] generate_podcast called")
20
+
21
+ # Check that only one input source is used
22
+ sources = [bool(file), bool(url), bool(video_url), bool(research_topic_input)]
23
+ if sum(sources) > 1:
24
+ print("[ERROR] Multiple input sources provided.")
25
+ return None, "Please provide either a PDF file, a URL, a YouTube link, or a Research topic - not multiple."
26
+ if not any(sources):
27
+ print("[ERROR] No input source provided.")
28
+ return None, "Please provide at least one source."
29
+
30
+ text = ""
31
+ if file:
32
+ try:
33
+ print("[LOG] Reading PDF file:", file.name)
34
+ if not file.name.lower().endswith('.pdf'):
35
+ print("[ERROR] Uploaded file is not a PDF.")
36
+ return None, "Please upload a PDF file."
37
+ reader = pypdf.PdfReader(file.name)
38
+ text = " ".join(page.extract_text() for page in reader.pages if page.extract_text())
39
+ print("[LOG] PDF text extraction successful.")
40
+ except Exception as e:
41
+ print("[ERROR] Error reading PDF file:", e)
42
+ return None, f"Error reading PDF file: {str(e)}"
43
+ elif url:
44
+ try:
45
+ print("[LOG] Using URL input")
46
+ text = extract_text_from_url(url)
47
+ if not text:
48
+ print("[ERROR] Failed to extract text from URL.")
49
+ return None, "Failed to extract text from the provided URL."
50
+ except Exception as e:
51
+ print("[ERROR] Error extracting text from URL:", e)
52
+ return None, f"Error extracting text from URL: {str(e)}"
53
+ elif video_url:
54
+ try:
55
+ print("[LOG] Using YouTube video input")
56
+ text = transcribe_youtube_video(video_url)
57
+ if not text:
58
+ print("[ERROR] Failed to transcribe YouTube video.")
59
+ return None, "Failed to transcribe the provided YouTube video."
60
+ except Exception as e:
61
+ print("[ERROR] Error transcribing YouTube video:", e)
62
+ return None, f"Error transcribing YouTube video: {str(e)}"
63
+ elif research_topic_input:
64
+ try:
65
+ print("[LOG] Researching topic:", research_topic_input)
66
+ text = research_topic(research_topic_input)
67
+ if not text:
68
+ print("[ERROR] No information found for the topic.")
69
+ return None, f"Sorry, I couldn't find recent information on '{research_topic_input}'."
70
+ except Exception as e:
71
+ print("[ERROR] Error researching topic:", e)
72
+ return None, f"Error researching topic: {str(e)}"
73
+ else:
74
+ print("[ERROR] No valid input source detected.")
75
+ return None, "Please provide a PDF file, URL, YouTube link, or Research topic."
76
+
77
+ try:
78
+ text = truncate_text(text)
79
+ script = generate_script(SYSTEM_PROMPT, text, tone, length)
80
+ except Exception as e:
81
+ print("[ERROR] Error generating script:", e)
82
+ return None, f"Error generating script: {str(e)}"
83
+
84
+ audio_segments = []
85
+ transcript = ""
86
+
87
+ try:
88
+ print("[LOG] Generating audio segments...")
89
+ # Define crossfade duration in milliseconds
90
+ crossfade_duration = 50 # 50ms crossfade for smooth transitions
91
+
92
+ for i, item in enumerate(script.dialogue):
93
+ try:
94
+ audio_file = generate_audio_mp3(item.text, item.speaker) # Updated function call
95
+ line_audio = AudioSegment.from_file(audio_file, format="mp3") # Changed format to mp3
96
+ audio_segments.append(line_audio)
97
+ transcript += f"**{item.speaker}**: {item.text}\n\n"
98
+ os.remove(audio_file)
99
+ except Exception as e:
100
+ print(f"[ERROR] Error generating audio for dialogue item {i+1}: {e}")
101
+ continue
102
+
103
+ if not audio_segments:
104
+ print("[ERROR] No audio segments were generated.")
105
+ return None, "No audio segments were generated."
106
+
107
+ print("[LOG] Combining audio segments with crossfades...")
108
+ # Initialize combined audio with the first segment
109
+ combined = audio_segments[0]
110
+
111
+ # Append remaining segments with crossfade
112
+ for seg in audio_segments[1:]:
113
+ combined = combined.append(seg, crossfade=crossfade_duration)
114
+
115
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as temp_audio: # Changed suffix to mp3
116
+ combined.export(temp_audio.name, format="mp3") # Changed format to mp3
117
+ print("[LOG] Podcast generated:", temp_audio.name)
118
+ return temp_audio.name, transcript
119
+
120
+ except Exception as e:
121
+ print("[ERROR] Error generating audio:", e)
122
+ return None, f"Error generating audio: {str(e)}"
123
+
124
+ def main():
125
+ # Set Streamlit page config
126
+ st.set_page_config(
127
+ page_title="MyPod - AI based Podcast Generator",
128
+ layout="centered"
129
+ )
130
+
131
+ st.title("🎙 MyPod - AI-based Podcast Generator")
132
+ st.markdown(
133
+ """
134
+ <style>
135
+ .main {
136
+ background-color: #f9f9f9;
137
+ }
138
+ .block-container {
139
+ padding: 2rem;
140
+ border-radius: 10px;
141
+ background-color: #ffffff;
142
+ box-shadow: 0 0 10px rgba(0,0,0,0.1);
143
+ }
144
+ </style>
145
+ """,
146
+ unsafe_allow_html=True
147
+ )
148
+
149
+ st.markdown(
150
+ "Welcome to **MyPod**, your go-to AI-powered podcast generator! 🎉\n\n"
151
+ "MyPod transforms your documents, webpages, YouTube videos, or research topics into a more human-sounding, conversational podcast.\n"
152
+ "Select a tone and a duration range. The script will be on-topic, concise, and respect your chosen length.\n\n"
153
+ "### How to use:\n"
154
+ "1. **Provide one source:** PDF, URL, YouTube link (Requires User Auth - Work in Progress), or a Topic to Research.\n"
155
+ "2. **Choose the tone and the target duration.**\n"
156
+ "3. **Click 'Generate Podcast'** to produce your podcast.\n\n"
157
+ "**Research a Topic:** Please be as detailed as possible in your topic statement. If it's too niche or specific, "
158
+ "you might not get the desired outcome. We'll fetch information from Wikipedia and RSS feeds (BBC, CNN, Associated Press, "
159
+ "NDTV, Times of India, The Hindu, Economic Times, Google News) or the LLM knowledge base to get recent info about the topic.\n\n"
160
+ "**Token Limit:** Up to ~2,048 tokens are supported. Long inputs may be truncated.\n"
161
+ "**Note:** YouTube transcription uses Whisper on CPU and may take longer for very long videos.\n\n"
162
+ "⏳**Please be patient while your podcast is being generated.** This process involves content analysis, script creation, "
163
+ "and high-quality audio synthesis, which may take a few minutes.\n\n"
164
+ "🔥 **Ready to create your personalized podcast?** Give it a try now and let the magic happen! 🔥"
165
+ )
166
+
167
+ st.write("---")
168
+
169
+ # Create 2 columns for inputs
170
+ col1, col2 = st.columns(2)
171
+
172
+ with col1:
173
+ file = st.file_uploader("Upload PDF (Only .pdf)", type=["pdf"])
174
+ url = st.text_input("Or Enter URL")
175
+ video_url = st.text_input("Or Enter YouTube Link (Requires User Auth - Work in Progress)")
176
+
177
+ with col2:
178
+ research_topic_input = st.text_input("Or Research a Topic")
179
+ tone = st.radio(
180
+ "Tone",
181
+ ["Humorous", "Formal", "Casual", "Youthful"],
182
+ index=2
183
+ )
184
+ length = st.radio(
185
+ "Length",
186
+ ["1-3 Mins", "3-5 Mins", "5-10 Mins", "10-20 Mins"],
187
+ index=0
188
+ )
189
+
190
+ st.write("")
191
+ generate_button = st.button("Generate Podcast")
192
+
193
+ if generate_button:
194
+ # Run the generate_podcast function
195
+ with st.spinner("Generating your podcast, please wait..."):
196
+ podcast_file, transcript = generate_podcast(
197
+ file, url, video_url, research_topic_input, tone, length
198
+ )
199
+
200
+ if podcast_file is None:
201
+ st.error(transcript)
202
+ else:
203
+ st.success("Podcast generated successfully!")
204
+ audio_file = open(podcast_file, 'rb')
205
+ audio_bytes = audio_file.read()
206
+ audio_file.close()
207
+
208
+ st.audio(audio_bytes, format='audio/mp3')
209
+ st.markdown(transcript)
210
+
211
+ # Clean up the temp file
212
+ os.remove(podcast_file)
213
+
214
+ if __name__ == "__main__":
215
+ main()