Spaces:
Sleeping
Sleeping
Update ttsfm-web/app.py
Browse files- ttsfm-web/app.py +2 -84
ttsfm-web/app.py
CHANGED
|
@@ -29,11 +29,6 @@ except ImportError:
|
|
| 29 |
from ttsfm.exceptions import APIException, NetworkException, ValidationException
|
| 30 |
from ttsfm.utils import validate_text_length, split_text_by_length
|
| 31 |
|
| 32 |
-
# Import Gradio for additional API/UI exposure
|
| 33 |
-
import gradio as gr
|
| 34 |
-
import tempfile
|
| 35 |
-
import base64
|
| 36 |
-
|
| 37 |
# Load environment variables
|
| 38 |
load_dotenv()
|
| 39 |
|
|
@@ -284,7 +279,7 @@ def generate_speech():
|
|
| 284 |
|
| 285 |
except TTSException as e:
|
| 286 |
logger.error(f"TTS error: {e}")
|
| 287 |
-
return
|
| 288 |
|
| 289 |
except Exception as e:
|
| 290 |
logger.error(f"Unexpected error: {e}")
|
|
@@ -337,6 +332,7 @@ def generate_speech_batch():
|
|
| 337 |
)
|
| 338 |
|
| 339 |
# Convert to base64 for JSON response
|
|
|
|
| 340 |
audio_b64 = base64.b64encode(response.audio_data).decode('utf-8')
|
| 341 |
|
| 342 |
results.append({
|
|
@@ -558,88 +554,10 @@ def internal_error(error):
|
|
| 558 |
logger.error(f"Internal server error: {error}")
|
| 559 |
return jsonify({"error": "Internal server error"}), 500
|
| 560 |
|
| 561 |
-
# Gradio Integration for external API/UI access
|
| 562 |
-
def generate_tts_gradio(text, voice, response_format, instructions=None):
|
| 563 |
-
try:
|
| 564 |
-
voice_enum = Voice(voice.lower())
|
| 565 |
-
format_enum = AudioFormat(response_format.lower())
|
| 566 |
-
response = tts_client.generate_speech(
|
| 567 |
-
text=text,
|
| 568 |
-
voice=voice_enum,
|
| 569 |
-
response_format=format_enum,
|
| 570 |
-
instructions=instructions,
|
| 571 |
-
max_length=4096,
|
| 572 |
-
validate_length=True
|
| 573 |
-
)
|
| 574 |
-
# Save to temporary file for Gradio Audio output
|
| 575 |
-
with tempfile.NamedTemporaryFile(delete=False, suffix=f".{response.format.value}") as tmp:
|
| 576 |
-
tmp.write(response.audio_data)
|
| 577 |
-
return tmp.name
|
| 578 |
-
except Exception as e:
|
| 579 |
-
raise gr.Error(f"Generation failed: {str(e)}")
|
| 580 |
-
|
| 581 |
-
def generate_tts_batch_gradio(text, voice, response_format, instructions=None, max_length=4096, preserve_words=True):
|
| 582 |
-
try:
|
| 583 |
-
voice_enum = Voice(voice.lower())
|
| 584 |
-
format_enum = AudioFormat(response_format.lower())
|
| 585 |
-
chunks = split_text_by_length(text, max_length, preserve_words)
|
| 586 |
-
results = []
|
| 587 |
-
for i, chunk in enumerate(chunks):
|
| 588 |
-
response = tts_client.generate_speech(
|
| 589 |
-
text=chunk,
|
| 590 |
-
voice=voice_enum,
|
| 591 |
-
response_format=format_enum,
|
| 592 |
-
instructions=instructions,
|
| 593 |
-
max_length=max_length,
|
| 594 |
-
validate_length=False
|
| 595 |
-
)
|
| 596 |
-
with tempfile.NamedTemporaryFile(delete=False, suffix=f".{response.format.value}") as tmp:
|
| 597 |
-
tmp.write(response.audio_data)
|
| 598 |
-
results.append((chunk, tmp.name))
|
| 599 |
-
return results
|
| 600 |
-
except Exception as e:
|
| 601 |
-
raise gr.Error(f"Batch generation failed: {str(e)}")
|
| 602 |
-
|
| 603 |
-
voices_list = [v.value for v in Voice]
|
| 604 |
-
formats_list = [f.value for f in AudioFormat]
|
| 605 |
-
|
| 606 |
-
with gr.Blocks(title="TTSFM Gradio Interface") as demo:
|
| 607 |
-
gr.Markdown("# TTSFM Text-to-Speech Interface")
|
| 608 |
-
with gr.Tab("Single Generation"):
|
| 609 |
-
text_input = gr.Textbox(label="Input Text", placeholder="Enter text to convert to speech...")
|
| 610 |
-
voice_dropdown = gr.Dropdown(choices=voices_list, label="Voice", value=Voice.ALLOY.value)
|
| 611 |
-
format_dropdown = gr.Dropdown(choices=formats_list, label="Audio Format", value=AudioFormat.MP3.value)
|
| 612 |
-
instructions_input = gr.Textbox(label="Instructions (Optional)", placeholder="Additional instructions for generation...")
|
| 613 |
-
output_audio = gr.Audio(label="Generated Audio")
|
| 614 |
-
generate_btn = gr.Button("Generate")
|
| 615 |
-
generate_btn.click(
|
| 616 |
-
fn=generate_tts_gradio,
|
| 617 |
-
inputs=[text_input, voice_dropdown, format_dropdown, instructions_input],
|
| 618 |
-
outputs=output_audio
|
| 619 |
-
)
|
| 620 |
-
with gr.Tab("Batch Generation"):
|
| 621 |
-
batch_text_input = gr.Textbox(label="Input Text (Long Text)", placeholder="Enter long text to split and convert...")
|
| 622 |
-
batch_voice_dropdown = gr.Dropdown(choices=voices_list, label="Voice", value=Voice.ALLOY.value)
|
| 623 |
-
batch_format_dropdown = gr.Dropdown(choices=formats_list, label="Audio Format", value=AudioFormat.MP3.value)
|
| 624 |
-
batch_instructions_input = gr.Textbox(label="Instructions (Optional)", placeholder="Additional instructions for generation...")
|
| 625 |
-
batch_max_length = gr.Number(label="Max Chunk Length", value=4096)
|
| 626 |
-
batch_preserve_words = gr.Checkbox(label="Preserve Words in Splitting", value=True)
|
| 627 |
-
batch_output = gr.Gallery(label="Generated Audio Chunks (with Text Previews)")
|
| 628 |
-
batch_generate_btn = gr.Button("Generate Batch")
|
| 629 |
-
batch_generate_btn.click(
|
| 630 |
-
fn=generate_tts_batch_gradio,
|
| 631 |
-
inputs=[batch_text_input, batch_voice_dropdown, batch_format_dropdown, batch_instructions_input, batch_max_length, batch_preserve_words],
|
| 632 |
-
outputs=batch_output
|
| 633 |
-
)
|
| 634 |
-
|
| 635 |
-
# Mount Gradio to Flask at /gradio
|
| 636 |
-
gr.mount_gradio_app(app, demo, path="/gradio")
|
| 637 |
-
|
| 638 |
if __name__ == '__main__':
|
| 639 |
logger.info(f"Starting TTSFM web application on {HOST}:{PORT}")
|
| 640 |
logger.info("Using openai.fm free TTS service")
|
| 641 |
logger.info(f"Debug mode: {DEBUG}")
|
| 642 |
-
logger.info("Gradio interface available at /gradio")
|
| 643 |
|
| 644 |
try:
|
| 645 |
app.run(
|
|
|
|
| 29 |
from ttsfm.exceptions import APIException, NetworkException, ValidationException
|
| 30 |
from ttsfm.utils import validate_text_length, split_text_by_length
|
| 31 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 32 |
# Load environment variables
|
| 33 |
load_dotenv()
|
| 34 |
|
|
|
|
| 279 |
|
| 280 |
except TTSException as e:
|
| 281 |
logger.error(f"TTS error: {e}")
|
| 282 |
+
return jsonify({"error": str(e)}), 500
|
| 283 |
|
| 284 |
except Exception as e:
|
| 285 |
logger.error(f"Unexpected error: {e}")
|
|
|
|
| 332 |
)
|
| 333 |
|
| 334 |
# Convert to base64 for JSON response
|
| 335 |
+
import base64
|
| 336 |
audio_b64 = base64.b64encode(response.audio_data).decode('utf-8')
|
| 337 |
|
| 338 |
results.append({
|
|
|
|
| 554 |
logger.error(f"Internal server error: {error}")
|
| 555 |
return jsonify({"error": "Internal server error"}), 500
|
| 556 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 557 |
if __name__ == '__main__':
|
| 558 |
logger.info(f"Starting TTSFM web application on {HOST}:{PORT}")
|
| 559 |
logger.info("Using openai.fm free TTS service")
|
| 560 |
logger.info(f"Debug mode: {DEBUG}")
|
|
|
|
| 561 |
|
| 562 |
try:
|
| 563 |
app.run(
|