import os import torch import argparse import gradio as gr import requests from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from email.mime.application import MIMEApplication from openvoice import se_extractor from openvoice.api import BaseSpeakerTTS, ToneColorConverter from dotenv import load_dotenv from openai import OpenAI from elevenlabs.client import ElevenLabs from elevenlabs import play, save import time # Load environment variables load_dotenv() # Argument parsing parser = argparse.ArgumentParser() parser.add_argument("--share", action='store_true', default=False, help="make link public") args = parser.parse_args() # Initialize ElevenLabs client client = ElevenLabs(api_key=os.environ.get("ELEVENLABS_API_KEY")) device = 'cuda' if torch.cuda.is_available() else 'cpu' output_dir = 'outputs' os.makedirs(output_dir, exist_ok=True) api_key = os.environ.get("ELEVENLABS_API_KEY") supported_languages = ['zh', 'en'] # Mailgun configuration MAILGUN_DOMAIN = "sandbox3785301d5591459ca8b5b5cd121edfb8.mailgun.org" MAILGUN_API_KEY = os.environ.get("MAILGUN_API_KEY") # Function to send email with downloadable file using Mailgun def send_email_with_file(recipient_email, file_path, subject, body): try: # Prepare the MIME message message = MIMEMultipart() message['From'] = f"Your App " message['To'] = recipient_email message['Subject'] = subject # Attach the text body message.attach(MIMEText(body)) # Attach the file with open(file_path, "rb") as file: part = MIMEApplication(file.read(), Name=os.path.basename(file_path)) part['Content-Disposition'] = f'attachment; filename="{os.path.basename(file_path)}"' message.attach(part) # Send the email using Mailgun API response = requests.post( f"https://api.mailgun.net/v3/{MAILGUN_DOMAIN}/messages", auth=("api", MAILGUN_API_KEY), files=[("attachment", (os.path.basename(file_path), open(file_path, "rb").read()))], data={ "from": f"Your App ", "to": recipient_email, "subject": subject, "text": body, } ) if response.status_code == 200: print("Email sent successfully") return True else: print(f"Failed to send email. Status code: {response.status_code}") print(f"Response: {response.text}") return False except Exception as e: print(f"An error occurred while sending email: {e}") return False # Predict function def predict(prompt, style, audio_file_pth, voice_name, customer_email): text_hint = 'Your file will only be saved for 24 hours.\n' if len(prompt) < 2: text_hint += "[ERROR] Please provide a longer prompt text.\n" return text_hint, None, None if len(prompt) > 200: text_hint += "[ERROR] Text length limited to 200 characters. Please try shorter text.\n" return text_hint, None, None print(audio_file_pth) voice = client.clone( name=voice_name, description="A trial voice model for testing", files=[audio_file_pth], ) # Generate audio from text audio = client.generate(text=prompt, voice=voice) save_path = f'{output_dir}/output.wav' save(audio, save_path) # Send email with downloadable file subject = "Your Voice Clone File" body = "Thank you for using our Voice Clone service. Your file is attached." if send_email_with_file(customer_email, save_path, subject, body): text_hint += "Email sent successfully with the voice file.\n" else: text_hint += "Failed to send email with the voice file. Please try again later.\n" return text_hint, save_path, audio_file_pth # Gradio interface setup with gr.Blocks(gr.themes.Glass()) as demo: with gr.Row(): with gr.Column(): input_text_gr = gr.Textbox( label="Create This", info="One or two sentences at a time is better. Up to 200 text characters.", value="He hoped there would be stew for dinner, turnips and carrots and bruised potatoes and fat mutton pieces to be ladled out in thick, peppered, flour-fattened sauce.", ) style_gr = gr.Dropdown( label="Style", choices=['default', 'whispering', 'cheerful', 'terrified', 'angry', 'sad', 'friendly'], info="Please upload a reference audio file that is at least 1 minute long. For best results, ensure the audio is clear. You can use Adobe Podcast Enhance(https://podcast.adobe.com/enhance) to improve the audio quality before uploading.", max_choices=1, value="default", ) ref_gr = gr.Audio( label="Original Audio", type="filepath", sources=["upload"], # Allow only upload ) voice_name_gr = gr.Textbox( label="Your name and Product you bought", value="Sam" ) customer_email_gr = gr.Textbox( label="Your Email", info="We'll send you a downloadable file to this email address." ) tts_button = gr.Button("Start", elem_id="send-btn", visible=True) with gr.Column(): out_text_gr = gr.Text(label="Info") audio_gr = gr.Audio(label="Replicated Sound", autoplay=True) ref_audio_gr = gr.Audio(label="Original Audio Used ") tts_button.click(predict, [input_text_gr, style_gr, ref_gr, voice_name_gr, customer_email_gr], outputs=[out_text_gr, audio_gr, ref_audio_gr]) demo.queue() demo.launch(debug=True, show_api=False, share=args.share) # Hide Gradio footer and record button css = """ footer {visibility: hidden} audio .btn-container {display: none} """ demo.add_css(css)