Spaces:
Sleeping
Sleeping
Upload 4 files
Browse files- app (7).py +81 -0
- audio_generator.py +23 -0
- podcast_generator.py +48 -0
- requirements (4).txt +6 -0
app (7).py
ADDED
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
from podcast_generator import generate_podcast_script
|
3 |
+
from audio_generator import gtpodcast_script_to_audio
|
4 |
+
import os
|
5 |
+
from groq import Groq
|
6 |
+
|
7 |
+
# Initialize Groq client
|
8 |
+
api_key = os.getenv("GROQ_API_KEY")
|
9 |
+
client = Groq(api_key=api_key)
|
10 |
+
|
11 |
+
def chat_with_bot(user_input):
|
12 |
+
messages = [
|
13 |
+
{
|
14 |
+
"role": "system",
|
15 |
+
"content": "You are an academic blogger and can reply to any topic."
|
16 |
+
},
|
17 |
+
{
|
18 |
+
"role": "user",
|
19 |
+
"content": user_input
|
20 |
+
}
|
21 |
+
]
|
22 |
+
|
23 |
+
completion = client.chat.completions.create(
|
24 |
+
model="llama3-70b-8192",
|
25 |
+
messages=messages,
|
26 |
+
temperature=1,
|
27 |
+
max_tokens=1024,
|
28 |
+
top_p=1,
|
29 |
+
stream=True,
|
30 |
+
stop=None,
|
31 |
+
)
|
32 |
+
|
33 |
+
response_content = ""
|
34 |
+
for chunk in completion:
|
35 |
+
response_content += chunk.choices[0].delta.content or ""
|
36 |
+
|
37 |
+
return response_content
|
38 |
+
|
39 |
+
#In this function you will pass the chatbot stream replace the response_content variable with the variable that has response from your chatbot.
|
40 |
+
def generate_and_play_podcast(response_content: str) -> tuple:
|
41 |
+
# Generate podcast script
|
42 |
+
podcast_script = generate_podcast_script(response_content)
|
43 |
+
|
44 |
+
# Convert the script to audio
|
45 |
+
audio_path = gtpodcast_script_to_audio(podcast_script)
|
46 |
+
|
47 |
+
# Return both the script and the audio file path
|
48 |
+
return podcast_script, audio_path
|
49 |
+
|
50 |
+
|
51 |
+
with gr.Blocks() as demo:
|
52 |
+
with gr.Row():
|
53 |
+
gr.Markdown("Espresso With LeProf Lite")
|
54 |
+
|
55 |
+
with gr.Row():
|
56 |
+
user_input = gr.Textbox(label="Enter your question", placeholder="Ask anything about technology, science, etc.")
|
57 |
+
submit_button = gr.Button("Generate Chatbot Response")
|
58 |
+
|
59 |
+
with gr.Row():
|
60 |
+
response_output = gr.Textbox(label="Chatbot Response", placeholder="Response will appear here.", lines=10)
|
61 |
+
|
62 |
+
with gr.Row():
|
63 |
+
podcast_button = gr.Button("Generate and Play Podcast")
|
64 |
+
podcast_script_output = gr.Textbox(label="Generated Podcast Script", placeholder="Podcast script will appear here.", lines=10)
|
65 |
+
podcast_audio_output = gr.Audio(label="Podcast Audio")
|
66 |
+
|
67 |
+
# Connect chatbot response generation
|
68 |
+
submit_button.click(
|
69 |
+
fn=chat_with_bot,
|
70 |
+
inputs=user_input,
|
71 |
+
outputs=response_output
|
72 |
+
)
|
73 |
+
|
74 |
+
# Connect podcast generation and audio playback
|
75 |
+
podcast_button.click(
|
76 |
+
fn=generate_and_play_podcast,
|
77 |
+
inputs=response_output, # Use chatbot response as input
|
78 |
+
outputs=[podcast_script_output, podcast_audio_output] # Output both script and audio
|
79 |
+
)
|
80 |
+
|
81 |
+
demo.launch()
|
audio_generator.py
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from gtts import gTTS
|
2 |
+
from pydub import AudioSegment
|
3 |
+
import tempfile
|
4 |
+
|
5 |
+
def gtpodcast_script_to_audio(script: str) -> str:
|
6 |
+
if not script.strip():
|
7 |
+
raise ValueError("No script provided for audio conversion.")
|
8 |
+
|
9 |
+
# Generate TTS audio
|
10 |
+
tts = gTTS(text=script, lang="en", tld='ca') # British English accent
|
11 |
+
temp_audio_path = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3").name
|
12 |
+
tts.save(temp_audio_path)
|
13 |
+
|
14 |
+
# Load the generated audio and lower the pitch
|
15 |
+
audio = AudioSegment.from_file(temp_audio_path)
|
16 |
+
lowered_pitch_audio = audio._spawn(audio.raw_data, overrides={"frame_rate": int(audio.frame_rate * 0.95)})
|
17 |
+
lowered_pitch_audio = lowered_pitch_audio.set_frame_rate(audio.frame_rate)
|
18 |
+
|
19 |
+
# Export the modified audio
|
20 |
+
podcast_path = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3").name
|
21 |
+
lowered_pitch_audio.export(podcast_path, format="mp3")
|
22 |
+
|
23 |
+
return podcast_path
|
podcast_generator.py
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# podcast_generator.py
|
2 |
+
|
3 |
+
from groq import Groq
|
4 |
+
import os
|
5 |
+
|
6 |
+
# Initialize Groq client
|
7 |
+
api_key = os.getenv("GROQ_API_KEY")
|
8 |
+
client = Groq(api_key=api_key)
|
9 |
+
|
10 |
+
def generate_podcast_script(topic):
|
11 |
+
if not topic.strip():
|
12 |
+
return "Please provide a topic from the chatbot response to generate the script."
|
13 |
+
|
14 |
+
messages = [
|
15 |
+
{
|
16 |
+
"role": "system",
|
17 |
+
"content": """
|
18 |
+
You are Professor Elsaddik, host of Espresso with LeProf, a short academic podcast addressing questions from your listener sente by email.
|
19 |
+
- Each episode is inspired by a question emailed by a listener, which you answer directly, blending academic insight with practical advice.
|
20 |
+
- Speak in a warm, conversational tone as if you’re having a quick coffee chat, sharing valuable, easy-to-digest insights.
|
21 |
+
-You can use engaging style to connect the audience.
|
22 |
+
- Conclude each episode with 3 quick quiz questions related to the topic, inviting listeners to think critically and send you the answers.
|
23 |
+
- Keep the episode brief, under 60 seconds, and introduce yourself as Professor Elsaddik, host of Espresso with LeProf.
|
24 |
+
- Use casual fillers for a natural, approachable flow, without background music or extra frills.
|
25 |
+
-Avoid using audio or visual cues. It will be passed as an input to the TTS function.
|
26 |
+
"""
|
27 |
+
},
|
28 |
+
{
|
29 |
+
"role": "user",
|
30 |
+
"content": f"{topic}"
|
31 |
+
}
|
32 |
+
]
|
33 |
+
|
34 |
+
completion = client.chat.completions.create(
|
35 |
+
model="llama3-70b-8192",
|
36 |
+
messages=messages,
|
37 |
+
temperature=1,
|
38 |
+
max_tokens=1024,
|
39 |
+
top_p=1,
|
40 |
+
stream=True,
|
41 |
+
stop=None,
|
42 |
+
)
|
43 |
+
|
44 |
+
script_content = ""
|
45 |
+
for chunk in completion:
|
46 |
+
script_content += chunk.choices[0].delta.content or ""
|
47 |
+
|
48 |
+
return script_content
|
requirements (4).txt
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
groq
|
2 |
+
gradio
|
3 |
+
transformers
|
4 |
+
torch
|
5 |
+
gtts
|
6 |
+
pydub
|