Turbiling commited on
Commit
e13f7aa
·
verified ·
1 Parent(s): 833b605

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +138 -86
app.py CHANGED
@@ -1,128 +1,180 @@
1
  import os
2
  import gradio as gr
3
- import yt_dlp
4
  import subprocess
 
 
 
5
  from groq import Groq
6
  from huggingface_hub import InferenceClient
7
 
8
- # Initialize clients
9
- groq_client = Groq(api_key=os.getenv("GROQ_API_KEY"))
10
- hf_client = InferenceClient("facebook/bart-large-cnn")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
- # 🔹 Convert audio to WAV format for transcription
13
  def convert_to_wav(audio_path):
14
- wav_path = audio_path.replace(".mp3", ".wav")
15
  try:
 
 
 
 
16
  subprocess.run(
17
  ["ffmpeg", "-y", "-i", audio_path, "-ar", "16000", "-ac", "1", wav_path],
18
  check=True,
19
  stdout=subprocess.PIPE,
20
- stderr=subprocess.PIPE
21
  )
22
  return wav_path
 
 
23
  except Exception as e:
24
- raise RuntimeError(f"❌ ffmpeg conversion failed: {e}")
25
 
26
- # 🔹 Download YouTube audio
27
- def download_youtube_audio(youtube_url):
28
  try:
29
- output_path = "youtube_audio.wav"
30
- ydl_opts = {
31
- "format": "bestaudio/best",
32
- "outtmpl": "youtube_audio.%(ext)s",
33
- "quiet": True,
34
- "postprocessors": [{
35
- "key": "FFmpegExtractAudio",
36
- "preferredcodec": "wav",
37
- "preferredquality": "192",
38
- }],
39
- }
40
- with yt_dlp.YoutubeDL(ydl_opts) as ydl:
41
- ydl.download([youtube_url])
42
- return output_path
43
  except Exception as e:
44
  raise RuntimeError(f"❌ Error downloading YouTube audio: {e}")
45
 
46
- # 🔹 Transcribe audio
47
- def transcribe_audio(audio_file=None, youtube_url=None):
 
 
48
  try:
49
  if youtube_url:
50
- audio_file = download_youtube_audio(youtube_url)
51
- if not audio_file:
52
- return "❌ Please upload or record audio or provide a YouTube link.", ""
53
-
54
- wav_file = convert_to_wav(audio_file)
55
- with open(wav_file, "rb") as f:
56
- transcription = groq_client.audio.transcriptions.create(
57
- model="whisper-large-v3",
58
- file=(wav_file, f, "audio/wav")
 
 
59
  )
60
- text = transcription.text
61
- return text, " Transcription complete."
 
 
 
 
 
62
  except Exception as e:
63
- return "", f"❌ Error during transcription: {e}"
64
 
65
- # 🔹 Summarize text
66
- def summarize_text(transcription, language):
67
  try:
68
- if not transcription.strip():
69
- return " Please transcribe audio first."
70
- if language == "English":
71
- summary = hf_client.summarization(transcription, max_length=250, min_length=100)
72
- return summary[0]["summary_text"]
73
- else:
74
- # For Urdu, use Groq model
75
- prompt = f"اس انگریزی متن کا خلاصہ تفصیلی اردو میں لکھیں:\n\n{transcription}"
76
- response = groq_client.chat.completions.create(
77
- model="openai/gpt-oss-120b",
78
- messages=[{"role": "user", "content": prompt}],
79
- temperature=0.5
80
- )
81
- return response.choices[0].message.content
82
  except Exception as e:
83
  return f"❌ Summarization failed: {e}"
84
 
85
- # 🔹 Craft tutorial
86
- def craft_tutorial(transcription, language):
87
  try:
88
- if not transcription.strip():
89
- return " Please transcribe or summarize first."
90
- if language == "English":
91
- prompt = f"Create a comprehensive beginner-friendly tutorial based on this transcription:\n\n{transcription}"
92
- else:
93
- prompt = f"اس ٹرانسکرپشن کی بنیاد پر اردو میں ایک جامع، آسان، تعلیمی ٹیوٹوریل لکھیں جو بالکل ابتدائی افراد کے لیے ہو۔\n\n{transcription}"
94
-
95
- response = groq_client.chat.completions.create(
96
- model="openai/gpt-oss-120b",
97
  messages=[{"role": "user", "content": prompt}],
98
- temperature=0.6
 
99
  )
100
- return response.choices[0].message.content
101
  except Exception as e:
102
- return f"❌ Error creating tutorial: {e}"
103
 
104
- # 🔹 Gradio Interface
105
- with gr.Blocks(title="🎧 AI Audio Transcriber & Educator") as app:
106
- gr.Markdown("## 🎙️ AI Audio Transcriber + Summarizer + Tutorial Generator")
107
- gr.Markdown("Transcribe, summarize, and learn from audio (English or Urdu).")
108
 
