ThioJoe / Auto-Synced-Translated-Dubs

Automatically translates the text of a video based on a subtitle file, and then uses AI voice services to create a new dubbed & translated audio track where the speech is synced using the subtitle's timings.
GNU General Public License v3.0
1.6k stars 158 forks source link

ElevenLabs Error 400 #84

Closed RafaelGodoyEbert closed 9 months ago

RafaelGodoyEbert commented 10 months ago

image When I use ElevenLabs together with the API, I get this error.

ThioJoe commented 10 months ago

Hm I’ll have to investigate. But I think it might be because elevenlabs returned an error. Notice how up higher it says “Error 400”. So it didnt return a file which would explain why the script couldn’t find one. I’ll have to add more detailed error handling so it’s more obvious what the problem is exactly.

Also it looks like it might be an API key issue: https://help.elevenlabs.io/hc/en-us/articles/19572237925521-API-Error-Code-400-or-401-API-Key-

Did you set an API key with the elevenlabs_api_key setting in the cloud_service_settings.ini file?

ThioJoe commented 10 months ago

With the latest release it should provide a proper error message to explain what went wrong.

RafaelGodoyEbert commented 10 months ago

Yes, I placed the API in the correct location.

Below the error appeared

image

But in the end I created my own code to work with my API

So for me it's ok, I'm already using elevenlabs with my additional code, I just changed some things to recognize it.

I'm just contacting you to alert you to the error.

If you correct or find the solution or error I'm making, I'll use your code again.

 

I edited Scripts/TTS.py and added

script_path = os.path.join(current_directory, "ElevenlabsAPI.py")

def synthesize_text_elevenlabsapi(text, languageCode, TTS_FilePath, subtitle_num):
    # Chamada ao script srt2edge-tts.py usando subprocess
    subprocess.run(["python", script_path, text, languageCode, TTS_FilePath, subtitle_num])

and

elif cloudConfig['tts_service'] == "elevenlabsapi":
                synthesize_text_elevenlabsapi(value['translated_text'], langDict['languageCode'], 'workingFolder', str(key))

so I could use the file below in isolation from the others.

import asyncio
from elevenlabs import generate, set_api_key
import os
import sys

async def generate_tts(text, output_file, voice):
    audio_data = generate(
        text=text,
        voice=voice,
        model='eleven_multilingual_v2'
    )
    with open(output_file, "wb") as audio_file:
        audio_file.write(audio_data)

async def amain(text, languageCode, output_folder, subtitle_num) -> None:
    try:
        set_api_key("API_KEY")
        # O código relacionado ao mapeamento de voz não é necessário com a API Eleven Labs,
        # pois a API já lida com a seleção de voz.
        voice = "Charlie"  # Substitua pela voz desejada
    except Exception as e:
        print(f"Exceção: {e}")

    if voice:
        if not os.path.exists(output_folder):
            os.makedirs(output_folder)

        tts_output_file = os.path.join(output_folder, f"{subtitle_num}.mp3")

        await generate_tts(text, tts_output_file, voice)

    else:
        print(f"Idioma {languageCode} não suportado.")
        print(f"Lang Code: '{languageCode}'")
        print(f"Voice: {voice}")

def main():
    if len(sys.argv) != 5:
        print("Uso: python srt2edge-tts.py <texto> <lang_code> <output_folder> <subtitle_num>")
        sys.exit(1)

    text = sys.argv[1]
    lang_code = sys.argv[2]
    output_folder = sys.argv[3]
    subtitle_num = sys.argv[4]

    # Define output_folder para a pasta "workingFolder" um nível acima do diretório atual
    output_folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'workingFolder'))

    asyncio.run(amain(text, lang_code, output_folder, subtitle_num))

if __name__ == "__main__":
    main()

ps: ignore possible edge-tts leftovers

ThioJoe commented 10 months ago

Did you read the error message all the way through? It mentions en-US-JasonNeural, which would be the default voice currently selected in the batch.ini file, which is an Azure voice. You have to set an ElevenLabs voice. You can find the IDs for voices like this: https://help.elevenlabs.io/hc/en-us/articles/14599760033937-How-do-I-find-my-voices-ID-of-my-voices-via-the-website-and-through-the-API-

I did forget to take out a test line of code in one of the functions that probably made the error messaging overly complex.

In any case I'll add some handling for when it returns the invalid_uid error in the future. Unfortunately ElevenLabs doesn't seem to have a list of all the possible errors so I can only really add them as they come up.

RafaelGodoyEbert commented 10 months ago

Yes, I read until the end and saw that it was en-US-JasonNeural. At first, when you posted 17.0 I just tried to change it to some name that is there, like 'Adam'.

Now it's clear that it has to be the ID codes, which I can find more specifically at this link https://api.elevenlabs.io/v1/voices

Thanks for the feedback.

image

ThioJoe commented 10 months ago

Yea I've just added a new release that should provide more details about at least two invalid voice errors