diff --git a/.gitignore b/.gitignore index 6f4c5ba..1b7f0fb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ cache/* characters/* extensions/silero_tts/outputs/* +extensions/elevenlabs_tts/outputs/* logs/* models/* softprompts/* diff --git a/extensions/elevenlabs_tts/outputs/outputs-will-be-saved-here.txt b/extensions/elevenlabs_tts/outputs/outputs-will-be-saved-here.txt new file mode 100644 index 0000000..e69de29 diff --git a/extensions/elevenlabs_tts/requirements.txt b/extensions/elevenlabs_tts/requirements.txt new file mode 100644 index 0000000..8ec07a8 --- /dev/null +++ b/extensions/elevenlabs_tts/requirements.txt @@ -0,0 +1,3 @@ +elevenlabslib +soundfile +sounddevice diff --git a/extensions/elevenlabs_tts/script.py b/extensions/elevenlabs_tts/script.py new file mode 100644 index 0000000..ae4fe01 --- /dev/null +++ b/extensions/elevenlabs_tts/script.py @@ -0,0 +1,118 @@ +import asyncio +import io +import json +import os +from pathlib import Path + +import gradio as gr +import requests +import torch +from elevenlabslib import * +from elevenlabslib.helpers import * + +params = { + 'activate': True, + 'api_key': '12345', + 'selected_voice': 'None', +} +initial_voice = ['None'] +wav_idx = 0 +user = ElevenLabsUser(params['api_key']) +user_info = None + + +"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 params['activate'] == False: + 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): + new_string = "" + in_star = False + for char in string: + if char == '*': + in_star = not in_star + elif not in_star: + new_string += char + return new_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 params['activate'] == False: + return string + elif user_info == 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('extensions/elevenlabs_tts/outputs/{}.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("extensions/elevenlabs_tts/outputs/{}.wav".format(wav_idx), audio_data) + + + string = f'' + 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) +