Turbiling commited on
Commit
d80887b
·
verified ·
1 Parent(s): 4c576df

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +86 -136
app.py CHANGED
@@ -1,171 +1,121 @@
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
- # Models
18
- WHISPER_MODEL = "openai/whisper-large-v3-turbo"
19
- TUTORIAL_MODEL = "openai/gpt-oss-120b"
20
-
21
- # API Clients
22
- groq_client = Groq(api_key=GROQ_API_KEY)
23
- hf_client = InferenceClient(model=WHISPER_MODEL, token=HUGGINGFACE_API_TOKEN)
24
-
25
- # ========= AUDIO HELPERS ==========
26
-
27
- def convert_to_wav(audio_path):
28
- """Convert any audio/video to WAV 16kHz mono."""
29
- try:
30
- if audio_path.endswith(".wav"):
31
- return audio_path
32
- base, _ = os.path.splitext(audio_path)
33
- wav_path = base + "_converted.wav"
34
- subprocess.run(
35
- ["ffmpeg", "-y", "-i", audio_path, "-ar", "16000", "-ac", "1", wav_path],
36
- check=True,
37
- stdout=subprocess.PIPE,
38
- stderr=subprocess.PIPE,
39
- )
40
- return wav_path
41
- except subprocess.CalledProcessError as e:
42
- raise RuntimeError(f"❌ ffmpeg conversion failed: {e.stderr.decode('utf-8')}")
43
- except Exception as e:
44
- raise RuntimeError(f"❌ Error converting to WAV: {e}")
45
 
46
  def download_youtube_audio(url):
47
- """Download audio from YouTube using yt_dlp."""
48
  try:
49
- with tempfile.TemporaryDirectory() as tmpdir:
50
  ydl_opts = {
51
  "format": "bestaudio/best",
52
- "outtmpl": os.path.join(tmpdir, "audio.%(ext)s"),
53
  "quiet": True,
54
  "postprocessors": [{"key": "FFmpegExtractAudio", "preferredcodec": "mp3"}],
55
  }
56
  with yt_dlp.YoutubeDL(ydl_opts) as ydl:
57
  ydl.download([url])
58
- audio_file = os.path.join(tmpdir, "audio.mp3")
59
- wav_file = convert_to_wav(audio_file)
60
- return wav_file
61
  except Exception as e:
62
- raise RuntimeError(f"❌ Error downloading YouTube audio: {e}")
63
 
64
- # ========= CORE FUNCTIONS ==========
 
 
 
 
 
 
 
 
65
 
66
- def transcribe_audio(audio_path=None, youtube_url=None):
67
- """Transcribe uploaded, recorded, or YouTube audio."""
68
  try:
69
  if youtube_url:
70
- wav_file = download_youtube_audio(youtube_url)
71
- elif audio_path:
72
- wav_file = convert_to_wav(audio_path)
73
  else:
74
- return "⚠️ Please upload or record an audio or provide a YouTube link."
 
 
75
 
76
- with open(wav_file, "rb") as f:
77
- transcription = hf_client.audio_to_text(f)
78
- if not transcription:
79
- return "❌ No text generated from transcription."
80
- return transcription.strip()
 
 
81
  except Exception as e:
82
  return f"❌ Error during transcription: {e}"
83
 
84
- def summarize_text(text, language):
85
- """Generate detailed summary in selected language."""
86
  try:
87
- if len(text.split()) < 20:
88
- return "⚠️ Text too short to summarize."
89
-
90
- prompt = (
91
- f"Summarize the following text in detail in {language}. "
92
- f"Ensure the summary is coherent, complete, and descriptive:\n\n{text}"
93
- )
94
- summary = groq_client.chat.completions.create(
95
- model="llama-3.1-8b-instant",
96
- messages=[{"role": "user", "content": prompt}],
97
- temperature=0.6,
98
- max_tokens=1800,
99
- )
100
- return summary.choices[0].message.content.strip()
101
  except Exception as e:
102
  return f"❌ Summarization failed: {e}"
103
 
104
- def generate_tutorial(summary_text, language):
105
- """Generate a clear tutorial based on summary."""
106
  try:
 
