File size: 4,233 Bytes
05b45a5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import os

import gradio as gr

from . import api
from .components import create_input_column, create_model_column, create_output_column
from .handlers import setup_event_handlers


def create_interface():
    """Create the main Gradio interface."""
    # Skip initial status check - let the timer handle it
    is_available, available_voices = False, []

    # Check if local saving is disabled
    disable_local_saving = os.getenv("DISABLE_LOCAL_SAVING", "false").lower() == "true"

    with gr.Blocks(title="Kokoro TTS Demo", theme=gr.themes.Monochrome()) as demo:
        gr.HTML(
            value='<div style="display: flex; gap: 0;">'
            '<a href="https://huggingface.co/hexgrad/Kokoro-82M" target="_blank" style="color: #2196F3; text-decoration: none; margin: 2px; border: 1px solid #2196F3; padding: 4px 8px; height: 24px; box-sizing: border-box; display: inline-flex; align-items: center;">Kokoro-82M HF Repo</a>'
            '<a href="https://github.com/remsky/Kokoro-FastAPI" target="_blank" style="color: #2196F3; text-decoration: none; margin: 2px; border: 1px solid #2196F3; padding: 4px 8px; height: 24px; box-sizing: border-box; display: inline-flex; align-items: center;">Kokoro-FastAPI Repo</a>'
            "</div>",
            show_label=False,
        )

        # Main interface
        with gr.Row():
            # Create columns
            input_col, input_components = create_input_column(disable_local_saving)
            model_col, model_components = create_model_column(
                available_voices
            )  # Pass initial voices
            output_col, output_components = create_output_column(disable_local_saving)

            # Collect all components
            components = {
                "input": input_components,
                "model": model_components,
                "output": output_components,
            }

            # Set up event handlers
            setup_event_handlers(components, disable_local_saving)

        # Add periodic status check with Timer
        def update_status():
            try:
                is_available, voices = api.check_api_status()
                status = "Available" if is_available else "Waiting for Service..."

                if is_available and voices:
                    # Service is available, update UI and stop timer
                    current_voice = components["model"]["voice"].value
                    default_voice = (
                        current_voice if current_voice in voices else voices[0]
                    )
                    # Return values in same order as outputs list
                    return [
                        gr.update(
                            value=f"🔄 TTS Service: {status}",
                            interactive=True,
                            variant="secondary",
                        ),
                        gr.update(choices=voices, value=default_voice),
                        gr.update(active=False),  # Stop timer
                    ]

                # Service not available yet, keep checking
                return [
                    gr.update(
                        value=f"⌛ TTS Service: {status}",
                        interactive=True,
                        variant="secondary",
                    ),
                    gr.update(choices=[], value=None),
                    gr.update(active=True),
                ]
            except Exception as e:
                print(f"Error in status update: {str(e)}")
                # On error, keep the timer running but show error state
                return [
                    gr.update(
                        value="❌ TTS Service: Connection Error",
                        interactive=True,
                        variant="secondary",
                    ),
                    gr.update(choices=[], value=None),
                    gr.update(active=True),
                ]

        timer = gr.Timer(value=5)  # Check every 5 seconds
        timer.tick(
            fn=update_status,
            outputs=[
                components["model"]["status_btn"],
                components["model"]["voice"],
                timer,
            ],
        )

    return demo