Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -294,15 +294,131 @@
|
|
294 |
|
295 |
# demo.launch()
|
296 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
297 |
import os
|
298 |
import gradio as gr
|
299 |
import requests
|
300 |
from TTS.api import TTS
|
301 |
|
302 |
-
# β
Accept Coqui
|
303 |
os.environ["COQUI_TOS_AGREED"] = "1"
|
304 |
|
305 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
306 |
surah_info = {
|
307 |
"Al-Fatiha": (1, 7),
|
308 |
"Al-Baqarah": (2, 286),
|
@@ -324,26 +440,111 @@ surah_info = {
|
|
324 |
"Al-Kahf": (18, 110),
|
325 |
"Maryam": (19, 98),
|
326 |
"Taha": (20, 135),
|
327 |
-
|
328 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
329 |
}
|
330 |
|
331 |
-
# β
Load TTS with Arabic + speaker support
|
332 |
-
tts = TTS(model_name="tts_models/multilingual/multi-dataset/xtts_v2")
|
333 |
-
speaker = "random" # or use "en_0", "ar_0" etc.
|
334 |
-
|
335 |
-
# π Main function
|
336 |
-
def ai_quran(surah_name, ayat_num, mode):
|
337 |
-
surah_num, total_ayats = surah_info.get(surah_name, (None, None))
|
338 |
-
if not surah_num:
|
339 |
-
return "Invalid Surah", "", None
|
340 |
|
|
|
|
|
341 |
if mode == "Full Surah":
|
342 |
url = f"https://api.alquran.cloud/v1/surah/{surah_num}/editions/quran-simple,en.asad"
|
343 |
-
else:
|
344 |
-
if not
|
345 |
-
return f"
|
346 |
-
url = f"https://api.alquran.cloud/v1/ayah/{surah_num}:{
|
347 |
|
348 |
try:
|
349 |
res = requests.get(url)
|
@@ -351,51 +552,47 @@ def ai_quran(surah_name, ayat_num, mode):
|
|
351 |
data = res.json()
|
352 |
|
353 |
if mode == "Full Surah":
|
354 |
-
|
355 |
-
|
356 |
-
arabic_text = "\n".join([a['text'] for a in arabic_ayahs])
|
357 |
-
english_text = "\n".join([e['text'] for e in english_ayahs])
|
358 |
else:
|
359 |
-
|
360 |
-
|
361 |
|
362 |
-
|
363 |
-
audio_path = "ayat.wav"
|
364 |
tts.tts_to_file(
|
365 |
-
text=
|
366 |
-
|
367 |
language="ar",
|
368 |
file_path=audio_path
|
369 |
)
|
370 |
|
371 |
-
return
|
372 |
|
373 |
except Exception as e:
|
374 |
-
return f"
|
375 |
|
376 |
-
|
377 |
-
def toggle_ayat(mode, surah):
|
378 |
if mode == "Full Surah":
|
379 |
return gr.update(visible=False)
|
380 |
return gr.update(visible=True, maximum=surah_info[surah][1])
|
381 |
|
382 |
-
#
|
383 |
-
with gr.Blocks(title="π AI
|
384 |
-
gr.Markdown("##
|
385 |
|
386 |
with gr.Row():
|
387 |
mode = gr.Radio(["Full Surah", "Single Ayat"], label="Mode", value="Full Surah")
|
388 |
surah = gr.Dropdown(choices=list(surah_info.keys()), label="Surah", value="Al-Fatiha")
|
389 |
-
|
390 |
|
391 |
-
recite_btn = gr.Button("
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
recite_btn.click(ai_quran, inputs=[surah, ayat, mode], outputs=[arabic, english, audio])
|
400 |
|
401 |
demo.launch()
|
|
|
|
294 |
|
295 |
# demo.launch()
|
296 |
|
297 |
+
# import os
|
298 |
+
# import gradio as gr
|
299 |
+
# import requests
|
300 |
+
# from TTS.api import TTS
|
301 |
+
|
302 |
+
# # β
Accept Coqui TTS license
|
303 |
+
# os.environ["COQUI_TOS_AGREED"] = "1"
|
304 |
+
|
305 |
+
# # π Surah info: name -> (number, total ayats)
|
306 |
+
# surah_info = {
|
307 |
+
# "Al-Fatiha": (1, 7),
|
308 |
+
# "Al-Baqarah": (2, 286),
|
309 |
+
# "Aal-i-Imran": (3, 200),
|
310 |
+
# "An-Nisa": (4, 176),
|
311 |
+
# "Al-Ma'idah": (5, 120),
|
312 |
+
# "Al-An'am": (6, 165),
|
313 |
+
# "Al-A'raf": (7, 206),
|
314 |
+
# "Al-Anfal": (8, 75),
|
315 |
+
# "At-Tawbah": (9, 129),
|
316 |
+
# "Yunus": (10, 109),
|
317 |
+
# "Hud": (11, 123),
|
318 |
+
# "Yusuf": (12, 111),
|
319 |
+
# "Ar-Ra'd": (13, 43),
|
320 |
+
# "Ibrahim": (14, 52),
|
321 |
+
# "Al-Hijr": (15, 99),
|
322 |
+
# "An-Nahl": (16, 128),
|
323 |
+
# "Al-Isra": (17, 111),
|
324 |
+
# "Al-Kahf": (18, 110),
|
325 |
+
# "Maryam": (19, 98),
|
326 |
+
# "Taha": (20, 135),
|
327 |
+
# # π Add remaining up to Surah 114
|
328 |
+
# "An-Nas": (114, 6),
|
329 |
+
# }
|
330 |
+
|
331 |
+
# # β
Load TTS with Arabic + speaker support
|
332 |
+
# tts = TTS(model_name="tts_models/multilingual/multi-dataset/xtts_v2")
|
333 |
+
# speaker = "random" # or use "en_0", "ar_0" etc.
|
334 |
+
|
335 |
+
# # π Main function
|
336 |
+
# def ai_quran(surah_name, ayat_num, mode):
|
337 |
+
# surah_num, total_ayats = surah_info.get(surah_name, (None, None))
|
338 |
+
# if not surah_num:
|
339 |
+
# return "Invalid Surah", "", None
|
340 |
+
|
341 |
+
# if mode == "Full Surah":
|
342 |
+
# url = f"https://api.alquran.cloud/v1/surah/{surah_num}/editions/quran-simple,en.asad"
|
343 |
+
# else: # Single Ayah
|
344 |
+
# if not ayat_num or ayat_num < 1 or ayat_num > total_ayats:
|
345 |
+
# return f"β Ayat number must be between 1 and {total_ayats}", "", None
|
346 |
+
# url = f"https://api.alquran.cloud/v1/ayah/{surah_num}:{ayat_num}/editions/quran-simple,en.asad"
|
347 |
+
|
348 |
+
# try:
|
349 |
+
# res = requests.get(url)
|
350 |
+
# res.raise_for_status()
|
351 |
+
# data = res.json()
|
352 |
+
|
353 |
+
# if mode == "Full Surah":
|
354 |
+
# arabic_ayahs = data['data'][0]['ayahs']
|
355 |
+
# english_ayahs = data['data'][1]['ayahs']
|
356 |
+
# arabic_text = "\n".join([a['text'] for a in arabic_ayahs])
|
357 |
+
# english_text = "\n".join([e['text'] for e in english_ayahs])
|
358 |
+
# else:
|
359 |
+
# arabic_text = data['data'][0]['text']
|
360 |
+
# english_text = data['data'][1]['text']
|
361 |
+
|
362 |
+
# # π Generate TTS
|
363 |
+
# audio_path = "ayat.wav"
|
364 |
+
# tts.tts_to_file(
|
365 |
+
# text=arabic_text,
|
366 |
+
# speaker=speaker,
|
367 |
+
# language="ar",
|
368 |
+
# file_path=audio_path
|
369 |
+
# )
|
370 |
+
|
371 |
+
# return arabic_text, english_text, audio_path
|
372 |
+
|
373 |
+
# except Exception as e:
|
374 |
+
# return f"API Error: {e}", "", None
|
375 |
+
|
376 |
+
# # π§ Ayat field visibility toggle
|
377 |
+
# def toggle_ayat(mode, surah):
|
378 |
+
# if mode == "Full Surah":
|
379 |
+
# return gr.update(visible=False)
|
380 |
+
# return gr.update(visible=True, maximum=surah_info[surah][1])
|
381 |
+
|
382 |
+
# # ποΈ Gradio UI
|
383 |
+
# with gr.Blocks(title="π AI Quran Reciter") as demo:
|
384 |
+
# gr.Markdown("## π AI Quran Reciter with Arabic Voice | XTTSv2 Model")
|
385 |
+
|
386 |
+
# with gr.Row():
|
387 |
+
# mode = gr.Radio(["Full Surah", "Single Ayat"], label="Mode", value="Full Surah")
|
388 |
+
# surah = gr.Dropdown(choices=list(surah_info.keys()), label="Surah", value="Al-Fatiha")
|
389 |
+
# ayat = gr.Number(label="Ayat Number", visible=False)
|
390 |
+
|
391 |
+
# recite_btn = gr.Button("π₯ Recite")
|
392 |
+
# arabic = gr.Textbox(label="π Arabic Text")
|
393 |
+
# english = gr.Textbox(label="π English Translation")
|
394 |
+
# audio = gr.Audio(label="π Listen")
|
395 |
+
|
396 |
+
# # Event hooks
|
397 |
+
# mode.change(toggle_ayat, inputs=[mode, surah], outputs=ayat)
|
398 |
+
# surah.change(toggle_ayat, inputs=[mode, surah], outputs=ayat)
|
399 |
+
# recite_btn.click(ai_quran, inputs=[surah, ayat, mode], outputs=[arabic, english, audio])
|
400 |
+
|
401 |
+
# demo.launch()
|
402 |
+
|
403 |
import os
|
404 |
import gradio as gr
|
405 |
import requests
|
406 |
from TTS.api import TTS
|
407 |
|
408 |
+
# β
Accept Coqui license for Hugging Face Space
|
409 |
os.environ["COQUI_TOS_AGREED"] = "1"
|
410 |
|
411 |
+
# β
Fix PyTorch 2.6 checkpoint loading issue
|
412 |
+
import torch
|
413 |
+
from torch.serialization import add_safe_globals
|
414 |
+
from TTS.tts.configs.xtts_config import XttsConfig
|
415 |
+
add_safe_globals([XttsConfig])
|
416 |
+
|
417 |
+
# β
Load multilingual XTTSv2 model (speaker supported)
|
418 |
+
tts = TTS(model_name="tts_models/multilingual/multi-dataset/xtts_v2")
|
419 |
+
speaker_wav = None # Optional: path to your own .wav voice file
|
420 |
+
|
421 |
+
# Surah list with Ayah counts (can be extended)
|
422 |
surah_info = {
|
423 |
"Al-Fatiha": (1, 7),
|
424 |
"Al-Baqarah": (2, 286),
|
|
|
440 |
"Al-Kahf": (18, 110),
|
441 |
"Maryam": (19, 98),
|
442 |
"Taha": (20, 135),
|
443 |
+
"Al-Anbiya": (21, 112),
|
444 |
+
"Al-Hajj": (22, 78),
|
445 |
+
"Al-Mu'minun": (23, 118),
|
446 |
+
"An-Nur": (24, 64),
|
447 |
+
"Al-Furqan": (25, 77),
|
448 |
+
"Ash-Shu'ara": (26, 227),
|
449 |
+
"An-Naml": (27, 93),
|
450 |
+
"Al-Qasas": (28, 88),
|
451 |
+
"Al-Ankabut": (29, 69),
|
452 |
+
"Ar-Rum": (30, 60),
|
453 |
+
"Luqman": (31, 34),
|
454 |
+
"As-Sajda": (32, 30),
|
455 |
+
"Al-Ahzab": (33, 73),
|
456 |
+
"Saba": (34, 54),
|
457 |
+
"Fatir": (35, 45),
|
458 |
+
"Ya-Sin": (36, 83),
|
459 |
+
"As-Saffat": (37, 182),
|
460 |
+
"Sad": (38, 88),
|
461 |
+
"Az-Zumar": (39, 75),
|
462 |
+
"Ghafir": (40, 85),
|
463 |
+
"Fussilat": (41, 54),
|
464 |
+
"Ash-Shura": (42, 53),
|
465 |
+
"Az-Zukhruf": (43, 89),
|
466 |
+
"Ad-Dukhan": (44, 59),
|
467 |
+
"Al-Jathiya": (45, 37),
|
468 |
+
"Al-Ahqaf": (46, 35),
|
469 |
+
"Muhammad": (47, 38),
|
470 |
+
"Al-Fath": (48, 29),
|
471 |
+
"Al-Hujurat": (49, 18),
|
472 |
+
"Qaf": (50, 45),
|
473 |
+
"Adh-Dhariyat": (51, 60),
|
474 |
+
"At-Tur": (52, 49),
|
475 |
+
"An-Najm": (53, 62),
|
476 |
+
"Al-Qamar": (54, 55),
|
477 |
+
"Ar-Rahman": (55, 78),
|
478 |
+
"Al-Waqia": (56, 96),
|
479 |
+
"Al-Hadid": (57, 29),
|
480 |
+
"Al-Mujadila": (58, 22),
|
481 |
+
"Al-Hashr": (59, 24),
|
482 |
+
"Al-Mumtahina": (60, 13),
|
483 |
+
"As-Saff": (61, 14),
|
484 |
+
"Al-Jumu'a": (62, 11),
|
485 |
+
"Al-Munafiqun": (63, 11),
|
486 |
+
"At-Taghabun": (64, 18),
|
487 |
+
"At-Talaq": (65, 12),
|
488 |
+
"At-Tahrim": (66, 12),
|
489 |
+
"Al-Mulk": (67, 30),
|
490 |
+
"Al-Qalam": (68, 52),
|
491 |
+
"Al-Haqqa": (69, 52),
|
492 |
+
"Al-Ma'arij": (70, 44),
|
493 |
+
"Nuh": (71, 28),
|
494 |
+
"Al-Jinn": (72, 28),
|
495 |
+
"Al-Muzzammil": (73, 20),
|
496 |
+
"Al-Muddaththir": (74, 56),
|
497 |
+
"Al-Qiyamah": (75, 40),
|
498 |
+
"Al-Insan": (76, 31),
|
499 |
+
"Al-Mursalat": (77, 50),
|
500 |
+
"An-Naba": (78, 40),
|
501 |
+
"An-Nazi'at": (79, 46),
|
502 |
+
"Abasa": (80, 42),
|
503 |
+
"At-Takwir": (81, 29),
|
504 |
+
"Al-Infitar": (82, 19),
|
505 |
+
"Al-Mutaffifin": (83, 36),
|
506 |
+
"Al-Inshiqaq": (84, 25),
|
507 |
+
"Al-Buruj": (85, 22),
|
508 |
+
"At-Tariq": (86, 17),
|
509 |
+
"Al-A'la": (87, 19),
|
510 |
+
"Al-Ghashiyah": (88, 26),
|
511 |
+
"Al-Fajr": (89, 30),
|
512 |
+
"Al-Balad": (90, 20),
|
513 |
+
"Ash-Shams": (91, 15),
|
514 |
+
"Al-Layl": (92, 21),
|
515 |
+
"Ad-Duha": (93, 11),
|
516 |
+
"Ash-Sharh": (94, 8),
|
517 |
+
"At-Tin": (95, 8),
|
518 |
+
"Al-Alaq": (96, 19),
|
519 |
+
"Al-Qadr": (97, 5),
|
520 |
+
"Al-Bayyina": (98, 8),
|
521 |
+
"Az-Zalzalah": (99, 8),
|
522 |
+
"Al-Adiyat": (100, 11),
|
523 |
+
"Al-Qari'a": (101, 11),
|
524 |
+
"At-Takathur": (102, 8),
|
525 |
+
"Al-Asr": (103, 3),
|
526 |
+
"Al-Humazah": (104, 9),
|
527 |
+
"Al-Fil": (105, 5),
|
528 |
+
"Quraysh": (106, 4),
|
529 |
+
"Al-Ma'un": (107, 7),
|
530 |
+
"Al-Kawthar": (108, 3),
|
531 |
+
"Al-Kafirun": (109, 6),
|
532 |
+
"An-Nasr": (110, 3),
|
533 |
+
"Al-Masad": (111, 5),
|
534 |
+
"Al-Ikhlas": (112, 4),
|
535 |
+
"Al-Falaq": (113, 5),
|
536 |
+
"An-Nas": (114, 6)
|
537 |
}
|
538 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
539 |
|
540 |
+
def recite_quran(surah_name, ayah_number, mode):
|
541 |
+
surah_num, total_ayahs = surah_info[surah_name]
|
542 |
if mode == "Full Surah":
|
543 |
url = f"https://api.alquran.cloud/v1/surah/{surah_num}/editions/quran-simple,en.asad"
|
544 |
+
else:
|
545 |
+
if not (1 <= ayah_number <= total_ayahs):
|
546 |
+
return f"Ayat must be between 1 and {total_ayahs}", "", None
|
547 |
+
url = f"https://api.alquran.cloud/v1/ayah/{surah_num}:{ayah_number}/editions/quran-simple,en.asad"
|
548 |
|
549 |
try:
|
550 |
res = requests.get(url)
|
|
|
552 |
data = res.json()
|
553 |
|
554 |
if mode == "Full Surah":
|
555 |
+
arabic = "\n".join([a['text'] for a in data['data'][0]['ayahs']])
|
556 |
+
english = "\n".join([a['text'] for a in data['data'][1]['ayahs']])
|
|
|
|
|
557 |
else:
|
558 |
+
arabic = data['data'][0]['text']
|
559 |
+
english = data['data'][1]['text']
|
560 |
|
561 |
+
audio_path = "output.wav"
|
|
|
562 |
tts.tts_to_file(
|
563 |
+
text=arabic,
|
564 |
+
speaker_wav=speaker_wav,
|
565 |
language="ar",
|
566 |
file_path=audio_path
|
567 |
)
|
568 |
|
569 |
+
return arabic, english, audio_path
|
570 |
|
571 |
except Exception as e:
|
572 |
+
return f"β Error: {e}", "", None
|
573 |
|
574 |
+
def toggle_ayah_visibility(mode, surah):
|
|
|
575 |
if mode == "Full Surah":
|
576 |
return gr.update(visible=False)
|
577 |
return gr.update(visible=True, maximum=surah_info[surah][1])
|
578 |
|
579 |
+
# Gradio Interface
|
580 |
+
with gr.Blocks(title="π Quran AI Reader (with Speaker)") as demo:
|
581 |
+
gr.Markdown("## π AI Quran Reciter using XTTSv2 (Arabic Voice with Speaker)")
|
582 |
|
583 |
with gr.Row():
|
584 |
mode = gr.Radio(["Full Surah", "Single Ayat"], label="Mode", value="Full Surah")
|
585 |
surah = gr.Dropdown(choices=list(surah_info.keys()), label="Surah", value="Al-Fatiha")
|
586 |
+
ayah = gr.Number(label="Ayat Number", visible=False)
|
587 |
|
588 |
+
recite_btn = gr.Button("π§ Recite")
|
589 |
+
arabic_box = gr.Textbox(label="π Arabic Text")
|
590 |
+
english_box = gr.Textbox(label="π English Translation")
|
591 |
+
audio_output = gr.Audio(label="π Listen")
|
592 |
|
593 |
+
mode.change(toggle_ayah_visibility, inputs=[mode, surah], outputs=ayah)
|
594 |
+
surah.change(toggle_ayah_visibility, inputs=[mode, surah], outputs=ayah)
|
595 |
+
recite_btn.click(recite_quran, inputs=[surah, ayah, mode], outputs=[arabic_box, english_box, audio_output])
|
|
|
596 |
|
597 |
demo.launch()
|
598 |
+
|