forked from elevenlabs/elevenlabs-examples
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add python example for dubbing a video (elevenlabs#25)
* fix: Handle by pre-commit * fix: Do ruff fix
- Loading branch information
1 parent
22dc216
commit ab9c050
Showing
4 changed files
with
207 additions
and
82 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import os | ||
from typing import Optional | ||
|
||
from dotenv import load_dotenv | ||
from dubbing_utils import download_dubbed_file, wait_for_dubbing_completion | ||
from elevenlabs.client import ElevenLabs | ||
|
||
# Load environment variables | ||
load_dotenv() | ||
|
||
# Retrieve the API key | ||
ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY") | ||
if not ELEVENLABS_API_KEY: | ||
raise ValueError( | ||
"ELEVENLABS_API_KEY environment variable not found. " | ||
"Please set the API key in your environment variables." | ||
) | ||
|
||
client = ElevenLabs(api_key=ELEVENLABS_API_KEY) | ||
|
||
|
||
def create_dub_from_file( | ||
input_file_path: str, | ||
file_format: str, | ||
source_language: str, | ||
target_language: str, | ||
) -> Optional[str]: | ||
""" | ||
Dubs an audio or video file from one language to another and saves the output. | ||
Args: | ||
input_file_path (str): The file path of the audio or video to dub. | ||
file_format (str): The file format of the input file. | ||
source_language (str): The language of the input file. | ||
target_language (str): The target language to dub into. | ||
Returns: | ||
Optional[str]: The file path of the dubbed file or None if operation failed. | ||
""" | ||
if not os.path.isfile(input_file_path): | ||
raise FileNotFoundError(f"The input file does not exist: {input_file_path}") | ||
|
||
with open(input_file_path, "rb") as audio_file: | ||
response = client.dubbing.dub_a_video_or_an_audio_file( | ||
file=(os.path.basename(input_file_path), audio_file, file_format), | ||
target_lang=target_language, | ||
mode="automatic", | ||
source_lang=source_language, | ||
num_speakers=1, | ||
watermark=False, # reduces the characters used if enabled, only works for videos not audio | ||
) | ||
|
||
dubbing_id = response.dubbing_id | ||
if wait_for_dubbing_completion(dubbing_id): | ||
output_file_path = download_dubbed_file(dubbing_id, target_language) | ||
return output_file_path | ||
else: | ||
return None | ||
|
||
|
||
if __name__ == "__main__": | ||
result = create_dub_from_file( | ||
"../example_speech.mp3", # Input file path | ||
"audio/mpeg", # File format | ||
"en", # Source language | ||
"es", # Target language | ||
) | ||
if result: | ||
print("Dubbing was successful! File saved at:", result) | ||
else: | ||
print("Dubbing failed or timed out.") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import os | ||
from typing import Optional | ||
|
||
from dotenv import load_dotenv | ||
from dubbing_utils import download_dubbed_file, wait_for_dubbing_completion | ||
from elevenlabs.client import ElevenLabs | ||
|
||
# Load environment variables | ||
load_dotenv() | ||
|
||
# Retrieve the API key | ||
ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY") | ||
if not ELEVENLABS_API_KEY: | ||
raise ValueError( | ||
"ELEVENLABS_API_KEY environment variable not found. " | ||
"Please set the API key in your environment variables." | ||
) | ||
|
||
client = ElevenLabs(api_key=ELEVENLABS_API_KEY) | ||
|
||
|
||
def create_dub_from_url( | ||
source_url: str, | ||
source_language: str, | ||
target_language: str, | ||
) -> Optional[str]: | ||
""" | ||
Downloads a video from a URL, and creates a dubbed version in the target language. | ||
Args: | ||
source_url (str): The URL of the source video to dub. Can be a YouTube link, TikTok, X (Twitter) or a Vimeo link. | ||
source_language (str): The language of the source video. | ||
target_language (str): The target language to dub into. | ||
Returns: | ||
Optional[str]: The file path of the dubbed file or None if operation failed. | ||
""" | ||
|
||
response = client.dubbing.dub_a_video_or_an_audio_file( | ||
source_url=source_url, | ||
target_lang=target_language, | ||
mode="automatic", | ||
source_lang=source_language, | ||
num_speakers=1, | ||
watermark=True, # reduces the characters used | ||
) | ||
|
||
dubbing_id = response.dubbing_id | ||
if wait_for_dubbing_completion(dubbing_id): | ||
output_file_path = download_dubbed_file(dubbing_id, target_language) | ||
return output_file_path | ||
else: | ||
return None | ||
|
||
|
||
if __name__ == "__main__": | ||
source_url = "https://www.youtube.com/watch?v=0EqSXDwTq6U" # Charlie bit my finger | ||
source_language = "en" | ||
target_language = "fr" | ||
result = create_dub_from_url(source_url, source_language, target_language) | ||
if result: | ||
print("Dubbing was successful! File saved at:", result) | ||
else: | ||
print("Dubbing failed or timed out.") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import os | ||
import time | ||
|
||
from dotenv import load_dotenv | ||
from elevenlabs.client import ElevenLabs | ||
|
||
# Load environment variables | ||
load_dotenv() | ||
|
||
# Retrieve the API key | ||
ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY") | ||
if not ELEVENLABS_API_KEY: | ||
raise ValueError( | ||
"ELEVENLABS_API_KEY environment variable not found. " | ||
"Please set the API key in your environment variables." | ||
) | ||
|
||
client = ElevenLabs(api_key=ELEVENLABS_API_KEY) | ||
|
||
|
||
def download_dubbed_file(dubbing_id: str, language_code: str) -> str: | ||
""" | ||
Downloads the dubbed file for a given dubbing ID and language code. | ||
Args: | ||
dubbing_id: The ID of the dubbing project. | ||
language_code: The language code for the dubbing. | ||
Returns: | ||
The file path to the downloaded dubbed file. | ||
""" | ||
dir_path = f"data/{dubbing_id}" | ||
os.makedirs(dir_path, exist_ok=True) | ||
|
||
file_path = f"{dir_path}/{language_code}.mp4" | ||
with open(file_path, "wb") as file: | ||
for chunk in client.dubbing.get_dubbed_file(dubbing_id, language_code): | ||
file.write(chunk) | ||
|
||
return file_path | ||
|
||
|
||
def wait_for_dubbing_completion(dubbing_id: str) -> bool: | ||
""" | ||
Waits for the dubbing process to complete by periodically checking the status. | ||
Args: | ||
dubbing_id (str): The dubbing project id. | ||
Returns: | ||
bool: True if the dubbing is successful, False otherwise. | ||
""" | ||
MAX_ATTEMPTS = 120 | ||
CHECK_INTERVAL = 10 # In seconds | ||
|
||
for _ in range(MAX_ATTEMPTS): | ||
metadata = client.dubbing.get_dubbing_project_metadata(dubbing_id) | ||
if metadata.status == "dubbed": | ||
return True | ||
elif metadata.status == "dubbing": | ||
print( | ||
"Dubbing in progress... Will check status again in", | ||
CHECK_INTERVAL, | ||
"seconds.", | ||
) | ||
time.sleep(CHECK_INTERVAL) | ||
else: | ||
print("Dubbing failed:", metadata.error_message) | ||
return False | ||
|
||
print("Dubbing timed out") | ||
return False |