File size: 5,285 Bytes
8a61c0b
d80887b
e13f7aa
 
d80887b
a64985a
022d09b
8a61c0b
e2f51b1
 
 
a64985a
 
 
e13f7aa
a64985a
8a61c0b
e2f51b1
 
 
a64985a
e2f51b1
8a61c0b
a64985a
 
 
 
 
 
 
 
 
 
b16b9a6
a64985a
8a61c0b
a64985a
e2f51b1
d80887b
 
2b2420e
 
 
e2f51b1
2b2420e
d80887b
 
 
e13f7aa
e2f51b1
a64985a
e2f51b1
d80887b
b16b9a6
a64985a
d80887b
e2f51b1
d80887b
e2f51b1
 
d80887b
 
4c576df
e2f51b1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a64985a
b16b9a6
e13f7aa
8a61c0b
e2f51b1
a64985a
e2f51b1
a64985a
b16b9a6
d80887b
a64985a
 
d80887b
a64985a
 
 
d80887b
 
a64985a
8a61c0b
b16b9a6
8a61c0b
e2f51b1
 
 
a64985a
8a61c0b
e13f7aa
e2f51b1
 
 
022d09b
a64985a
 
 
b16b9a6
d80887b
 
e2f51b1
 
 
a64985a
e2f51b1
d80887b
a64985a
e2f51b1
 
d80887b
a64985a
e2f51b1
d80887b
a64985a
e2f51b1
 
a64985a
e2f51b1
d80887b
a64985a
e2f51b1
d80887b
e2f51b1
 
 
 
d80887b
 
0956e94
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import gradio as gr
import os
import tempfile
import yt_dlp
import subprocess
import requests
from huggingface_hub import InferenceClient

# ---------------------------
# Model setup
# ---------------------------
WHISPER_MODEL = "openai/whisper-large-v3"
EN_SUMMARY_MODEL = "facebook/bart-large-cnn"
UR_SUMMARY_MODEL = "openai/gpt-oss-120b"

client = InferenceClient()

# ---------------------------
# Helper Functions
# ---------------------------
def download_youtube_audio(url: str):
    """Download YouTube audio as mp3"""
    try:
        tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3")
        ydl_opts = {
            "format": "bestaudio/best",
            "outtmpl": tmp.name,
            "quiet": True,
            "postprocessors": [{"key": "FFmpegExtractAudio", "preferredcodec": "mp3"}],
        }
        with yt_dlp.YoutubeDL(ydl_opts) as ydl:
            ydl.download([url])
        return tmp.name
    except Exception as e:
        raise RuntimeError(f"❌ Error downloading YouTube audio: {e}")

def convert_to_wav(audio_path: str):
    """Convert any audio to 16kHz mono WAV"""
    wav_path = tempfile.mktemp(suffix=".wav")
    try:
        subprocess.run(
            ["ffmpeg", "-y", "-i", audio_path, "-ar", "16000", "-ac", "1", wav_path],
            check=True,
            capture_output=True,
        )
        return wav_path
    except subprocess.CalledProcessError as e:
        raise RuntimeError(f"❌ ffmpeg conversion failed: {e}")

# ---------------------------
# Transcription
# ---------------------------
def transcribe_audio(audio_file=None, youtube_url=None):
    try:
        if youtube_url and youtube_url.strip():
            audio_path = download_youtube_audio(youtube_url)
        elif audio_file:
            audio_path = audio_file
        else:
            return "❌ Please record, upload, or provide a YouTube link."

        wav_path = convert_to_wav(audio_path)

        headers = {
            "Authorization": f"Bearer {os.environ.get('HUGGINGFACE_API_TOKEN','')}",
            "Content-Type": "audio/wav"
        }
        api_url = f"https://api-inference.huggingface.co/models/{WHISPER_MODEL}"

        with open(wav_path, "rb") as f:
            response = requests.post(api_url, headers=headers, data=f.read())

        if response.status_code != 200:
            raise RuntimeError(f"HF API error: {response.text}")

        data = response.json()
        if isinstance(data, dict) and "text" in data:
            return data["text"]
        elif isinstance(data, list) and "text" in data[0]:
            return data[0]["text"]
        else:
            return str(data)
    except Exception as e:
        return f"❌ Error during transcription: {e}"

# ---------------------------
# Summarization
# ---------------------------
def summarize_text(text, language):
    try:
        if language == "English":
            result = client.summarization(model=EN_SUMMARY_MODEL, inputs=text, max_new_tokens=1024)
            return result["summary_text"]
        else:
            resp = client.text_generation(
                model=UR_SUMMARY_MODEL,
                prompt=f"مندرجہ ذیل انگریزی متن کا جامع اردو خلاصہ لکھیں:\n\n{text}",
                max_new_tokens=2048,
            )
            return resp
    except Exception as e:
        return f"❌ Summarization failed: {e}"

# ---------------------------
# Tutorial Generator
# ---------------------------
def generate_tutorial(transcription, summary, language):
    try:
        prompt = (
            f"Create a comprehensive, beginner-friendly tutorial in {language} "
            f"based on the following transcript and summary.\n\n"
            f"Transcript:\n{transcription}\n\nSummary:\n{summary}"
        )
        model = UR_SUMMARY_MODEL if language == "Urdu" else EN_SUMMARY_MODEL
        result = client.text_generation(model=model, prompt=prompt, max_new_tokens=2200)
        return result
    except Exception as e:
        return f"❌ Error generating tutorial: {e}"

# ---------------------------
# Gradio UI
# ---------------------------
with gr.Blocks(title="🎙️ Smart Transcriber & Tutorial Maker") as demo:
    gr.Markdown("## 🎧 Smart Transcriber, Summarizer & Tutorial Creator")

    with gr.Row():
        audio_input = gr.Audio(sources=["microphone", "upload"], type="filepath", label="🎙️ Record or Upload Audio")
        yt_input = gr.Textbox(label="🎥 Or paste YouTube link")

    trans_btn = gr.Button("🚀 Transcribe")
    transcript_output = gr.Textbox(label="📝 Transcription", lines=8)

    with gr.Row():
        lang_choice = gr.Radio(["English", "Urdu"], label="Select Summary Language", value="English")

    sum_btn = gr.Button("🧠 Generate Detailed Summary")
    summary_output = gr.Textbox(label="📋 Summary", lines=10)

    tut_btn = gr.Button("📘 Create Beginner Tutorial")
    tutorial_output = gr.Textbox(label="🎓 Tutorial", lines=12)

    # Button actions
    trans_btn.click(transcribe_audio, [audio_input, yt_input], transcript_output)
    sum_btn.click(summarize_text, [transcript_output, lang_choice], summary_output)
    tut_btn.click(generate_tutorial, [transcript_output, summary_output, lang_choice], tutorial_output)

demo.launch()