Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -9,7 +9,45 @@ from typing import Optional
|
|
| 9 |
SUPPORTED_FORMATS = ['.mp3', '.wav', '.m4a', '.aac', '.ogg', '.flac', '.webm']
|
| 10 |
MAX_FILE_SIZE_MB = 25
|
| 11 |
|
| 12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
"""Transcribe using Groq's free Whisper API with basic speaker detection"""
|
| 14 |
try:
|
| 15 |
url = "https://api.groq.com/openai/v1/audio/transcriptions"
|
|
@@ -21,6 +59,10 @@ def transcribe_with_groq(audio_file, api_key, enable_diarization=False):
|
|
| 21 |
"timestamp_granularities[]": (None, "segment")
|
| 22 |
}
|
| 23 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
files = {"file": f}
|
| 25 |
headers = {"Authorization": f"Bearer {api_key}"}
|
| 26 |
|
|
@@ -75,7 +117,7 @@ def format_with_speakers_groq(segments):
|
|
| 75 |
|
| 76 |
return formatted_text.strip()
|
| 77 |
|
| 78 |
-
def transcribe_with_assemblyai(audio_file, api_key, enable_diarization=False):
|
| 79 |
"""Transcribe using AssemblyAI's API with advanced speaker diarization"""
|
| 80 |
try:
|
| 81 |
# Step 1: Upload file
|
|
@@ -89,13 +131,19 @@ def transcribe_with_assemblyai(audio_file, api_key, enable_diarization=False):
|
|
| 89 |
|
| 90 |
upload_url = response.json()["upload_url"]
|
| 91 |
|
| 92 |
-
# Step 2: Request transcription with diarization
|
| 93 |
data = {
|
| 94 |
"audio_url": upload_url,
|
| 95 |
"speaker_labels": enable_diarization,
|
| 96 |
"speakers_expected": 2 if enable_diarization else None
|
| 97 |
}
|
| 98 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 99 |
response = requests.post("https://api.assemblyai.com/v2/transcript", json=data, headers=headers)
|
| 100 |
|
| 101 |
if response.status_code != 200:
|
|
@@ -160,21 +208,26 @@ def format_with_speakers_assemblyai(utterances):
|
|
| 160 |
|
| 161 |
return formatted_text.strip()
|
| 162 |
|
| 163 |
-
def transcribe_with_openai(audio_file, api_key):
|
| 164 |
"""Transcribe using OpenAI's Whisper API (no diarization support)"""
|
| 165 |
try:
|
| 166 |
url = "https://api.openai.com/v1/audio/transcriptions"
|
| 167 |
|
| 168 |
with open(audio_file, "rb") as f:
|
| 169 |
-
|
| 170 |
-
"file": f,
|
| 171 |
"model": (None, "whisper-1"),
|
| 172 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 173 |
headers = {
|
| 174 |
"Authorization": f"Bearer {api_key}"
|
| 175 |
}
|
| 176 |
|
| 177 |
-
response = requests.post(url, files=files, headers=headers, timeout=60)
|
| 178 |
|
| 179 |
if response.status_code == 200:
|
| 180 |
result = response.json()
|
|
@@ -210,7 +263,7 @@ def transcribe_with_deepgram(audio_file, api_key):
|
|
| 210 |
except Exception as e:
|
| 211 |
return {"success": False, "error": f"Deepgram request failed: {str(e)}"}
|
| 212 |
|
| 213 |
-
def transcribe_audio(audio_file, service_choice, api_key, enable_diarization, progress=gr.Progress()):
|
| 214 |
"""Main transcription function for audio files only"""
|
| 215 |
|
| 216 |
if audio_file is None:
|
|
@@ -267,15 +320,15 @@ def transcribe_audio(audio_file, service_choice, api_key, enable_diarization, pr
|
|
| 267 |
# Choose transcription service
|
| 268 |
if service_choice == "Groq (Gratis e Veloce)":
|
| 269 |
progress(0.3, desc="Trascrivendo con Groq...")
|
| 270 |
-
result = transcribe_with_groq(audio_file, api_key, enable_diarization)
|
| 271 |
elif service_choice == "AssemblyAI (Tier Gratuito)":
|
| 272 |
progress(0.3, desc="Caricando su AssemblyAI...")
|
| 273 |
-
result = transcribe_with_assemblyai(audio_file, api_key, enable_diarization)
|
| 274 |
elif service_choice == "OpenAI Whisper (A Pagamento)":
|
| 275 |
if enable_diarization:
|
| 276 |
return "❌ OpenAI Whisper non supporta il riconoscimento interlocutori. Usa Groq o AssemblyAI per questa funzione.", ""
|
| 277 |
progress(0.3, desc="Trascrivendo con OpenAI...")
|
| 278 |
-
result = transcribe_with_openai(audio_file, api_key)
|
| 279 |
elif service_choice == "Deepgram (Prova Gratuita)":
|
| 280 |
if enable_diarization:
|
| 281 |
return "❌ Riconoscimento interlocutori non implementato per Deepgram. Usa Groq o AssemblyAI.", ""
|
|
@@ -299,6 +352,7 @@ def transcribe_audio(audio_file, service_choice, api_key, enable_diarization, pr
|
|
| 299 |
|
| 300 |
# Create summary
|
| 301 |
diarization_status = "✅ Attivo" if enable_diarization else "❌ Disattivo"
|
|
|
|
| 302 |
|
| 303 |
summary = f"""✅ **Trascrizione Completata!**
|
| 304 |
|
|
@@ -312,6 +366,7 @@ def transcribe_audio(audio_file, service_choice, api_key, enable_diarization, pr
|
|
| 312 |
🔧 **Impostazioni:**
|
| 313 |
• Chiave API: {"✅ Fornita" if api_key else "❌ Mancante"}
|
| 314 |
• Riconoscimento Interlocutori: {diarization_status}
|
|
|
|
| 315 |
• Formato: {file_extension.upper()}
|
| 316 |
"""
|
| 317 |
|
|
@@ -420,6 +475,14 @@ with gr.Blocks(title=title, theme=gr.themes.Soft(), css=css) as demo:
|
|
| 420 |
info="Identifica diversi parlanti come Interlocutore 1, 2, ecc."
|
| 421 |
)
|
| 422 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 423 |
with gr.Accordion("ℹ️ Come ottenere le chiavi API", open=False):
|
| 424 |
gr.Markdown(get_service_info())
|
| 425 |
|
|
@@ -452,6 +515,11 @@ with gr.Blocks(title=title, theme=gr.themes.Soft(), css=css) as demo:
|
|
| 452 |
• ✅ **AssemblyAI**: Rilevamento avanzato (AI)
|
| 453 |
• ❌ **OpenAI/Deepgram**: Non supportato
|
| 454 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 455 |
**Formati supportati:**
|
| 456 |
MP3, WAV, M4A, AAC, OGG, FLAC, WebM
|
| 457 |
""")
|
|
@@ -477,7 +545,7 @@ MP3, WAV, M4A, AAC, OGG, FLAC, WebM
|
|
| 477 |
# Event handlers
|
| 478 |
transcribe_btn.click(
|
| 479 |
fn=transcribe_audio,
|
| 480 |
-
inputs=[audio_input, service_choice, api_key_input, diarization_checkbox],
|
| 481 |
outputs=[output_text, summary_output]
|
| 482 |
)
|
| 483 |
|
|
@@ -510,7 +578,7 @@ MP3, WAV, M4A, AAC, OGG, FLAC, WebM
|
|
| 510 |
**🔗 Ottieni Chiavi API:**
|
| 511 |
[Groq Console](https://console.groq.com/) • [AssemblyAI](https://www.assemblyai.com/) • [OpenAI Platform](https://platform.openai.com/) • [Deepgram](https://deepgram.com/)
|
| 512 |
|
| 513 |
-
**📚 Info:** Usa API affidabili per trascrizione • Groq e AssemblyAI supportano riconoscimento interlocutori • Tutti i servizi usano modelli Whisper
|
| 514 |
""")
|
| 515 |
|
| 516 |
if __name__ == "__main__":
|
|
|
|
| 9 |
SUPPORTED_FORMATS = ['.mp3', '.wav', '.m4a', '.aac', '.ogg', '.flac', '.webm']
|
| 10 |
MAX_FILE_SIZE_MB = 25
|
| 11 |
|
| 12 |
+
# Language options for Whisper
|
| 13 |
+
LANGUAGE_OPTIONS = [
|
| 14 |
+
("🌍 Auto-rilevamento", "auto"),
|
| 15 |
+
("🇮🇹 Italiano", "it"),
|
| 16 |
+
("🇺🇸 English", "en"),
|
| 17 |
+
("🇪🇸 Español", "es"),
|
| 18 |
+
("🇫🇷 Français", "fr"),
|
| 19 |
+
("🇩🇪 Deutsch", "de"),
|
| 20 |
+
("🇵🇹 Português", "pt"),
|
| 21 |
+
("🇷🇺 Русский", "ru"),
|
| 22 |
+
("🇨🇳 中文", "zh"),
|
| 23 |
+
("🇯🇵 日本語", "ja"),
|
| 24 |
+
("🇰🇷 한국어", "ko"),
|
| 25 |
+
("🇳🇱 Nederlands", "nl"),
|
| 26 |
+
("🇸🇦 العربية", "ar"),
|
| 27 |
+
("🇮🇳 हिन्दी", "hi"),
|
| 28 |
+
("🇹🇷 Türkçe", "tr"),
|
| 29 |
+
("🇵🇱 Polski", "pl"),
|
| 30 |
+
("🇸🇪 Svenska", "sv"),
|
| 31 |
+
("🇳🇴 Norsk", "no"),
|
| 32 |
+
("🇩🇰 Dansk", "da"),
|
| 33 |
+
("🇫🇮 Suomi", "fi"),
|
| 34 |
+
("🇬🇷 Ελληνικά", "el"),
|
| 35 |
+
("🇮🇱 עברית", "he"),
|
| 36 |
+
("🇹🇭 ไทย", "th"),
|
| 37 |
+
("🇻🇳 Tiếng Việt", "vi"),
|
| 38 |
+
("🇮🇩 Bahasa Indonesia", "id"),
|
| 39 |
+
("🇲🇾 Bahasa Melayu", "ms"),
|
| 40 |
+
("🇺🇦 Українська", "uk"),
|
| 41 |
+
("🇨🇿 Čeština", "cs"),
|
| 42 |
+
("🇭🇺 Magyar", "hu"),
|
| 43 |
+
("🇷🇴 Română", "ro"),
|
| 44 |
+
("🇧🇬 Български", "bg"),
|
| 45 |
+
("🇭🇷 Hrvatski", "hr"),
|
| 46 |
+
("🇸🇰 Slovenčina", "sk"),
|
| 47 |
+
("🇸🇮 Slovenščina", "sl"),
|
| 48 |
+
]
|
| 49 |
+
|
| 50 |
+
def transcribe_with_groq(audio_file, api_key, enable_diarization=False, language="auto"):
|
| 51 |
"""Transcribe using Groq's free Whisper API with basic speaker detection"""
|
| 52 |
try:
|
| 53 |
url = "https://api.groq.com/openai/v1/audio/transcriptions"
|
|
|
|
| 59 |
"timestamp_granularities[]": (None, "segment")
|
| 60 |
}
|
| 61 |
|
| 62 |
+
# Add language parameter if not auto
|
| 63 |
+
if language != "auto":
|
| 64 |
+
data["language"] = (None, language)
|
| 65 |
+
|
| 66 |
files = {"file": f}
|
| 67 |
headers = {"Authorization": f"Bearer {api_key}"}
|
| 68 |
|
|
|
|
| 117 |
|
| 118 |
return formatted_text.strip()
|
| 119 |
|
| 120 |
+
def transcribe_with_assemblyai(audio_file, api_key, enable_diarization=False, language="auto"):
|
| 121 |
"""Transcribe using AssemblyAI's API with advanced speaker diarization"""
|
| 122 |
try:
|
| 123 |
# Step 1: Upload file
|
|
|
|
| 131 |
|
| 132 |
upload_url = response.json()["upload_url"]
|
| 133 |
|
| 134 |
+
# Step 2: Request transcription with diarization and language
|
| 135 |
data = {
|
| 136 |
"audio_url": upload_url,
|
| 137 |
"speaker_labels": enable_diarization,
|
| 138 |
"speakers_expected": 2 if enable_diarization else None
|
| 139 |
}
|
| 140 |
|
| 141 |
+
# Add language detection or specific language
|
| 142 |
+
if language == "auto":
|
| 143 |
+
data["language_detection"] = True
|
| 144 |
+
else:
|
| 145 |
+
data["language_code"] = language
|
| 146 |
+
|
| 147 |
response = requests.post("https://api.assemblyai.com/v2/transcript", json=data, headers=headers)
|
| 148 |
|
| 149 |
if response.status_code != 200:
|
|
|
|
| 208 |
|
| 209 |
return formatted_text.strip()
|
| 210 |
|
| 211 |
+
def transcribe_with_openai(audio_file, api_key, language="auto"):
|
| 212 |
"""Transcribe using OpenAI's Whisper API (no diarization support)"""
|
| 213 |
try:
|
| 214 |
url = "https://api.openai.com/v1/audio/transcriptions"
|
| 215 |
|
| 216 |
with open(audio_file, "rb") as f:
|
| 217 |
+
data = {
|
|
|
|
| 218 |
"model": (None, "whisper-1"),
|
| 219 |
}
|
| 220 |
+
|
| 221 |
+
# Add language parameter if not auto
|
| 222 |
+
if language != "auto":
|
| 223 |
+
data["language"] = (None, language)
|
| 224 |
+
|
| 225 |
+
files = {"file": f}
|
| 226 |
headers = {
|
| 227 |
"Authorization": f"Bearer {api_key}"
|
| 228 |
}
|
| 229 |
|
| 230 |
+
response = requests.post(url, files=files, data=data, headers=headers, timeout=60)
|
| 231 |
|
| 232 |
if response.status_code == 200:
|
| 233 |
result = response.json()
|
|
|
|
| 263 |
except Exception as e:
|
| 264 |
return {"success": False, "error": f"Deepgram request failed: {str(e)}"}
|
| 265 |
|
| 266 |
+
def transcribe_audio(audio_file, service_choice, api_key, enable_diarization, language_choice, progress=gr.Progress()):
|
| 267 |
"""Main transcription function for audio files only"""
|
| 268 |
|
| 269 |
if audio_file is None:
|
|
|
|
| 320 |
# Choose transcription service
|
| 321 |
if service_choice == "Groq (Gratis e Veloce)":
|
| 322 |
progress(0.3, desc="Trascrivendo con Groq...")
|
| 323 |
+
result = transcribe_with_groq(audio_file, api_key, enable_diarization, language_choice)
|
| 324 |
elif service_choice == "AssemblyAI (Tier Gratuito)":
|
| 325 |
progress(0.3, desc="Caricando su AssemblyAI...")
|
| 326 |
+
result = transcribe_with_assemblyai(audio_file, api_key, enable_diarization, language_choice)
|
| 327 |
elif service_choice == "OpenAI Whisper (A Pagamento)":
|
| 328 |
if enable_diarization:
|
| 329 |
return "❌ OpenAI Whisper non supporta il riconoscimento interlocutori. Usa Groq o AssemblyAI per questa funzione.", ""
|
| 330 |
progress(0.3, desc="Trascrivendo con OpenAI...")
|
| 331 |
+
result = transcribe_with_openai(audio_file, api_key, language_choice)
|
| 332 |
elif service_choice == "Deepgram (Prova Gratuita)":
|
| 333 |
if enable_diarization:
|
| 334 |
return "❌ Riconoscimento interlocutori non implementato per Deepgram. Usa Groq o AssemblyAI.", ""
|
|
|
|
| 352 |
|
| 353 |
# Create summary
|
| 354 |
diarization_status = "✅ Attivo" if enable_diarization else "❌ Disattivo"
|
| 355 |
+
language_display = "🌍 Auto-rilevamento" if language_choice == "auto" else f"🗣️ {language_choice.upper()}"
|
| 356 |
|
| 357 |
summary = f"""✅ **Trascrizione Completata!**
|
| 358 |
|
|
|
|
| 366 |
🔧 **Impostazioni:**
|
| 367 |
• Chiave API: {"✅ Fornita" if api_key else "❌ Mancante"}
|
| 368 |
• Riconoscimento Interlocutori: {diarization_status}
|
| 369 |
+
• Lingua: {language_display}
|
| 370 |
• Formato: {file_extension.upper()}
|
| 371 |
"""
|
| 372 |
|
|
|
|
| 475 |
info="Identifica diversi parlanti come Interlocutore 1, 2, ecc."
|
| 476 |
)
|
| 477 |
|
| 478 |
+
# Language selection
|
| 479 |
+
language_dropdown = gr.Dropdown(
|
| 480 |
+
choices=LANGUAGE_OPTIONS,
|
| 481 |
+
value="auto",
|
| 482 |
+
label="🌍 Lingua Audio",
|
| 483 |
+
info="Seleziona la lingua dell'audio per migliorare l'accuratezza"
|
| 484 |
+
)
|
| 485 |
+
|
| 486 |
with gr.Accordion("ℹ️ Come ottenere le chiavi API", open=False):
|
| 487 |
gr.Markdown(get_service_info())
|
| 488 |
|
|
|
|
| 515 |
• ✅ **AssemblyAI**: Rilevamento avanzato (AI)
|
| 516 |
• ❌ **OpenAI/Deepgram**: Non supportato
|
| 517 |
|
| 518 |
+
**🌍 Selezione Lingua:**
|
| 519 |
+
• **Auto-rilevamento**: Lascia che l'AI detecti la lingua
|
| 520 |
+
• **Lingua specifica**: Migliora accuratezza e velocità
|
| 521 |
+
• **35+ lingue supportate**: Italiano, English, Español, etc.
|
| 522 |
+
|
| 523 |
**Formati supportati:**
|
| 524 |
MP3, WAV, M4A, AAC, OGG, FLAC, WebM
|
| 525 |
""")
|
|
|
|
| 545 |
# Event handlers
|
| 546 |
transcribe_btn.click(
|
| 547 |
fn=transcribe_audio,
|
| 548 |
+
inputs=[audio_input, service_choice, api_key_input, diarization_checkbox, language_dropdown],
|
| 549 |
outputs=[output_text, summary_output]
|
| 550 |
)
|
| 551 |
|
|
|
|
| 578 |
**🔗 Ottieni Chiavi API:**
|
| 579 |
[Groq Console](https://console.groq.com/) • [AssemblyAI](https://www.assemblyai.com/) • [OpenAI Platform](https://platform.openai.com/) • [Deepgram](https://deepgram.com/)
|
| 580 |
|
| 581 |
+
**📚 Info:** Usa API affidabili per trascrizione • Groq e AssemblyAI supportano riconoscimento interlocutori • Supporto per 35+ lingue • Tutti i servizi usano modelli Whisper
|
| 582 |
""")
|
| 583 |
|
| 584 |
if __name__ == "__main__":
|