|
import gradio as gr |
|
import numpy as np |
|
import io |
|
import base64 |
|
import requests |
|
import re |
|
from scipy.io import wavfile |
|
from murf import Murf |
|
|
|
|
|
attempt_count = 0 |
|
|
|
|
|
client = Murf(api_key="ap2_94209101-077d-4962-9f4b-daeec8caeda2") |
|
|
|
def extract_voice_id(selection): |
|
""" |
|
Extracts the voice ID from the dropdown selection. |
|
Expects a string in the format "Label (voice_id)". |
|
""" |
|
match = re.search(r'\((.*?)\)', selection) |
|
if match: |
|
return match.group(1) |
|
return selection |
|
|
|
def generate_voice_murf(text, voice_selection): |
|
global attempt_count, client |
|
|
|
if attempt_count >= 5: |
|
raise gr.Error("Limit of 5 tries reached. Please update your API key. To fetch your new API key, visit https://murf.ai/api/dashboard.") |
|
attempt_count += 1 |
|
|
|
|
|
voice_id = extract_voice_id(voice_selection) |
|
|
|
try: |
|
|
|
text = text[:250] |
|
|
|
|
|
response = client.text_to_speech.generate( |
|
text=text, |
|
voice_id=voice_id, |
|
format="WAV" |
|
) |
|
|
|
|
|
if hasattr(response, "encoded_audio") and response.encoded_audio: |
|
audio_bytes = base64.b64decode(response.encoded_audio) |
|
elif hasattr(response, "audio_file") and response.audio_file: |
|
audio_url = response.audio_file |
|
r = requests.get(audio_url) |
|
if r.status_code != 200: |
|
raise Exception("Error downloading audio file.") |
|
audio_bytes = r.content |
|
else: |
|
raise Exception("No audio returned by the API.") |
|
|
|
|
|
audio_file = io.BytesIO(audio_bytes) |
|
sample_rate, audio_data = wavfile.read(audio_file) |
|
return (sample_rate, audio_data) |
|
|
|
except Exception as e: |
|
raise gr.Error(str(e)) |
|
|
|
def update_api_key(new_key): |
|
global client, attempt_count |
|
if new_key.strip() == "": |
|
raise gr.Error("Please provide a valid API key.") |
|
client = Murf(api_key=new_key) |
|
attempt_count = 0 |
|
return "API key updated successfully. You can now try again." |
|
|
|
|
|
voice_options = [ |
|
"Natalie (en-US-natalie)", |
|
"Matt (en-UK-matt)" |
|
] |
|
|
|
with gr.Blocks() as demo: |
|
gr.Markdown("# Murf TTS Demo") |
|
gr.Markdown("A demo using the Murf API to generate speech from text. Enter some text (max 250 characters) and choose a voice.") |
|
|
|
input_text = gr.Textbox( |
|
label="Input Text (250 characters max)", |
|
lines=2, |
|
value="Hello, welcome to the Murf TTS demo!", |
|
elem_id="input_text" |
|
) |
|
|
|
voice_dropdown = gr.Dropdown( |
|
label="Voice", |
|
choices=voice_options, |
|
value=voice_options[0], |
|
elem_id="voice_dropdown" |
|
) |
|
|
|
generate_button = gr.Button("Generate Voice", elem_id="generate_button") |
|
out_audio = gr.Audio(label="Generated Voice", type="numpy", elem_id="out_audio") |
|
|
|
generate_button.click( |
|
fn=generate_voice_murf, |
|
inputs=[input_text, voice_dropdown], |
|
outputs=out_audio, |
|
queue=True |
|
) |
|
|
|
|
|
gr.Markdown("### Update API Key (Only update after receiving a 'Limit of 5 tries reached' error)") |
|
gr.Markdown("To fetch your new API key, visit [Murf Dashboard](https://murf.ai/api/dashboard).") |
|
new_api_key = gr.Textbox( |
|
label="New API Key", |
|
placeholder="Enter new API key here...", |
|
elem_id="new_api_key" |
|
) |
|
update_button = gr.Button("Update API Key", elem_id="update_button") |
|
api_key_status = gr.Textbox(label="Status", interactive=False, elem_id="api_key_status") |
|
|
|
update_button.click( |
|
fn=update_api_key, |
|
inputs=new_api_key, |
|
outputs=api_key_status, |
|
queue=True |
|
) |
|
|
|
demo.launch() |