hivecorp commited on
Commit
b00ca7d
·
verified ·
1 Parent(s): 2efe2f2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +63 -87
app.py CHANGED
@@ -281,41 +281,40 @@ class FileManager:
281
  except Exception:
282
  pass # Ignore if directory isn't empty or can't be removed
283
 
284
- def create_download_link(file_path, label="Download"):
285
- """Create a styled download link for a file"""
286
  if not file_path:
287
  return None
288
-
289
  filename = os.path.basename(file_path)
290
  return f"""
291
- <div class="download-btn" style="margin: 10px 0;">
292
- <a href="file={file_path}"
293
- download="{filename}"
294
- target="_blank"
295
- rel="noopener noreferrer"
296
- style="display: flex; align-items: center; justify-content: center; padding: 12px 24px; background: linear-gradient(135deg, #4776E6, #8E54E9); color: white; text-decoration: none; border-radius: 8px; font-weight: 600; transition: all 0.3s ease; text-align: center; width: 100%; gap: 8px;"
297
- onmouseover="this.style.transform='translateY(-2px)'; this.style.boxShadow='0 5px 15px rgba(71, 118, 230, 0.3)';"
298
- onmouseout="this.style.transform='translateY(0)'; this.style.boxShadow='none';"
299
- onclick="event.preventDefault(); fetch(this.href).then(resp => resp.blob()).then(blob => {{
300
- const url = window.URL.createObjectURL(blob);
301
- const a = document.createElement('a');
302
- a.style.display = 'none';
303
- a.href = url;
304
- a.download = '{filename}';
305
- document.body.appendChild(a);
306
- a.click();
307
- window.URL.revokeObjectURL(url);
308
- document.body.removeChild(a);
309
- }});">
310
- <span style="font-size: 20px;">⬇️</span>
311
- <span>{label}</span>
312
- </a>
313
- </div>
314
  """
315
 
316
  # Create global file manager
317
  file_manager = FileManager()
318
 
 
 
319
  # IMPROVEMENT 3: Parallel Processing for Segments
