hivecorp commited on
Commit
411d260
·
verified ·
1 Parent(s): f5a7824

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +43 -120
app.py CHANGED
@@ -9,42 +9,6 @@ import time
9
  import tempfile
10
  from concurrent.futures import ThreadPoolExecutor
11
  from typing import List, Tuple, Optional, Dict, Any
12
- from pathlib import Path
13
-
14
- def create_download_link(audio_path, label="Download"):
15
- if audio_path is None:
16
- return "" # Return empty string instead of None for HTML component
17
-
18
- filename = Path(audio_path).name
19
- # IMPORTANT: For Hugging Face Spaces, ensure your file URLs are correctly formed
20
- # This might need to point to /file= if Gradio serves static files that way
21
- # Or, if deployed on Hugging Face Spaces, the file serving might be handled by the backend directly
22
- # and not necessarily through gradio_api/file=. For now, keep as is, but be aware.
23
- base_url = "hivecorp-insta-maker-3.hf.space" # Replace with your actual deployment domain
24
- file_url = f"https://{base_url}/gradio_api/file={audio_path}" # This path might be problematic on Spaces
25
-
26
- return f"""
27
- <a href="{file_url}"
28
- download="{filename}"
29
- target="_blank"
30
- rel="noopener noreferrer"
31
- style="display: inline-block; padding: 10px 20px; background: linear-gradient(135deg, #4776E6, #8E54E9); color: white; text-decoration: none; border-radius: 8px; font-weight: 600; transition: all 0.3s ease;"
32
- onmouseover="this.style.transform='translateY(-2px)'; this.style.boxShadow='0 5px 15px rgba(71, 118, 230, 0.3)';"
33
- onmouseout="this.style.transform='translateY(0)'; this.style.boxShadow='none';"
34
- onclick="event.preventDefault(); fetch(this.href).then(resp => resp.blob()).then(blob => {{
35
- const url = window.URL.createObjectURL(blob);
36
- const a = document.createElement('a');
37
- a.style.display = 'none';
38
- a.href = url;
39
- a.download = '{filename}';
40
- document.body.appendChild(a);
41
- a.click();
42
- window.URL.revokeObjectURL(url);
43
- document.body.removeChild(a);
44
- }});">
45
- ⬇️ {label}
46
- </a>
47
- """
48
  import math
49
  from dataclasses import dataclass
50
 
@@ -65,7 +29,7 @@ def get_audio_length(audio_file):
65
 
66
  def format_time_ms(milliseconds):
67
  seconds, ms = divmod(int(milliseconds), 1000)
68
- mins, secs = divmod(mins, 60)
69
  hrs, mins = divmod(mins, 60)
70
  return f"{hrs:02}:{mins:02}:{secs:02},{ms:03}"
71
 
