Update app.py
Browse files
app.py
CHANGED
@@ -452,14 +452,18 @@ def create_download_link(audio_path):
|
|
452 |
return None
|
453 |
|
454 |
filename = Path(audio_path).name
|
455 |
-
|
456 |
-
|
|
|
457 |
|
458 |
return f"""
|
459 |
<a href="{file_url}"
|
460 |
download="{filename}"
|
461 |
target="_blank"
|
462 |
rel="noopener noreferrer"
|
|
|
|
|
|
|
463 |
onclick="event.preventDefault(); fetch(this.href).then(resp => resp.blob()).then(blob => {{
|
464 |
const url = window.URL.createObjectURL(blob);
|
465 |
const a = document.createElement('a');
|
@@ -471,7 +475,7 @@ def create_download_link(audio_path):
|
|
471 |
window.URL.revokeObjectURL(url);
|
472 |
document.body.removeChild(a);
|
473 |
}});">
|
474 |
-
|
475 |
</a>
|
476 |
"""
|
477 |
|
@@ -492,7 +496,7 @@ async def text_to_speech_edge(text, language_code, speaker, tashkeel_checkbox=Fa
|
|
492 |
# Define the character limit
|
493 |
char_limit = 100000000
|
494 |
if len(text) > char_limit:
|
495 |
-
return f"Error: Use
|
496 |
|
497 |
# Get the voice for the selected language and speaker
|
498 |
voice = language_dict[language_code][speaker]
|
@@ -522,94 +526,135 @@ def get_speakers(language):
|
|
522 |
default_language = None
|
523 |
default_speaker = None
|
524 |
with gr.Blocks(
|
525 |
-
title="
|
526 |
css="""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
527 |
@media (max-width: 768px) {
|
528 |
.container {
|
529 |
-
margin: 5px !important;
|
530 |
padding: 10px !important;
|
531 |
}
|
532 |
.header h1 {
|
533 |
font-size: 1.5em !important;
|
534 |
}
|
535 |
-
.header p {
|
536 |
-
font-size: 1em !important;
|
537 |
-
}
|
538 |
-
.input-section, .output-section {
|
539 |
-
padding: 10px !important;
|
540 |
-
}
|
541 |
-
.mobile-full {
|
542 |
-
width: 100% !important;
|
543 |
-
}
|
544 |
-
.mobile-stack {
|
545 |
-
flex-direction: column !important;
|
546 |
-
}
|
547 |
-
.mobile-stack > * {
|
548 |
-
width: 100% !important;
|
549 |
-
margin-bottom: 10px !important;
|
550 |
-
}
|
551 |
}
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
padding: 20px;
|
556 |
-
margin: 10px;
|
557 |
-
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
558 |
-
max-width: 1200px;
|
559 |
-
margin-left: auto;
|
560 |
-
margin-right: auto;
|
561 |
}
|
|
|
562 |
.container {
|
563 |
-
background-color:
|
564 |
-
|
|
|
565 |
padding: 20px;
|
566 |
-
margin: 10px;
|
567 |
-
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
568 |
}
|
|
|
569 |
.header {
|
570 |
text-align: center;
|
571 |
-
margin-bottom:
|
572 |
-
background: linear-gradient(
|
573 |
-
padding:
|
574 |
border-radius: 15px;
|
575 |
color: white;
|
|
|
576 |
}
|
577 |
-
|
578 |
-
|
579 |
-
|
|
|
580 |
border-radius: 15px;
|
581 |
-
margin-bottom:
|
|
|
|
|
|
|
582 |
}
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
587 |
}
|
|
|
588 |
.generate-btn {
|
589 |
-
background: linear-gradient(
|
590 |
-
|
591 |
-
|
|
|
|
|
|
|
|
|
592 |
}
|
|
|
593 |
.generate-btn:hover {
|
594 |
transform: translateY(-2px);
|
595 |
-
box-shadow: 0 5px 15px rgba(
|
596 |
}
|
|
|
597 |
.download-btn {
|
598 |
-
margin-top:
|
599 |
text-align: center;
|
600 |
}
|
|
|
601 |
.download-btn a {
|
602 |
-
|
|
|
|
|
|
|
603 |
color: white;
|
604 |
-
padding:
|
605 |
-
border-radius:
|
606 |
text-decoration: none;
|
607 |
-
|
|
|
608 |
transition: all 0.3s ease;
|
|
|
|
|
|
|
609 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
610 |
.download-btn a:hover {
|
611 |
transform: translateY(-2px);
|
612 |
-
box-shadow: 0 5px 15px rgba(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
613 |
}
|
614 |
"""
|
615 |
) as demo:
|
@@ -617,8 +662,7 @@ with gr.Blocks(
|
|
617 |
gr.HTML(
|
618 |
"""
|
619 |
<div class="header">
|
620 |
-
<
|
621 |
-
<p style="font-size: 1.2em;">Convert text to natural-sounding speech in multiple languages</p>
|
622 |
</div>
|
623 |
"""
|
624 |
)
|
@@ -662,7 +706,7 @@ with gr.Blocks(
|
|
662 |
)
|
663 |
|
664 |
with gr.Column(elem_classes="output-section mobile-full"):
|
665 |
-
output_text = gr.Textbox(label="
|
666 |
output_audio = gr.Audio(
|
667 |
type="filepath",
|
668 |
label="Generated Audio"
|
|
|
452 |
return None
|
453 |
|
454 |
filename = Path(audio_path).name
|
455 |
+
# Update URL format to match Gradio's file serving pattern
|
456 |
+
base_url = "hivecorp-w-t-p-01.hf.space"
|
457 |
+
file_url = f"https://{base_url}/file={audio_path}"
|
458 |
|
459 |
return f"""
|
460 |
<a href="{file_url}"
|
461 |
download="{filename}"
|
462 |
target="_blank"
|
463 |
rel="noopener noreferrer"
|
464 |
+
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;"
|
465 |
+
onmouseover="this.style.transform='translateY(-2px)'; this.style.boxShadow='0 5px 15px rgba(71, 118, 230, 0.3)';"
|
466 |
+
onmouseout="this.style.transform='translateY(0)'; this.style.boxShadow='none';"
|
467 |
onclick="event.preventDefault(); fetch(this.href).then(resp => resp.blob()).then(blob => {{
|
468 |
const url = window.URL.createObjectURL(blob);
|
469 |
const a = document.createElement('a');
|
|
|
475 |
window.URL.revokeObjectURL(url);
|
476 |
document.body.removeChild(a);
|
477 |
}});">
|
478 |
+
Download Audio File
|
479 |
</a>
|
480 |
"""
|
481 |
|
|
|
496 |
# Define the character limit
|
497 |
char_limit = 100000000
|
498 |
if len(text) > char_limit:
|
499 |
+
return f"Error: Use 15,000 Words at a time.", None, None
|
500 |
|
501 |
# Get the voice for the selected language and speaker
|
502 |
voice = language_dict[language_code][speaker]
|
|
|
526 |
default_language = None
|
527 |
default_speaker = None
|
528 |
with gr.Blocks(
|
529 |
+
title="WritooAI Free Plan",
|
530 |
css="""
|
531 |
+
:root {
|
532 |
+
--primary-color: #4776E6;
|
533 |
+
--secondary-color: #8E54E9;
|
534 |
+
--background-light: #ffffff;
|
535 |
+
--card-light: #f8f9fa;
|
536 |
+
--text-dark: #2d3436;
|
537 |
+
--text-gray: #636e72;
|
538 |
+
--border-color: #e0e0e0;
|
539 |
+
}
|
540 |
+
|
541 |
@media (max-width: 768px) {
|
542 |
.container {
|
|
|
543 |
padding: 10px !important;
|
544 |
}
|
545 |
.header h1 {
|
546 |
font-size: 1.5em !important;
|
547 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
548 |
}
|
549 |
+
|
550 |
+
body {
|
551 |
+
background-color: var(--background-light);
|
|
|
|
|
|
|
|
|
|
|
|
|
552 |
}
|
553 |
+
|
554 |
.container {
|
555 |
+
background-color: var(--background-light);
|
556 |
+
max-width: 1200px;
|
557 |
+
margin: 0 auto;
|
558 |
padding: 20px;
|
|
|
|
|
559 |
}
|
560 |
+
|
561 |
.header {
|
562 |
text-align: center;
|
563 |
+
margin-bottom: 30px;
|
564 |
+
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
|
565 |
+
padding: 25px;
|
566 |
border-radius: 15px;
|
567 |
color: white;
|
568 |
+
box-shadow: 0 4px 15px rgba(71, 118, 230, 0.2);
|
569 |
}
|
570 |
+
|
571 |
+
.input-section, .output-section {
|
572 |
+
background-color: var(--card-light);
|
573 |
+
padding: 25px;
|
574 |
border-radius: 15px;
|
575 |
+
margin-bottom: 20px;
|
576 |
+
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
|
577 |
+
border: 1px solid var(--border-color);
|
578 |
+
width: 100%;
|
579 |
}
|
580 |
+
|
581 |
+
.input-box textarea {
|
582 |
+
min-height: 120px !important;
|
583 |
+
font-size: 16px !important;
|
584 |
+
border: 1px solid var(--border-color) !important;
|
585 |
+
border-radius: 10px !important;
|
586 |
+
padding: 15px !important;
|
587 |
+
width: 100% !important;
|
588 |
+
}
|
589 |
+
|
590 |
+
.dropdown {
|
591 |
+
width: 100% !important;
|
592 |
+
}
|
593 |
+
|
594 |
+
select, input[type="text"] {
|
595 |
+
width: 100% !important;
|
596 |
+
padding: 12px !important;
|
597 |
+
border-radius: 8px !important;
|
598 |
+
border: 1px solid var(--border-color) !important;
|
599 |
}
|
600 |
+
|
601 |
.generate-btn {
|
602 |
+
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)) !important;
|
603 |
+
padding: 15px 30px !important;
|
604 |
+
border-radius: 10px !important;
|
605 |
+
font-weight: 600 !important;
|
606 |
+
letter-spacing: 0.5px !important;
|
607 |
+
width: 100% !important;
|
608 |
+
margin-top: 15px !important;
|
609 |
}
|
610 |
+
|
611 |
.generate-btn:hover {
|
612 |
transform: translateY(-2px);
|
613 |
+
box-shadow: 0 5px 15px rgba(71, 118, 230, 0.3) !important;
|
614 |
}
|
615 |
+
|
616 |
.download-btn {
|
617 |
+
margin-top: 20px;
|
618 |
text-align: center;
|
619 |
}
|
620 |
+
|
621 |
.download-btn a {
|
622 |
+
display: inline-flex;
|
623 |
+
align-items: center;
|
624 |
+
justify-content: center;
|
625 |
+
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
|
626 |
color: white;
|
627 |
+
padding: 12px 25px;
|
628 |
+
border-radius: 10px;
|
629 |
text-decoration: none;
|
630 |
+
font-weight: 600;
|
631 |
+
letter-spacing: 0.5px;
|
632 |
transition: all 0.3s ease;
|
633 |
+
gap: 8px;
|
634 |
+
width: 100%;
|
635 |
+
max-width: 300px;
|
636 |
}
|
637 |
+
|
638 |
+
.download-btn a:before {
|
639 |
+
content: "⬇️";
|
640 |
+
font-size: 1.2em;
|
641 |
+
}
|
642 |
+
|
643 |
.download-btn a:hover {
|
644 |
transform: translateY(-2px);
|
645 |
+
box-shadow: 0 5px 15px rgba(71, 118, 230, 0.3);
|
646 |
+
}
|
647 |
+
|
648 |
+
/* Audio player styling */
|
649 |
+
audio {
|
650 |
+
width: 100% !important;
|
651 |
+
margin: 15px 0 !important;
|
652 |
+
border-radius: 10px !important;
|
653 |
+
}
|
654 |
+
|
655 |
+
/* Hide output text */
|
656 |
+
#output-text {
|
657 |
+
display: none !important;
|
658 |
}
|
659 |
"""
|
660 |
) as demo:
|
|
|
662 |
gr.HTML(
|
663 |
"""
|
664 |
<div class="header">
|
665 |
+
<h2>WritooAI Pro Plan - 15+ more Human-like Voice </h2>
|
|
|
666 |
</div>
|
667 |
"""
|
668 |
)
|
|
|
706 |
)
|
707 |
|
708 |
with gr.Column(elem_classes="output-section mobile-full"):
|
709 |
+
output_text = gr.Textbox(label="", visible=False) # Hidden
|
710 |
output_audio = gr.Audio(
|
711 |
type="filepath",
|
712 |
label="Generated Audio"
|