107
  prompt = (
108
- f"Create a simple tutorial for absolute beginners based on this summary. "
109
- f"Write in {language} language, use step-by-step explanations, examples, and clear structure:\n\n{summary_text}"
110
- )
111
- tutorial = groq_client.chat.completions.create(
112
- model="llama-3.1-8b-instant",
113
- messages=[{"role": "user", "content": prompt}],
114
- temperature=0.7,
115
- max_tokens=2000,
116
  )
117
- return tutorial.choices[0].message.content.strip()
 
118
  except Exception as e:
119
- return f"❌ Tutorial generation failed: {e}"
120
-
121
- # ========= GRADIO INTERFACE ==========
122
-
123
- with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue")) as app:
124
- gr.Markdown(
125
- """
126
- # 🎙️ Smart Transcriber & Tutor
127
- **Capabilities:**
128
- - Upload / Record / YouTube Transcription
129
- - Generate Detailed Summaries (Urdu / English)
130
- - Create Step-by-Step Tutorials for Beginners
131
- """
132
- )
133
-
134
- with gr.Row():
135
- audio_upload = gr.Audio(label="🎧 Upload Audio", type="filepath")
136
- record_audio = gr.Audio(label="🎤 Record Audio", type="filepath", sources=["microphone"])
137
- youtube_link = gr.Textbox(label="📺 YouTube Link (optional)")
138
-
139
- language_dropdown = gr.Dropdown(["English", "Urdu"], label="Select Language", value="English")
140
-
141
- transcribe_btn = gr.Button("📝 Transcribe Audio")
142
- transcription_output = gr.Textbox(label="Transcription Result", lines=10)
143
-
144
- summarize_btn = gr.Button("🧠 Generate Detailed Summary")
145
- summary_output = gr.Textbox(label="Summary", lines=8)
146
-
147
- tutorial_btn = gr.Button("📘 Create Beginner Tutorial")
148
- tutorial_output = gr.Textbox(label="Tutorial", lines=10)
149
-
150
- # Button logic
151
- transcribe_btn.click(
152
- transcribe_audio,
153
- inputs=[audio_upload, youtube_link],
154
- outputs=transcription_output,
155
- )
156
-
157
- summarize_btn.click(
158
- summarize_text,
159
- inputs=[transcription_output, language_dropdown],
160
- outputs=summary_output,
161
- )
162
-
163
- tutorial_btn.click(
164
- generate_tutorial,
165
- inputs=[summary_output, language_dropdown],
166
- outputs=tutorial_output,
167
- )
168
-
169
- # ========= LAUNCH APP ==========
170
- if __name__ == "__main__":
171
- app.launch()
 
 
1
  import gradio as gr
2
+ import os
 
3
  import tempfile
4
  import yt_dlp
5
+ import subprocess
6
  from huggingface_hub import InferenceClient
7
 
8
+ # Initialize Hugging Face client
9
+ client = InferenceClient("openai/whisper-large-v3")
 
10
 
11
+ # Summarization and tutorial generation models
12
+ english_summarizer = InferenceClient("facebook/bart-large-cnn")
13
+ urdu_summarizer = InferenceClient("openai/gpt-oss-120b")
14
 
15
+ # --- Helper Functions ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
  def download_youtube_audio(url):
18
+ """Download audio from YouTube video"""
19
  try:
20
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as tmp:
21
  ydl_opts = {
22
  "format": "bestaudio/best",
23
+ "outtmpl": tmp.name,
24
  "quiet": True,
25
  "postprocessors": [{"key": "FFmpegExtractAudio", "preferredcodec": "mp3"}],
26
  }
27
  with yt_dlp.YoutubeDL(ydl_opts) as ydl:
28
  ydl.download([url])
29
+ return tmp.name
 
 
30
  except Exception as e:
31
+ raise RuntimeError(f"❌ Error downloading YouTube audio: {str(e)}")
32
 
33
+ def convert_to_wav(audio_path):
34
+ """Ensure audio is in .wav format"""
35
+ wav_path = tempfile.mktemp(suffix=".wav")
36
+ try:
37
+ subprocess.run(["ffmpeg", "-y", "-i", audio_path, "-ar", "16000", "-ac", "1", wav_path],
38
+ check=True, capture_output=True)
39
+ return wav_path
40
+ except subprocess.CalledProcessError as e:
41
+ raise RuntimeError(f"❌ ffmpeg conversion failed: {e}")
42
 