320
  async def generate_accurate_srt(
321
  text: str,
@@ -462,7 +461,7 @@ async def process_text_with_progress(
462
  ):
463
  # Input validation
464
  if not text or text.strip() == "":
465
- return None, None, None, "Please enter some text to convert to speech."
466
 
467
  # Format pitch and rate strings
468
  pitch_str = f"{pitch:+d}Hz" if pitch != 0 else "+0Hz"
@@ -486,28 +485,14 @@ async def process_text_with_progress(
486
  parallel=parallel_processing
487
  )
488
 
489
- # Create download links with descriptive labels
490
- srt_download_link = create_download_link(srt_path, "Download Subtitles (.srt)")
491
- audio_download_link = create_download_link(audio_path, "Download Audio (.mp3)")
492
-
493
- # Return exactly 4 values in the expected order:
494
- # 1. Audio preview path
495
- # 2. SRT download button HTML
496
- # 3. Audio download button HTML
497
- # 4. Status message
498
- return (
499
- audio_path, # Audio preview
500
- srt_download_link, # SRT download button
501
- audio_download_link, # Audio download button
502
- "Generation completed successfully!" # Status message
503
- )
504
-
505
  except TTSError as e:
506
- # Return error state with proper number of outputs
507
- return None, None, None, f"TTS Error: {str(e)}"
508
  except Exception as e:
509
- # Return error state with proper number of outputs
510
- return None, None, None, f"Unexpected error: {str(e)}"
511
 
512
  # Voice options dictionary
513
  voice_options = {
@@ -557,41 +542,33 @@ import atexit
557
  atexit.register(file_manager.cleanup_all)
558
 
559
  # Create Gradio interface
560
- with gr.Blocks(title="Advanced TTS with Configurable SRT Generation", analytics_enabled=False) as app:
561
  gr.Markdown("# Advanced TTS with Configurable SRT Generation")
562
  gr.Markdown("Generate perfectly synchronized audio and subtitles with natural speech patterns.")
563
 
564
  with gr.Row():
565
  with gr.Column(scale=3):
566
- text_input = gr.Textbox(
567
- label="Enter Text",
568
- lines=10,
569
- placeholder="Enter your text here...",
570
- elem_id="text_input"
571
- )
572
 
573
  with gr.Column(scale=2):
574
  voice_dropdown = gr.Dropdown(
575
  label="Select Voice",
576
  choices=list(voice_options.keys()),
577
- value="Jenny Female",
578
- elem_id="voice_dropdown"
579
  )
580
  pitch_slider = gr.Slider(
581
  label="Pitch Adjustment (Hz)",
582
  minimum=-10,
583
  maximum=10,
584
  value=0,
585
- step=1,
586
- elem_id="pitch_slider"
587
  )
588
  rate_slider = gr.Slider(
589
  label="Rate Adjustment (%)",
590
  minimum=-25,
591
  maximum=25,
592
  value=0,
593
- step=1,
594
- elem_id="rate_slider"
595
  )
596
 
597
  with gr.Row():
@@ -602,8 +579,7 @@ with gr.Blocks(title="Advanced TTS with Configurable SRT Generation", analytics_
602
  maximum=12,
603
  value=6,
604
  step=1,
605
- info="Controls how many words appear on each line of the subtitle",
606
- elem_id="words_per_line"
607
  )
608
  with gr.Column():
609
  lines_per_segment = gr.Slider(
@@ -612,34 +588,30 @@ with gr.Blocks(title="Advanced TTS with Configurable SRT Generation", analytics_
612
  maximum=4,
613
  value=2,
614
  step=1,
615
- info="Controls how many lines appear in each subtitle segment",
616
- elem_id="lines_per_segment"
617
  )
618
  with gr.Column():
619
  parallel_processing = gr.Checkbox(
620
  label="Enable Parallel Processing",
621
  value=True,
622
- info="Process multiple segments simultaneously for faster conversion (recommended for longer texts)",
623
- elem_id="parallel_processing"
624
  )
625
 
626
- submit_btn = gr.Button("Generate Audio & Subtitles", elem_id="submit_btn")
627
- # Output components
628
- with gr.Column(variant="panel") as output_col:
629
- gr.Markdown("### Generated Output")
630
- # Main output containers
631
- with gr.Row():
632
- audio_preview = gr.Audio(label="Preview Audio", elem_id="audio_preview")
633
-
634
- with gr.Row():
635
- with gr.Column(scale=1):
636
- srt_download = gr.HTML(label="", elem_id="srt_download")
637
- with gr.Column(scale=1):
638
- audio_download = gr.HTML(label="", elem_id="audio_download")
639
-
640
- error_output = gr.Textbox(label="Status", elem_id="error_output")
641
 
642
- # Handle button click
 
 
 
 
 
 
 
 
 
 
 
 
643
  submit_btn.click(
644
  fn=process_text_with_progress,
645
  inputs=[
@@ -652,11 +624,15 @@ with gr.Blocks(title="Advanced TTS with Configurable SRT Generation", analytics_
652
  parallel_processing
653
  ],
654
  outputs=[
655
- audio_preview, # Audio preview
656
- srt_download, # SRT download link
657
- audio_download, # Audio download link
658
- error_output # Status/error message
659
- ]
 
 
 
 
660
  )
661
 
662
  if __name__ == "__main__":
 
281
  except Exception:
282
  pass # Ignore if directory isn't empty or can't be removed
283
 
284
+
285
+ def create_download_link(file_path, label="Download"):
286
  if not file_path:
287
  return None
 
288
  filename = os.path.basename(file_path)
289
  return f"""
290
+ <a href="file={file_path}"
291
+ download="{filename}"
292
+ target="_blank"
293
+ rel="noopener noreferrer"
294
+ 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; text-align: center; width: 100%; margin: 5px 0;"
295
+ onmouseover="this.style.transform='translateY(-2px)'; this.style.boxShadow='0 5px 15px rgba(71, 118, 230, 0.3)';"
296
+ onmouseout="this.style.transform='translateY(0)'; this.style.boxShadow='none';"
297
+ onclick="event.preventDefault(); fetch(this.href).then(resp => resp.blob()).then(blob => {{
298
+ const url = window.URL.createObjectURL(blob);
299
+ const a = document.createElement('a');
300
+ a.style.display = 'none';
301
+ a.href = url;
302
+ a.download = '{filename}';
303
+ document.body.appendChild(a);
304
+ a.click();
305
+ window.URL.revokeObjectURL(url);
306
+ document.body.removeChild(a);
307
+ }});">
308
+ ⬇️ {label}
309
+ </a>
310
+
 
 
311
  """
312
 
313
  # Create global file manager
314
  file_manager = FileManager()
315
 
316
+
317
+
318
  # IMPROVEMENT 3: Parallel Processing for Segments
319
  async def generate_accurate_srt(
320
  text: str,
 
461
  ):
462
  # Input validation
463
  if not text or text.strip() == "":
464
+ return None, None, None, True, "Please enter some text to convert to speech."
465
 
466
  # Format pitch and rate strings
467
  pitch_str = f"{pitch:+d}Hz" if pitch != 0 else "+0Hz"
 
485
  parallel=parallel_processing
486
  )
487
 
488
+ # If successful, return results and hide error
489
+ return srt_path, audio_path, audio_path, False, ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
490
  except TTSError as e:
491
+ # Return specific TTS error
492
+ return None, None, None, True, f"TTS Error: {str(e)}"
493
  except Exception as e:
494
+ # Return any other error
495
+ return None, None, None, True, f"Unexpected error: {str(e)}"
496
 
497
  # Voice options dictionary
498
  voice_options = {
 
542
  atexit.register(file_manager.cleanup_all)
543
 
544
  # Create Gradio interface
545
+ with gr.Blocks(title="Advanced TTS with Configurable SRT Generation") as app:
546
  gr.Markdown("# Advanced TTS with Configurable SRT Generation")
547
  gr.Markdown("Generate perfectly synchronized audio and subtitles with natural speech patterns.")
548
 
549
  with gr.Row():
550
  with gr.Column(scale=3):
551
+ text_input = gr.Textbox(label="Enter Text", lines=10, placeholder="Enter your text here...")
 
 
 
 
 
552
 
553
  with gr.Column(scale=2):
554
  voice_dropdown = gr.Dropdown(
555
  label="Select Voice",
556
  choices=list(voice_options.keys()),
557
+ value="Jenny Female"
 
558
  )
559
  pitch_slider = gr.Slider(
560
  label="Pitch Adjustment (Hz)",
561
  minimum=-10,
562
  maximum=10,
563
  value=0,
564
+ step=1
 
565
  )
566
  rate_slider = gr.Slider(
567
  label="Rate Adjustment (%)",
568
  minimum=-25,
569
  maximum=25,
570
  value=0,
571
+ step=1
 
572
  )
573
 
574
  with gr.Row():
 
579
  maximum=12,
580
  value=6,
581
  step=1,
582
+ info="Controls how many words appear on each line of the subtitle"
 
583
  )
584
  with gr.Column():
585
  lines_per_segment = gr.Slider(
 
588
  maximum=4,
589
  value=2,
590
  step=1,
591
+ info="Controls how many lines appear in each subtitle segment"
 
592
  )
593
  with gr.Column():
594
  parallel_processing = gr.Checkbox(
595
  label="Enable Parallel Processing",
596
  value=True,
597
+ info="Process multiple segments simultaneously for faster conversion (recommended for longer texts)"
 
598
  )
599
 
600
+ submit_btn = gr.Button("Generate Audio & Subtitles")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
601
 
602
+ # Add error message component
603
+ error_output = gr.Textbox(label="Status", visible=False)
604
+
605
+ with gr.Row():
606
+ with gr.Column():
607
+ audio_output = gr.Audio(label="Preview Audio")
608
+ with gr.Column():
609
+ srt_file = gr.File(label="Download SRT")
610
+ audio_file = gr.File(label="Download Audio")
611
+ srt_download = gr.HTML(elem_classes="download-btn")
612
+ audio_download = gr.HTML(elem_classes="download-btn")
613
+
614
+ # Handle button click with manual error handling instead of .catch()
615
  submit_btn.click(
616
  fn=process_text_with_progress,
617
  inputs=[
 
624
  parallel_processing
625
  ],
626
  outputs=[
627
+ srt_file,
628
+ audio_file,
629
+ audio_output,
630
+ error_output,
631
+ error_output,
632
+ srt_download,
633
+ audio_download
634
+ ],
635
+ api_name="generate"
636
  )
637
 
638
  if __name__ == "__main__":