File size: 3,624 Bytes
292c2df
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import re
from pathlib import Path

import gradio as gr
from elevenlabslib import ElevenLabsUser
from elevenlabslib.helpers import save_bytes_to_path

import modules.shared as shared

params = {
    'activate': True,
    'api_key': '12345',
    'selected_voice': 'None',
}

initial_voice = ['None']
wav_idx = 0
user = ElevenLabsUser(params['api_key'])
user_info = None

if not shared.args.no_stream:
    print("Please add --no-stream. This extension is not meant to be used with streaming.")
    raise ValueError

# Check if the API is valid and refresh the UI accordingly.


def check_valid_api():

    global user, user_info, params

    user = ElevenLabsUser(params['api_key'])
    user_info = user._get_subscription_data()
    print('checking api')
    if not params['activate']:
        return gr.update(value='Disconnected')
    elif user_info is None:
        print('Incorrect API Key')
        return gr.update(value='Disconnected')
    else:
        print('Got an API Key!')
        return gr.update(value='Connected')

# Once the API is verified, get the available voices and update the dropdown list


def refresh_voices():

    global user, user_info

    your_voices = [None]
    if user_info is not None:
        for voice in user.get_available_voices():
            your_voices.append(voice.initialName)
        return gr.Dropdown.update(choices=your_voices)
    else:
        return


def remove_surrounded_chars(string):
    # this expression matches to 'as few symbols as possible (0 upwards) between any asterisks' OR
    # 'as few symbols as possible (0 upwards) between an asterisk and the end of the string'
    return re.sub('\*[^\*]*?(\*|$)', '', string)


def input_modifier(string):
    """
    This function is applied to your text inputs before
    they are fed into the model.
    """

    return string


def output_modifier(string):
    """
    This function is applied to the model outputs.
    """

    global params, wav_idx, user, user_info

    if not params['activate']:
        return string
    elif user_info is None:
        return string

    string = remove_surrounded_chars(string)
    string = string.replace('"', '')
    string = string.replace('“', '')
    string = string.replace('\n', ' ')
    string = string.strip()

    if string == '':
        string = 'empty reply, try regenerating'

    output_file = Path(f'extensions/elevenlabs_tts/outputs/{wav_idx:06d}.wav'.format(wav_idx))
    voice = user.get_voices_by_name(params['selected_voice'])[0]
    audio_data = voice.generate_audio_bytes(string)
    save_bytes_to_path(Path(f'extensions/elevenlabs_tts/outputs/{wav_idx:06d}.wav'), audio_data)

    string = f'<audio src="file/{output_file.as_posix()}" controls></audio>'
    wav_idx += 1
    return string


def ui():

    # Gradio elements
    with gr.Row():
        activate = gr.Checkbox(value=params['activate'], label='Activate TTS')
        connection_status = gr.Textbox(value='Disconnected', label='Connection Status')
    voice = gr.Dropdown(value=params['selected_voice'], choices=initial_voice, label='TTS Voice')
    with gr.Row():
        api_key = gr.Textbox(placeholder="Enter your API key.", label='API Key')
        connect = gr.Button(value='Connect')

    # Event functions to update the parameters in the backend
    activate.change(lambda x: params.update({'activate': x}), activate, None)
    voice.change(lambda x: params.update({'selected_voice': x}), voice, None)
    api_key.change(lambda x: params.update({'api_key': x}), api_key, None)
    connect.click(check_valid_api, [], connection_status)
    connect.click(refresh_voices, [], voice)