File size: 4,402 Bytes
2f46bdb
 
 
 
 
 
 
 
 
a3ed77f
90fbf41
689b4fe
2f46bdb
 
 
 
 
a3ed77f
2f46bdb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a3ed77f
2f46bdb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90fbf41
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8635810
90fbf41
2f46bdb
a3ed77f
2f46bdb
a3ed77f
2f46bdb
a3ed77f
 
2f46bdb
 
 
 
a3ed77f
90fbf41
 
a3ed77f
 
 
90fbf41
 
 
a3ed77f
90fbf41
 
2f46bdb
 
 
 
a3ed77f
2f46bdb
 
 
 
 
 
 
 
689b4fe
 
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
124
125
126
127
128
129
130
131
import os
import numpy as np
import gradio as gr
import assemblyai as aai
from translate import Translator
import uuid
from elevenlabs import VoiceSettings
from elevenlabs.client import ElevenLabs
from pathlib import Path
from scipy.io.wavfile import write, read
import yt_dlp

ELEVENLABS_API = os.environ.get("ELEVENLABS_API")
ASSEMBLYAI_API = os.environ.get("ASSEMBLYAI_API")

def voice_to_voice(audio_file):
    transcript = transcribe_audio(audio_file)
    if transcript.status == 'error':
        raise gr.Error(transcript.error)
    else:
        transcript = transcript.text

    list_translations = translate_text(transcript)
    generated_audio_paths = []

    for translation in list_translations:
        translated_audio_file_name = text_to_speech(translation)
        path = Path(translated_audio_file_name)
        generated_audio_paths.append(path)

    return tuple(generated_audio_paths + list_translations)

def transcribe_audio(audio_file):
    aai.settings.api_key = ASSEMBLYAI_API
    transcriber = aai.Transcriber()
    transcript = transcriber.transcribe(audio_file)
    return transcript

def translate_text(text):
    languages = ["ru", "tr", "sv", "de", "es", "ja", "id"]
    list_translations = []

    for lan in languages:
        translator = Translator(from_lang="en", to_lang=lan)
        translation = translator.translate(text)
        list_translations.append(translation)

    return list_translations

def text_to_speech(text):
    client = ElevenLabs(api_key=ELEVENLABS_API)
    response = client.text_to_speech.convert(
        voice_id="<your-voice-id>",
        optimize_streaming_latency="0",
        output_format="mp3_22050_32",
        text=text,
        model_id="eleven_multilingual_v2",
        voice_settings=VoiceSettings(
            stability=0.5,
            similarity_boost=0.8,
            style=0.5,
            use_speaker_boost=True,
        ),
    )

    save_file_path = f"{uuid.uuid4()}.mp3"
    with open(save_file_path, "wb") as f:
        for chunk in response:
            if chunk:
                f.write(chunk)

    return save_file_path

def download_audio(url):
    ydl_opts = {
        'format': 'bestaudio/best',
        'outtmpl': 'ytdl/%(title)s.%(ext)s',
        'postprocessors': [{
            'key': 'FFmpegExtractAudio',
            'preferredcodec': 'wav',
            'preferredquality': '192',
        }],
    }

    with yt_dlp.YoutubeDL(ydl_opts) as ydl:
        info_dict = ydl.extract_info(url, download=True)
        file_path = ydl.prepare_filename(info_dict).rsplit('.', 1)[0] + '.wav'
        sample_rate, audio_data = read(file_path)
        audio_array = np.asarray(audio_data, dtype=np.int16)

        return file_path

with gr.Blocks() as demo:
    gr.Markdown("## Audio Translator")
    gr.Markdown(
        """
        The API Key you need:
        [AssemblyAI API key](https://www.assemblyai.com/?utm_source=youtube&utm_medium=referral&utm_campaign=yt_mis_66)<br>
        [Elevenlabs API key](https://elevenlabs.io/)<br>
        Note: you need at least 30 minutes of a voice recording of yourself for the *Professional voice cloning. But there is also a simpler voice cloning option that only requires 30 seconds of voice recording. *Professional voice cloning is a paid feature.
        """
    )
    audio_input = gr.Audio(type="filepath", show_download_button=True)
    with gr.Accordion("Inputs by Link", open=False):
        with gr.Row():
            link = gr.Textbox(
                label="Link",
                placeholder="Paste the link here",
                interactive=True
            )
            download_button = gr.Button(
                "Download!",
                variant="primary"
            )
            download_button.click(download_audio, [link], [audio_input])
    submit = gr.Button("Submit", variant="primary")
    clear_button = gr.ClearButton(audio_input, "Clear")

    output_components = []
    languages = ["Turkish", "Swedish", "Russian", "German", "Spanish", "Japanese", "Indonesian"]
    
    for lang in languages:
        with gr.Group():
            output_components.append(gr.Audio(label=lang, interactive=False))
            output_components.append(gr.Markdown())

    submit.click(fn=voice_to_voice, inputs=audio_input, outputs=output_components, show_progress=True)

# Use a random port if the default one is unavailable
demo.launch(server_port=7860)