File size: 5,827 Bytes
72f6ebe eae8a72 72f6ebe aadb66e 72f6ebe | 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 165 166 167 168 169 170 171 | import gradio as gr
import os
import time
import json
from PIL import Image
import logging
import sys
# Set up logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Print Gradio version for debugging
logger.info(f"Gradio version: {gr.__version__}")
# Import BytePlus SDK
try:
import byteplussdkcore
from byteplussdkarkruntime import Ark
SDK_AVAILABLE = True
logger.info("✅ BytePlus SDK loaded successfully")
except ImportError as e:
SDK_AVAILABLE = False
logger.warning(f"⚠️ BytePlus SDK not available: {e}")
def generate_video(api_key, prompt_text, image_url, model_id, progress=gr.Progress()):
"""Generate video using the BytePlus SDK"""
if not api_key or api_key == "key":
yield "⚠️ Please enter your actual BytePlus API key (the 'key' is just a placeholder)", None
return
if not SDK_AVAILABLE:
yield "❌ BytePlus SDK not available. Please check installation of byteplus-python-sdk-v2", None
return
try:
progress(0, desc="Initializing SDK...")
# Set environment variable
os.environ["Key"] = api_key
# Initialize client
client = Ark(
base_url="https://ark.ap-southeast.bytepluses.com/api/v3",
api_key=os.environ.get("Key"),
)
progress(0.1, desc="Creating video generation request...")
logger.info("🚀 Creating video generation request...")
# Create task
create_result = client.content_generation.tasks.create(
model=model_id,
content=[
{
"type": "text",
"text": prompt_text
},
{
"type": "image_url",
"image_url": {
"url": image_url
}
}
]
)
task_id = create_result.id
logger.info(f"📋 Task ID: {task_id}")
yield f"⏳ Task created with ID: {task_id}. Waiting for completion...", None
# Polling
max_attempts = 60
attempts = 0
while attempts < max_attempts:
progress(0.1 + (attempts / max_attempts) * 0.8,
desc=f"Polling status: {attempts + 1}/{max_attempts}")
get_result = client.content_generation.tasks.get(task_id=task_id)
status = get_result.status
if status == "succeeded":
progress(1.0, desc="Complete!")
logger.info("✅ Task succeeded!")
# Extract video URL
video_url = None
if hasattr(get_result, 'output') and get_result.output:
if isinstance(get_result.output, list) and len(get_result.output) > 0:
video_url = get_result.output[0].get('video_url')
elif hasattr(get_result.output, 'video_url'):
video_url = get_result.output.video_url
elif isinstance(get_result.output, dict):
video_url = get_result.output.get('video_url')
if video_url:
yield f"✅ Video generated successfully!", video_url
else:
yield f"✅ Task completed but no video URL in response", None
break
elif status == "failed":
error_msg = get_result.error if hasattr(get_result, 'error') else "Unknown error"
yield f"❌ Task failed: {error_msg}", None
break
else:
yield f"⏳ Current status: {status}, waiting... ({attempts + 1}/{max_attempts})", None
time.sleep(1)
attempts += 1
if attempts >= max_attempts:
yield "⏰ Timeout: Task took too long to complete. Please try again.", None
except Exception as e:
logger.error(f"Error: {e}")
yield f"❌ Error: {str(e)}", None
# Simple, clean UI
with gr.Blocks(title="BytePlus Video Generator", theme=gr.themes.Soft()) as demo:
gr.Markdown("""
# 🎥 BytePlus Video Generator
Generate videos from images and text prompts
""")
with gr.Row():
with gr.Column():
api_key = gr.Textbox(
label="🔑 API Key",
type="password",
placeholder="Enter your BytePlus API key",
value="key"
)
model_id = gr.Textbox(
label="🤖 Model ID",
value="seedance-1-5-pro-251215"
)
image_url = gr.Textbox(
label="🖼️ Image URL",
value="https://ark-doc.tos-ap-southeast-1.bytepluses.com/seepro_i2v%20.png"
)
prompt = gr.Textbox(
label="📝 Prompt",
lines=3,
value="At breakneck speed, drones thread through intricate obstacles --duration 5 --camerafixed false"
)
generate_btn = gr.Button("🚀 Generate", variant="primary")
with gr.Column():
status = gr.Textbox(label="Status", lines=3)
video = gr.Video(label="Generated Video")
video_url = gr.Textbox(label="Video URL")
generate_btn.click(
fn=generate_video,
inputs=[api_key, prompt, image_url, model_id],
outputs=[status, video]
).then(
fn=lambda url: url if url else "",
inputs=[video],
outputs=[video_url]
)
if __name__ == "__main__":
demo.launch() |