Spaces:
Sleeping
Sleeping
File size: 6,388 Bytes
122b90e 468dbfa 0ef4926 122b90e f339966 122b90e |
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 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
import streamlit as st
import requests
import time
# API Endpoints
GENERATE_VIDEO_URL = "https://api.heygen.com/v2/video/generate"
VIDEO_STATUS_URL = "https://api.heygen.com/v1/video_status.get"
# API Headers
HEADERS = {
"accept": "application/json",
"content-type": "application/json",
"x-api-key": "MWE1NDAyOWU1ZDkyNDhlZmIzM2MzYzY3ZmU1MGNiZDQtMTc0NDAxMjI0MA==" # Replace with actual API key
}
# Streamlit UI
st.title("HeyGen Video Generator π¬")
# instructions for users
st.subheader("Follow these simple steps:")
st.caption("""1οΈβ£ Enter Video Details β Provide a title.\n
2οΈβ£ Add Scenes β Click "β Add Scene" to add multiple scenes, each with:\n
Avatar ID & Style\n
Voice ID & Script Input\n
Emotion & Positioning\n
3οΈβ£ Generate Video β Click "π Generate Video" to start processing.\n
4οΈβ£ Track Progress β The app will automatically check the status every half minute.\n
5οΈβ£ Watch & Reset β Once the video is ready, it will be displayed. Click "π Reset All" to start over.\n\n""")
# Session state to track scenes and video status
if "scenes" not in st.session_state:
st.session_state.scenes = [] # List to hold scene data
if "video_id" not in st.session_state:
st.session_state.video_id = None
if "video_status" not in st.session_state:
st.session_state.video_status = None
# Function to reset all inputs
def reset_all():
st.session_state.scenes = []
st.session_state.video_id = None
st.session_state.video_status = None
st.rerun()
# Button to add a new scene
if st.button("β Add Scene",type="primary"):
st.session_state.scenes.append({
"avatar_id": "",
"avatar_style": "normal",
"offset_x": 0,
"offset_y": 0,
"voice_id": "",
"input_text": "",
"emotion": "Friendly"
})
# Input fields for video title and callback ID
title = st.text_input("Title", placeholder="Enter video title")
# Render scenes dynamically
for i, scene in enumerate(st.session_state.scenes):
st.subheader(f"π¬ Scene {i+1}")
# Inputs for each scene
scene["avatar_id"] = st.text_input(f"Avatar ID (Scene {i+1})", scene["avatar_id"], key=f"avatar_id_{i}")
scene["avatar_style"] = st.selectbox(f"Avatar Style (Scene {i+1})", ["normal", "circle", "closeUp"], index=0, key=f"avatar_style_{i}")
scene["offset_x"] = st.number_input(f"Offset X (Scene {i+1})", value=scene["offset_x"], key=f"offset_x_{i}")
scene["offset_y"] = st.number_input(f"Offset Y (Scene {i+1})", value=scene["offset_y"], key=f"offset_y_{i}")
scene["voice_id"] = st.text_input(f"Voice ID (Scene {i+1})", scene["voice_id"], key=f"voice_id_{i}")
scene["input_script"] = st.text_area(f"Input script (Scene {i+1})", scene["input_text"], key=f"input_text_{i}")
scene["emotion"] = st.selectbox(f"Voice emotion (Scene {i+1})", ["Friendly", "Serious", "Excited", "Soothing", "Broadcaster"], index=0, key=f"emotion_{i}")
# Button to generate video
if st.button("π Generate Video"):
if not title or not st.session_state.scenes:
st.error("β Please fill in all required fields and add at least one scene!")
else:
# Constructing video_inputs array from scenes
video_inputs = [
{
"character": {
"type": "avatar",
"avatar_id": scene["avatar_id"],
"scale": 1,
"avatar_style": scene["avatar_style"],
"offset": {"x": scene["offset_x"], "y": scene["offset_y"]},
},
"voice": {
"type": "text",
"voice_id": scene["voice_id"],
"input_text": scene["input_script"],
"speed": 1,
"emotion": scene["emotion"],
},
}
for scene in st.session_state.scenes
]
# API Request Payload
payload = {
"caption": False,
"title": title,
"dimension": {"width": 1280, "height": 720},
"video_inputs": video_inputs,
}
# Call API to generate video
response = requests.post(GENERATE_VIDEO_URL, json=payload, headers=HEADERS)
# Handle API Response
if response.status_code == 200:
data = response.json()
if data.get("error") is None:
st.session_state.video_id = data["data"]["video_id"]
st.success(f"β
Video generation started! Video ID: {st.session_state.video_id}")
else:
st.error(f"β API Error: {data['error']}")
else:
st.error(f"β Request Failed! Status Code: {response.status_code}")
# Function to check video status
def check_video_status(video_id):
while True:
params = {"video_id": video_id}
response = requests.get(VIDEO_STATUS_URL, headers=HEADERS, params=params)
if response.status_code == 200:
data = response.json()
status = data["data"]["status"]
st.session_state.video_status = status
# Show status messages
if status in ["processing", "waiting", "pending"]:
st.info(f"β³ Video is still {status}. Please wait...")
elif status == "failed":
error_info = data["data"].get("error", {})
error_message = error_info.get("message", "An unknown error occurred.")
st.error(f"β Video generation failed: {error_message}")
return
elif status == "completed":
video_url = data["data"].get("video_url")
if video_url:
st.success("π Video is ready! Watch it below:")
st.video(video_url)
else:
st.warning("β οΈ Video completed but URL is missing.")
return
else:
st.error(f"β Request Failed! Status Code: {response.status_code}")
return
time.sleep(30) # Wait 1 minute before checking again
# Check video status if video ID is available
if st.session_state.video_id:
check_video_status(st.session_state.video_id)
# Reset button (only shows after video generation)
if st.session_state.video_status == "completed":
if st.button("π Reset All"):
reset_all()
|