109
- with gr.Row():
110
- audio_input = gr.Audio(label="🎧 Upload or Record Audio", type="filepath", sources=["microphone", "upload"])
111
- youtube_url = gr.Textbox(label="🔗 YouTube Link (optional)")
 
 
 
 
 
 
 
112
 
113
  with gr.Row():
114
- language = gr.Radio(["English", "Urdu"], label="🌍 Output Language", value="English")
 
 
 
 
 
 
 
 
 
 
 
 
 
115
 
116
- transcribe_btn = gr.Button("🚀 Transcribe Audio")
117
- summary_btn = gr.Button("🧠 Generate Detailed Summary")
118
- tutorial_btn = gr.Button("📘 Craft Tutorial")
 
 
 
119
 
120
- transcription_output = gr.Textbox(label="📝 Transcription", lines=8)
121
- summary_output = gr.Textbox(label="🧾 Summary", lines=6)
122
- tutorial_output = gr.Textbox(label="📚 Tutorial", lines=10)
 
 
123
 
124
- transcribe_btn.click(transcribe_audio, inputs=[audio_input, youtube_url], outputs=[transcription_output, gr.Textbox()])
125
- summary_btn.click(summarize_text, inputs=[transcription_output, language], outputs=summary_output)
126
- tutorial_btn.click(craft_tutorial, inputs=[transcription_output, language], outputs=tutorial_output)
 
 
127
 
128
- app.launch()
 
 
 
1
  import os
2
  import gradio as gr
 
3
  import subprocess
4
+ import requests
5
+ import tempfile
6
+ import yt_dlp
7
  from groq import Groq
8
  from huggingface_hub import InferenceClient
9
 
10
+ # ========= CONFIG ==========
11
+ GROQ_API_KEY = os.getenv("GROQ_API_KEY")
12
+ HUGGINGFACE_API_TOKEN = os.getenv("HUGGINGFACE_API_TOKEN")
13
+
14
+ if not GROQ_API_KEY or not HUGGINGFACE_API_TOKEN:
15
+ raise EnvironmentError("Please set GROQ_API_KEY and HUGGINGFACE_API_TOKEN.")
16
+
17
+ # Whisper and summarization models
18
+ WHISPER_MODEL = "openai/whisper-large-v3-turbo"
19
+ SUMMARIZER_MODEL = "facebook/bart-large-cnn"
20
+ TUTORIAL_MODEL = "openai/gpt-oss-120b"
21
+
22
+ # API Clients
23
+ groq_client = Groq(api_key=GROQ_API_KEY)
24
+ hf_client = InferenceClient(token=HUGGINGFACE_API_TOKEN)
25
+
26
+ # ========= AUDIO HELPERS ==========
27
 
 
28
  def convert_to_wav(audio_path):
29
+ """Convert any audio/video to WAV 16kHz mono."""
30
  try:
31
+ if audio_path.endswith(".wav"):
32
+ return audio_path
33
+ base, _ = os.path.splitext(audio_path)
34
+ wav_path = base + "_converted.wav"
35
  subprocess.run(
36
  ["ffmpeg", "-y", "-i", audio_path, "-ar", "16000", "-ac", "1", wav_path],
37
  check=True,
38
  stdout=subprocess.PIPE,
39
+ stderr=subprocess.PIPE,
40
  )
41
  return wav_path
42
+ except subprocess.CalledProcessError as e:
43
+ raise RuntimeError(f"❌ ffmpeg conversion failed: {e.stderr.decode('utf-8')}")
44
  except Exception as e:
45
+ raise RuntimeError(f"❌ Error converting to WAV: {e}")
46
 
47
+ def download_youtube_audio(url):
48
+ """Download audio from YouTube using yt_dlp."""
49
  try:
50
+ with tempfile.TemporaryDirectory() as tmpdir:
51
+ ydl_opts = {
52
+ "format": "bestaudio/best",
53
+ "outtmpl": os.path.join(tmpdir, "audio.%(ext)s"),
54
+ "quiet": True,
55
+ "postprocessors": [{"key": "FFmpegExtractAudio", "preferredcodec": "mp3"}],
56
+ }
57
+ with yt_dlp.YoutubeDL(ydl_opts) as ydl:
58
+ ydl.download([url])
59
+ audio_file = os.path.join(tmpdir, "audio.mp3")
60
+ wav_file = convert_to_wav(audio_file)
61
+ return wav_file
 
 
62
  except Exception as e:
63
  raise RuntimeError(f"❌ Error downloading YouTube audio: {e}")
64
 
65
+ # ========= CORE FUNCTIONS ==========
66
+
67
+ def transcribe_audio(audio_path=None, youtube_url=None):
68
+ """Transcribe uploaded, recorded, or YouTube audio."""
69
  try:
70
  if youtube_url:
71
+ wav_file = download_youtube_audio(youtube_url)
72
+ elif audio_path:
73
+ wav_file = convert_to_wav(audio_path)
74
+ else:
75
+ return "⚠️ Please upload or record an audio or provide YouTube link."
76
+
77
+ with open(wav_file, "rb") as audio_file:
78
+ response = hf_client.post(
79
+ f"https://api-inference.huggingface.co/models/{WHISPER_MODEL}",
80
+ headers={"Authorization": f"Bearer {HUGGINGFACE_API_TOKEN}"},
81
+ data=audio_file.read(),
82
  )
83
+ if response.status_code != 200:
84
+ return f" Transcription failed: {response.text}"
85
+ result = response.json()
86
+ text = result.get("text", "").strip()
87
+ if not text:
88
+ return "❌ No text generated from transcription."
89
+ return text
90
  except Exception as e:
91
+ return f"❌ Error during transcription: {e}"
92
 
93
+ def summarize_text(text, language):
94
+ """Generate detailed summary in selected language."""
95
  try:
96
+ if len(text.split()) < 20:
97
+ return "⚠️ Text too short to summarize."
98
+
99
+ prompt = (
100
+ f"Summarize the following text in detail in {language}. "
101
+ f"Ensure the summary is coherent and complete.\n\n{text}"
102
+ )
103
+ summary = groq_client.chat.completions.create(
104
+ model="llama-3.1-8b-instant",
105
+ messages=[{"role": "user", "content": prompt}],
106
+ temperature=0.6,
107
+ max_tokens=1500,
108
+ )
109
+ return summary.choices[0].message.content.strip()
110
  except Exception as e:
111
  return f"❌ Summarization failed: {e}"
112
 
113
+ def generate_tutorial(summary_text, language):
114
+ """Generate an easy tutorial in Urdu or English based on summary."""
115
  try:
116
+ prompt = (
117
+ f"Create a simple tutorial for absolute beginners based on this summary. "
118
+ f"Write it in {language} language, use simple and clear explanations, and keep it structured:\n\n{summary_text}"
119
+ )
120
+ tutorial = groq_client.chat.completions.create(
121
+ model="llama-3.1-8b-instant",
 
 
 
122
  messages=[{"role": "user", "content": prompt}],
123
+ temperature=0.7,
124
+ max_tokens=1800,
125
  )
126
+ return tutorial.choices[0].message.content.strip()
127
  except Exception as e:
128
+ return f"❌ Tutorial generation failed: {e}"
129
 
130
+ # ========= GRADIO INTERFACE ==========
 
 
 
131
 
132
+ with gr.Blocks(theme=gr.themes.Soft(primary_hue="teal")) as app:
133
+ gr.Markdown(
134
+ """
135
+ # 🎙️ Smart Transcriber & Tutor
136
+ **Features:**
137
+ - Upload / Record / YouTube Transcription
138
+ - Summarize in English or Urdu
139
+ - Generate Tutorial for Beginners
140
+ """
141
+ )
142
 
143
  with gr.Row():
144
+ audio_upload = gr.Audio(label="🎧 Upload Audio", type="filepath")
145
+ record_audio = gr.Audio(label="🎤 Record Audio", type="filepath", sources=["microphone"])
146
+ youtube_link = gr.Textbox(label="📺 YouTube Link (optional)")
147
+
148
+ language_dropdown = gr.Dropdown(["English", "Urdu"], label="Select Language", value="English")
149
+
150
+ transcribe_btn = gr.Button("📝 Transcribe Audio")
151
+ transcription_output = gr.Textbox(label="Transcription Result", lines=10)
152
+
153
+ summarize_btn = gr.Button("🧠 Generate Detailed Summary")
154
+ summary_output = gr.Textbox(label="Summary", lines=8)
155
+
156
+ tutorial_btn = gr.Button("📘 Create Beginner Tutorial")
157
+ tutorial_output = gr.Textbox(label="Tutorial", lines=10)
158
 
159
+ # Button logic
160
+ transcribe_btn.click(
161
+ transcribe_audio,
162
+ inputs=[audio_upload, youtube_link],
163
+ outputs=transcription_output,
164
+ )
165
 
166
+ summarize_btn.click(
167
+ summarize_text,
168
+ inputs=[transcription_output, language_dropdown],
169
+ outputs=summary_output,
170
+ )
171
 
172
+ tutorial_btn.click(
173
+ generate_tutorial,
174
+ inputs=[summary_output, language_dropdown],
175
+ outputs=tutorial_output,
176
+ )
177
 
178
+ # ========= LAUNCH APP ==========
179
+ if __name__ == "__main__":
180
+ app.launch()