Guide: Simple Python App for Generating Videos from HeyGen Templates
In this guide, we'll explore how to generate a dynamic video presentation with Python using HeyGen's V2 Template API. We'll focus on a template called Fruit Presentation, comprising 5 scenes. By inputting specific fruit details, we'll customize and generate engaging presentation videos.
Here's an overview of the Fruit Presentation timeline and its associated variables and scripts:
- Scene 1:
FRUIT_NAME
,Subtitle
,scene_1_image_1
Welcome to the
FRUIT_NAME
presentation. - Scene 2:
scene_2_bg_image
scene_2_script
- Scene 3:
scene_3_image_1
,scene_3_image_2
,scene_3_image_3
scene_3_script
- Scene 4:
scene_4_bg_image
,scene_4_image_1
,scene_4_image_2
,scene_4_image_3
scene_4_script
- Scene 5:
scene_5_bg_image
,scene_5_image_1
,scene_5_image_2
,scene_5_image_3
scene_5_script
Now, let's proceed to the Python code.
Step 1. Obtain the Template ID
See detailed API reference
Using the following API request you will get a list of your templates that you have created in the HeyGen interface, obtain your template_id
from here.
curl --location 'https://api.heygen.com/v2/templates' \
--header 'accept: application/json' \
--header 'x-api-key: <your-api-key>'
{
"error": null,
"data": {
"templates": [
{
"template_id": "<template_id>",
"name": "Fruits Presentation",
"thumbnail_image_url": "https://resource.heygencdn.com/image/313f99089bf3410bb7f3ffcadf9b8864/original"
},
...
]
}
}
template_list_url = "https://api.heygen.com/v2/templates"
headers = {"accept": "application/json", "x-api-key": api_key}
response = requests.get(template_list_url, headers=headers)
template_id = response.json()["data"]["templates"][0]["template_id"] # Get the first template_id
Step 2. Obtain Video Elements
See detailed API reference
To retrieve video elements for a specific template, use this API request to get the variable you want to change.
curl --location 'https://api.heygen.com/v2/template/<template_id>' \
--header 'accept: application/json' \
--header 'x-api-key: <your-api-key>'
{
"error": null,
"data": {
"variables": {
"Subtitle": {
"name": "Subtitle",
"type": "text",
"properties": {
"content": ""
}
},
"FRUIT_NAME": {
"name": "FRUIT_NAME",
"type": "text",
"properties": {
"content": ""
}
},
"scene_2_script": {
"name": "scene_2_script",
"type": "text",
"properties": {
"content": ""
}
},
"scene_3_script": {
"name": "scene_3_script",
"type": "text",
"properties": {
"content": ""
}
},
"scene_4_script": {
"name": "scene_4_script",
"type": "text",
"properties": {
"content": ""
}
},
"scene_5_script": {
"name": "scene_5_script",
"type": "text",
"properties": {
"content": ""
}
},
"scene_1_image_1": {
"name": "scene_1_image_1",
"type": "image",
"properties": {
"url": "blob:https://app.heygen.com/c0d751f0-ef87-4ee5-b5f4-6ad080b21de2",
"asset_id": null,
"fit": "none"
}
},
"scene_3_image_1": {
"name": "scene_3_image_1",
"type": "image",
"properties": {
"url": "blob:https://app.heygen.com/e2265816-4531-49eb-8e75-4ba8a7cf6305",
"asset_id": null,
"fit": "none"
}
},
"scene_3_image_2": {
"name": "scene_3_image_2",
"type": "image",
"properties": {
"url": "blob:https://app.heygen.com/a7e01dbd-ea84-41cc-b1b7-cb843bf6f9c8",
"asset_id": null,
"fit": "none"
}
},
"scene_3_image_3": {
"name": "scene_3_image_3",
"type": "image",
"properties": {
"url": "blob:https://app.heygen.com/29cd0a23-1885-4727-b695-ef17cfa0813e",
"asset_id": null,
"fit": "none"
}
},
"scene_4_image_1": {
"name": "scene_4_image_1",
"type": "image",
"properties": {
"url": "blob:https://app.heygen.com/e2265816-4531-49eb-8e75-4ba8a7cf6305",
"asset_id": null,
"fit": "none"
}
},
"scene_4_image_2": {
"name": "scene_4_image_2",
"type": "image",
"properties": {
"url": "blob:https://app.heygen.com/a7e01dbd-ea84-41cc-b1b7-cb843bf6f9c8",
"asset_id": null,
"fit": "none"
}
},
"scene_4_image_3": {
"name": "scene_4_image_3",
"type": "image",
"properties": {
"url": "blob:https://app.heygen.com/29cd0a23-1885-4727-b695-ef17cfa0813e",
"asset_id": null,
"fit": "none"
}
},
"scene_5_image_1": {
"name": "scene_5_image_1",
"type": "image",
"properties": {
"url": "blob:https://app.heygen.com/e2265816-4531-49eb-8e75-4ba8a7cf6305",
"asset_id": null,
"fit": "none"
}
},
"scene_5_image_2": {
"name": "scene_5_image_2",
"type": "image",
"properties": {
"url": "blob:https://app.heygen.com/a7e01dbd-ea84-41cc-b1b7-cb843bf6f9c8",
"asset_id": null,
"fit": "none"
}
},
"scene_5_image_3": {
"name": "scene_5_image_3",
"type": "image",
"properties": {
"url": "blob:https://app.heygen.com/29cd0a23-1885-4727-b695-ef17cfa0813e",
"asset_id": null,
"fit": "none"
}
},
"scene_2_bg_image": {
"name": "scene_2_bg_image",
"type": "image",
"properties": {
"url": "blob:https://app.heygen.com/332c8f13-63e6-4378-9f01-293f13e4314c",
"asset_id": null,
"fit": "none"
}
},
"scene_4_bg_image": {
"name": "scene_4_bg_image",
"type": "image",
"properties": {
"url": "blob:https://app.heygen.com/332c8f13-63e6-4378-9f01-293f13e4314c",
"asset_id": null,
"fit": "none"
}
},
"scene_5_bg_image": {
"name": "scene_5_bg_image",
"type": "image",
"properties": {
"url": "blob:https://app.heygen.com/332c8f13-63e6-4378-9f01-293f13e4314c",
"asset_id": null,
"fit": "none"
}
}
}
}
}
template_url = f"https://api.heygen.com/v2/template/{template_id}"
response = requests.get(template_url, headers=headers)
Step 3. Prepare Variable Values
Define variable values like fruit names, subtitles, and scripts.
api_key = "<your-api-key>"
headers = {"Accept": "application/json", "X-API-KEY": api_key}
template_id = "<template_id>"
FRUIT_NAME = "APPLE"
Subtitle = "The Wonderful World of Apples"
scene_2_script = "Apples are one of the most widely consumed fruits worldwide. They come in various colors, shapes, and sizes, with over 7,500 known apple cultivars around the world."
scene_3_script = (
"Some popular varieties include Granny Smith, Red Delicious, Gala, and Fuji."
)
scene_4_script = "They are a rich source of dietary fiber, vitamin C, and antioxidants. Eating apples regularly has been linked to numerous health benefits, including improved digestion, lowered risk of heart disease, and enhanced immune function..."
scene_5_script = "Additionally, apples are often associated with folklore and cultural traditions. They symbolize knowledge, temptation, and forbidden fruit in various mythologies and stories."
# and images...
Step 4. Generate Video from Template
Send a payload to the Generate endpoint for video creation.
generate_url = f"https://api.heygen.com/v2/template/{template_id}/generate"
payload = {
"test": True,
"caption": False,
"title": FRUIT_NAME + " | Fruit Presentation",
"variables": {
"Subtitle": {
"name": "Subtitle",
"type": "text",
"properties": {"content": Subtitle},
},
"FRUIT_NAME": {
"name": "FRUIT_NAME",
"type": "text",
"properties": {"content": FRUIT_NAME},
},
"scene_2_script": {
"name": "scene_2_script",
"type": "text",
"properties": {"content": scene_2_script},
},
"scene_3_script": {
"name": "scene_3_script",
"type": "text",
"properties": {"content": scene_3_script},
},
"scene_4_script": {
"name": "scene_4_script",
"type": "text",
"properties": {"content": scene_4_script},
},
"scene_5_script": {
"name": "scene_5_script",
"type": "text",
"properties": {"content": scene_5_script},
},
"scene_1_image_1": {
"name": "scene_1_image_1",
"type": "image",
"properties": {
"url": "https://images.unsplash.com/photo-1567974772901-1365e616baa9",
"asset_id": None,
"fit": "contain",
},
},
"scene_3_image_1": {
"name": "scene_3_image_1",
"type": "image",
"properties": {
"url": "https://i.postimg.cc/HkDP99Xp/bD6x1R5.jpg",
"asset_id": None,
"fit": "contain",
},
},
"scene_3_image_2": {
"name": "scene_3_image_2",
"type": "image",
"properties": {
"url": "https://i.postimg.cc/K81vtF7X/GmT8jqJ.jpg",
"asset_id": None,
"fit": "contain",
},
},
"scene_3_image_3": {
"name": "scene_3_image_3",
"type": "image",
"properties": {
"url": "https://i.postimg.cc/8CTKqkZ9/undefined-Imgur.jpg",
"asset_id": None,
"fit": "contain",
},
},
"scene_4_image_1": {
"name": "scene_4_image_1",
"type": "image",
"properties": {
"url": "https://images.unsplash.com/photo-1552255349-450c59a5ec8e",
"asset_id": None,
"fit": "contain",
},
},
"scene_4_image_2": {
"name": "scene_4_image_2",
"type": "image",
"properties": {
"url": "https://images.unsplash.com/photo-1570913149827-d2ac84ab3f9a",
"asset_id": None,
"fit": "contain",
},
},
"scene_4_image_3": {
"name": "scene_4_image_3",
"type": "image",
"properties": {
"url": "https://i.postimg.cc/XvxH3MhJ/OeCAhPD.png",
"asset_id": None,
"fit": "contain",
},
},
"scene_5_image_1": {
"name": "scene_5_image_1",
"type": "image",
"properties": {
"url": "https://i.postimg.cc/ZRRf57tL/pFJPqUx.jpg",
"asset_id": None,
"fit": "contain",
},
},
"scene_5_image_2": {
"name": "scene_5_image_2",
"type": "image",
"properties": {
"url": "https://i.postimg.cc/pT6shfPM/8MwSsQG.jpg",
"asset_id": None,
"fit": "contain",
},
},
"scene_5_image_3": {
"name": "scene_5_image_3",
"type": "image",
"properties": {
"url": "https://i.postimg.cc/GtTqk4p8/HxAM8yR.jpg",
"asset_id": None,
"fit": "contain",
},
},
"scene_2_bg_image": {
"name": "scene_2_bg_image",
"type": "image",
"properties": {
"url": "https://images.unsplash.com/photo-1545160788-dc8fd1971a96",
"asset_id": None,
"fit": "contain",
},
},
"scene_4_bg_image": {
"name": "scene_4_bg_image",
"type": "image",
"properties": {
"url": "https://images.unsplash.com/photo-1620992467768-3cb360bf2aac",
"asset_id": None,
"fit": "crop",
},
},
"scene_5_bg_image": {
"name": "scene_5_bg_image",
"type": "image",
"properties": {
"url": "https://images.unsplash.com/photo-1605153322277-dd0d7f608b4d",
"asset_id": None,
"fit": "crop",
},
},
},
}
headers["Content-Type"] = "application/json"
response = requests.post(generate_url, headers=headers, json=payload)
if not response.json()["data"]:
print(response)
print(response.json()["error"])
exit()
video_id = response.json()["data"]["video_id"]
print("video_id:", video_id)
Step 5. Check Video Status and Download the Video
Implement logic to check video status and download the video upon successful completion, we will print the video url and thumbnail url to the console and save the video to storage.
video_status_url = f"https://api.heygen.com/v1/video_status.get?video_id={video_id}"
while True:
response = requests.get(video_status_url, headers=headers)
status = response.json()["data"]["status"]
if status == "completed":
video_url = response.json()["data"]["video_url"]
thumbnail_url = response.json()["data"]["thumbnail_url"]
print(
f"Video generation completed! \nVideo URL: {video_url} \nThumbnail URL: {thumbnail_url}"
)
# Save the video to a file
video_filename = "generated_video.mp4"
with open(video_filename, "wb") as video_file:
video_content = requests.get(video_url).content
video_file.write(video_content)
break
elif status == "processing" or status == "pending":
print("Video is still processing. Checking status...")
time.sleep(5) # Sleep for 5 seconds before checking again
elif status == "failed":
error = response.json()["data"]["error"]
print(f"Video generation failed. '{error}'")
break
Final Result
Here is the complete Python code:
import requests
import time
api_key = "<your-api-key>"
headers = {"Accept": "application/json", "X-API-KEY": api_key}
template_id = "<template_id>"
FRUIT_NAME = "APPLE"
Subtitle = "The Wonderful World of Apples"
scene_2_script = "Apples are one of the most widely consumed fruits worldwide. They come in various colors, shapes, and sizes, with over 7,500 known apple cultivars around the world."
scene_3_script = (
"Some popular varieties include Granny Smith, Red Delicious, Gala, and Fuji."
)
scene_4_script = "They are a rich source of dietary fiber, vitamin C, and antioxidants. Eating apples regularly has been linked to numerous health benefits, including improved digestion, lowered risk of heart disease, and enhanced immune function..."
scene_5_script = "Additionally, apples are often associated with folklore and cultural traditions. They symbolize knowledge, temptation, and forbidden fruit in various mythologies and stories."
# Modify Template Elements and Generate Video
generate_url = f"https://api.heygen.com/v2/template/{template_id}/generate"
payload = {
"caption": False,
"title": FRUIT_NAME + " | Fruit Presentation",
"variables": {
"Subtitle": {
"name": "Subtitle",
"type": "text",
"properties": {"content": Subtitle},
},
"FRUIT_NAME": {
"name": "FRUIT_NAME",
"type": "text",
"properties": {"content": FRUIT_NAME},
},
"scene_2_script": {
"name": "scene_2_script",
"type": "text",
"properties": {"content": scene_2_script},
},
"scene_3_script": {
"name": "scene_3_script",
"type": "text",
"properties": {"content": scene_3_script},
},
"scene_4_script": {
"name": "scene_4_script",
"type": "text",
"properties": {"content": scene_4_script},
},
"scene_5_script": {
"name": "scene_5_script",
"type": "text",
"properties": {"content": scene_5_script},
},
"scene_1_image_1": {
"name": "scene_1_image_1",
"type": "image",
"properties": {
"url": "https://images.unsplash.com/photo-1567974772901-1365e616baa9",
"asset_id": None,
"fit": "contain",
},
},
"scene_3_image_1": {
"name": "scene_3_image_1",
"type": "image",
"properties": {
"url": "https://i.imgur.com/bD6x1R5.jpg",
"asset_id": None,
"fit": "contain",
},
},
"scene_3_image_2": {
"name": "scene_3_image_2",
"type": "image",
"properties": {
"url": "https://i.imgur.com/GmT8jqJ.jpg",
"asset_id": None,
"fit": "contain",
},
},
"scene_3_image_3": {
"name": "scene_3_image_3",
"type": "image",
"properties": {
"url": "https://i.imgur.com/kFXc1Dg.jpg",
"asset_id": None,
"fit": "contain",
},
},
"scene_4_image_1": {
"name": "scene_4_image_1",
"type": "image",
"properties": {
"url": "https://images.unsplash.com/photo-1552255349-450c59a5ec8e",
"asset_id": None,
"fit": "contain",
},
},
"scene_4_image_2": {
"name": "scene_4_image_2",
"type": "image",
"properties": {
"url": "https://images.unsplash.com/photo-1570913149827-d2ac84ab3f9a",
"asset_id": None,
"fit": "contain",
},
},
"scene_4_image_3": {
"name": "scene_4_image_3",
"type": "image",
"properties": {
"url": "https://i.imgur.com/OeCAhPD.png",
"asset_id": None,
"fit": "contain",
},
},
"scene_5_image_1": {
"name": "scene_5_image_1",
"type": "image",
"properties": {
"url": "https://i.imgur.com/pFJPqUx.jpg",
"asset_id": None,
"fit": "contain",
},
},
"scene_5_image_2": {
"name": "scene_5_image_2",
"type": "image",
"properties": {
"url": "https://i.imgur.com/8MwSsQG.jpg",
"asset_id": None,
"fit": "contain",
},
},
"scene_5_image_3": {
"name": "scene_5_image_3",
"type": "image",
"properties": {
"url": "https://i.imgur.com/HxAM8yR.jpg",
"asset_id": None,
"fit": "contain",
},
},
"scene_2_bg_image": {
"name": "scene_2_bg_image",
"type": "image",
"properties": {
"url": "https://images.unsplash.com/photo-1545160788-dc8fd1971a96",
"asset_id": None,
"fit": "contain",
},
},
"scene_4_bg_image": {
"name": "scene_4_bg_image",
"type": "image",
"properties": {
"url": "https://images.unsplash.com/photo-1620992467768-3cb360bf2aac",
"asset_id": None,
"fit": "crop",
},
},
"scene_5_bg_image": {
"name": "scene_5_bg_image",
"type": "image",
"properties": {
"url": "https://images.unsplash.com/photo-1605153322277-dd0d7f608b4d",
"asset_id": None,
"fit": "crop",
},
},
},
}
headers["Content-Type"] = "application/json"
response = requests.post(generate_url, headers=headers, json=payload)
if not response.json()["data"]:
print(response)
print(response.json()["error"])
exit()
video_id = response.json()["data"]["video_id"]
print("video_id:", video_id)
# Check Video Generation Status
video_status_url = f"https://api.heygen.com/v1/video_status.get?video_id={video_id}"
while True:
response = requests.get(video_status_url, headers=headers)
status = response.json()["data"]["status"]
if status == "completed":
video_url = response.json()["data"]["video_url"]
thumbnail_url = response.json()["data"]["thumbnail_url"]
print(
f"Video generation completed! \nVideo URL: {video_url} \nThumbnail URL: {thumbnail_url}"
)
# Save the video to a file
video_filename = "generated_video.mp4"
with open(video_filename, "wb") as video_file:
video_content = requests.get(video_url).content
video_file.write(video_content)
break
elif status == "processing" or status == "pending":
print("Video is still processing. Checking status...")
time.sleep(5) # Sleep for 5 seconds before checking again
elif status == "failed":
error = response.json()["data"]["error"]
print(f"Video generation failed. '{error}'")
break
Here is the final video output:
Conclusion
In this guide, we've walked you through the process of script, text elements, and images replacing within a template with Python HeyGen's Template API. By following the steps outlined here, you can seamlessly modify template elements to create customized videos that suit your specific needs.
Images are sourced from Unsplash and Wikipedia Commons under creative commons license.
Updated about 1 month ago