@@ -453,52 +417,32 @@ async def generate_accurate_srt(
453
 
454
  return srt_path, audio_path
455
 
 
456
  async def process_text_with_progress(
457
- text,
458
- pitch,
459
- rate,
460
- voice,
461
- words_per_line,
462
- lines_per_segment,
463
  parallel_processing,
464
  progress=gr.Progress()
465
  ):
466
- # Initialize all outputs to their "cleared" state.
467
- # We now control visibility of the *groups* not individual items directly.
468
- srt_file_update = gr.File(value=None) # No visible here, controlled by group
469
- audio_file_update = gr.File(value=None) # No visible here, controlled by group
470
- audio_output_val = None
471
- error_output_update = gr.Textbox(value="", visible=False)
472
- srt_download_link_html = "" # HTML content, not a gr.HTML object
473
- audio_download_link_html = "" # HTML content, not a gr.HTML object
474
-
475
- # Group visibility controls
476
- file_group_visible = gr.update(visible=False)
477
- download_group_visible = gr.update(visible=False)
478
-
479
  # Input validation
480
  if not text or text.strip() == "":
481
- error_output_update = gr.Textbox(value="Please enter some text to convert to speech.", visible=True)
482
- return (
483
- srt_file_update,
484
- audio_file_update,
485
- audio_output_val,
486
- error_output_update,
487
- file_group_visible, # Output for the file group visibility
488
- download_group_visible, # Output for the download link group visibility
489
- srt_download_link_html, # Output for srt_download (HTML string)
490
- audio_download_link_html # Output for audio_download (HTML string)
491
- )
492
-
493
  pitch_str = f"{pitch:+d}Hz" if pitch != 0 else "+0Hz"
494
  rate_str = f"{rate:+d}%" if rate != 0 else "+0%"
495
-
496
  try:
 
497
  progress(0, "Preparing text...")
498
-
499
  def update_progress(value, status):
500
  progress(value, status)
501
-
502
  srt_path, audio_path = await generate_accurate_srt(
503
  text,
504
  voice_options[voice],
@@ -509,33 +453,25 @@ async def process_text_with_progress(
509
  progress_callback=update_progress,
510
  parallel=parallel_processing
511
  )
512
-
513
- srt_file_update = gr.File(value=srt_path)
514
- audio_file_update = gr.File(value=audio_path)
515
- audio_output_val = audio_path
516
 
517
- file_group_visible = gr.update(visible=True)
518
- download_group_visible = gr.update(visible=True)
 
519
 
520
- srt_download_link_html = create_download_link(srt_path, "Download Subtitles (.srt)")
521
- audio_download_link_html = create_download_link(audio_path, "Download Audio (.mp3)")
522
-
 
 
 
 
 
523
  except TTSError as e:
524
- error_output_update = gr.Textbox(value=f"TTS Error: {str(e)}", visible=True)
 
525
  except Exception as e:
526
- error_output_update = gr.Textbox(value=f"Unexpected error: {str(e)}", visible=True)
527
-
528
- # Always return the full tuple of updated components
529
- return (
530
- srt_file_update,
531
- audio_file_update,
532
- audio_output_val,
533
- error_output_update,
534
- file_group_visible,
535
- download_group_visible,
536
- srt_download_link_html,
537
- audio_download_link_html
538
- )
539
 
540
 
541
  # Voice options dictionary
@@ -643,28 +579,18 @@ with gr.Blocks(title="Advanced TTS with Configurable SRT Generation") as app:
643
 
644
  submit_btn = gr.Button("Generate Audio & Subtitles")
645
 
646
- # Initialize error message component
647
- error_output = gr.Textbox(label="Status", value="", visible=False)
648
 
649
  with gr.Row():
650
  with gr.Column():
651
  audio_output = gr.Audio(label="Preview Audio")
652
-
653
- # --- NEW: Group for gr.File components ---
654
- with gr.Column() as file_download_group:
655
- # gr.File components initially visible within their group
656
- srt_file = gr.File(label="Download SRT", value=None)
657
- audio_file = gr.File(label="Download Audio", value=None)
658
- file_download_group.visible = False # Control group visibility
659
-
660
- # --- NEW: Group for gr.HTML download links ---
661
- with gr.Column() as html_download_group:
662
- # gr.HTML components initialized with empty string
663
- srt_download = gr.HTML(value="")
664
- audio_download = gr.HTML(value="")
665
- html_download_group.visible = False # Control group visibility
666
-
667
- # Handle button click
668
  submit_btn.click(
669
  fn=process_text_with_progress,
670
  inputs=[
@@ -677,14 +603,11 @@ with gr.Blocks(title="Advanced TTS with Configurable SRT Generation") as app:
677
  parallel_processing
678
  ],
679
  outputs=[
680
- srt_file, # gr.File
681
- audio_file, # gr.File
682
- audio_output, # gr.Audio
683
- error_output, # gr.Textbox
684
- file_download_group,# Control visibility of this group
685
- html_download_group,# Control visibility of this group
686
- srt_download, # gr.HTML (will receive the HTML string directly)
687
- audio_download # gr.HTML (will receive the HTML string directly)
688
  ],
689
  api_name="generate"
690
  )
 
9
  import tempfile
10
  from concurrent.futures import ThreadPoolExecutor
11
  from typing import List, Tuple, Optional, Dict, Any
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  import math
13
  from dataclasses import dataclass
14
 
 
29
 
30
  def format_time_ms(milliseconds):
31
  seconds, ms = divmod(int(milliseconds), 1000)
32
+ mins, secs = divmod(seconds, 60)
33
  hrs, mins = divmod(mins, 60)
34
  return f"{hrs:02}:{mins:02}:{secs:02},{ms:03}"
35
 
 
417
 
418
  return srt_path, audio_path
419
 
420
+ # IMPROVEMENT 4: Progress Reporting with proper error handling for older Gradio versions
421
  async def process_text_with_progress(
422
+ text,
423
+ pitch,
424
+ rate,
425
+ voice,
426
+ words_per_line,
427
+ lines_per_segment,
428
  parallel_processing,
429
  progress=gr.Progress()
430
  ):
 
 
 
 
 
 
 
 
 
 
 
 
 
431
  # Input validation
432
  if not text or text.strip() == "":
433
+ return None, None, None, gr.update(value="", visible=True), gr.update(value="", visible=False), "Please enter some text to convert to speech."
434
+
435
+ # Format pitch and rate strings
 
 
 
 
 
 
 
 
 
436
  pitch_str = f"{pitch:+d}Hz" if pitch != 0 else "+0Hz"
437
  rate_str = f"{rate:+d}%" if rate != 0 else "+0%"
438
+
439
  try:
440
+ # Start progress tracking
441
  progress(0, "Preparing text...")
442
+
443
  def update_progress(value, status):
444
  progress(value, status)
445
+
446
  srt_path, audio_path = await generate_accurate_srt(
447
  text,
448
  voice_options[voice],
 
453
  progress_callback=update_progress,
454
  parallel=parallel_processing
455
  )
 
 
 
 
456
 
457
+ # Generate Markdown links for download that open in a new tab
458
+ srt_download_link = f'<a href="file={srt_path}" download="subtitles.srt" target="_blank">Download SRT</a>'
459
+ audio_download_link = f'<a href="file={audio_path}" download="audio.mp3" target="_blank">Download Audio</a>'
460
 
461
+ # Return the paths for gr.Audio and Markdown for download links
462
+ return (
463
+ audio_path,
464
+ gr.update(value=srt_download_link, visible=True), # Use gr.Markdown for SRT download
465
+ gr.update(value=audio_download_link, visible=True), # Use gr.Markdown for Audio download
466
+ gr.update(value="", visible=False), # Hide error message
467
+ "" # Clear error message
468
+ )
469
  except TTSError as e:
470
+ # Return specific TTS error
471
+ return None, gr.update(value="", visible=False), gr.update(value="", visible=False), gr.update(value=f"TTS Error: {str(e)}", visible=True), f"TTS Error: {str(e)}"
472
  except Exception as e:
473
+ # Return any other error
474
+ return None, gr.update(value="", visible=False), gr.update(value="", visible=False), gr.update(value=f"Unexpected error: {str(e)}", visible=True), f"Unexpected error: {str(e)}"
 
 
 
 
 
 
 
 
 
 
 
475
 
476
 
477
  # Voice options dictionary
 
579
 
580
  submit_btn = gr.Button("Generate Audio & Subtitles")
581
 
582
+ # Add error message component
583
+ error_output = gr.Textbox(label="Status", visible=False)
584
 
585
  with gr.Row():
586
  with gr.Column():
587
  audio_output = gr.Audio(label="Preview Audio")
588
+ with gr.Column():
589
+ # Change gr.File to gr.Markdown for download links
590
+ srt_download_link = gr.Markdown(value="", visible=False, label="Download SRT")
591
+ audio_download_link = gr.Markdown(value="", visible=False, label="Download Audio")
592
+
593
+ # Handle button click with manual error handling instead of .catch()
 
 
 
 
 
 
 
 
 
 
594
  submit_btn.click(
595
  fn=process_text_with_progress,
596
  inputs=[
 
603
  parallel_processing
604
  ],
605
  outputs=[
606
+ audio_output,
607
+ srt_download_link, # Output to Markdown component
608
+ audio_download_link, # Output to Markdown component
609
+ error_output,
610
+ error_output
 
 
 
611
  ],
612
  api_name="generate"
613
  )