43
+ def transcribe_audio(audio_file=None, youtube_url=None):
44
+ """Transcribe uploaded or YouTube audio"""
45
  try:
46
  if youtube_url:
47
+ audio_path = download_youtube_audio(youtube_url)
 
 
48
  else:
49
+ audio_path = audio_file
50
+
51
+ wav_path = convert_to_wav(audio_path)
52
 
53
+ with open(wav_path, "rb") as f:
54
+ text = client.text_generation(
55
+ prompt="Transcribe this English audio accurately:",
56
+ inputs=f.read(),
57
+ max_new_tokens=5000,
58
+ )
59
+ return text
60
  except Exception as e:
61
  return f"❌ Error during transcription: {e}"
62
 
63
+ def summarize_text(transcribed_text, language):
64
+ """Generate summary in English or Urdu"""
65
  try:
66
+ if language == "English":
67
+ response = english_summarizer.text_generation(
68
+ prompt="Summarize this text comprehensively:\n" + transcribed_text,
69
+ max_new_tokens=1024,
70
+ )
71
+ return response
72
+ else:
73
+ response = urdu_summarizer.text_generation(
74
+ prompt="مندرجہ ذیل انگریزی متن کا جامع اردو خلاصہ تحریر کریں:\n" + transcribed_text,
75
+ max_new_tokens=2048,
76
+ )
77
+ return response
 
 
78
  except Exception as e:
79
  return f"❌ Summarization failed: {e}"
80
 
81
+ def generate_tutorial(transcribed_text, summary, language):
82
+ """Craft a beginner-friendly tutorial in Urdu or English"""
83
  try:
84
+ model = urdu_summarizer if language == "Urdu" else english_summarizer
85
  prompt = (
86
+ f"Write a simple, step-by-step tutorial in {language} for beginners based on this transcript:\n\n"
87
+ f"Transcript:\n{transcribed_text}\n\nSummary:\n{summary}\n"
 
 
 
 
 
 
88
  )
89
+ response = model.text_generation(prompt=prompt, max_new_tokens=2500)
90
+ return response
91
  except Exception as e:
92
+ return f"❌ Error generating tutorial: {e}"
93
+
94
+ # --- Gradio UI ---
95
+
96
+ with gr.Blocks(title="🎙️ AI Audio Transcriber & Tutorial Maker") as demo:
97
+ gr.Markdown("## 🎧 AI Audio Transcriber, Summarizer & Tutorial Creator")
98
+
99
+ with gr.Tab("🎤 Record / Upload Audio"):
100
+ with gr.Row():
101
+ audio_input = gr.Audio(sources=["microphone", "upload"], type="filepath", label="🎙️ Record or Upload Audio")
102
+ youtube_input = gr.Textbox(label="🎥 Or paste YouTube link")
103
+ transcribed_output = gr.Textbox(label="📝 Transcription", lines=8)
104
+ transcribe_btn = gr.Button("🚀 Transcribe Audio")
105
+
106
+ with gr.Tab("🧠 Summarize"):
107
+ language_choice = gr.Radio(["English", "Urdu"], label="Choose Summary Language", value="English")
108
+ summary_output = gr.Textbox(label="📋 Detailed Summary", lines=10)
109
+ summarize_btn = gr.Button(" Generate Summary")
110
+
111
+ with gr.Tab("📘 Tutorial Creator"):
112
+ tutorial_output = gr.Textbox(label="🎓 Beginner Tutorial", lines=12)
113
+ tutorial_btn = gr.Button("📚 Create Tutorial from Summary")
114
+
115
+ # --- Button Actions ---
116
+ transcribe_btn.click(fn=transcribe_audio, inputs=[audio_input, youtube_input], outputs=transcribed_output)
117
+ summarize_btn.click(fn=summarize_text, inputs=[transcribed_output, language_choice], outputs=summary_output)
118
+ tutorial_btn.click(fn=generate_tutorial, inputs=[transcribed_output, summary_output, language_choice], outputs=tutorial_output)
119
+
120
+ # Launch
121
+ demo.launch()