MySafeCode commited on
Commit
4c05865
·
verified ·
1 Parent(s): b0593c4

Create a.py

Browse files
Files changed (1) hide show
  1. a.py +169 -0
a.py ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import time
3
+ import gradio as gr
4
+ from byteplussdkarkruntime import Ark
5
+
6
+ # Get API key from Hugging Face secret "Key"
7
+ API_KEY = os.environ.get("Key", "")
8
+
9
+ # Initialize client exactly like your working code
10
+ client = Ark(
11
+ base_url="https://ark.ap-southeast.bytepluses.com/api/v3",
12
+ api_key=API_KEY,
13
+ )
14
+
15
+ def generate_video(image, prompt_text, progress=gr.Progress()):
16
+ """Generate video using HF temp URL trick"""
17
+
18
+ if not API_KEY:
19
+ yield "❌ API Key not configured. Please add 'Key' secret.", None
20
+ return
21
+
22
+ if image is None:
23
+ yield "⚠️ Please upload an image first", None
24
+ return
25
+
26
+ try:
27
+ progress(0, desc="Preparing image...")
28
+
29
+ # THE TRICK: Get the Hugging Face temp URL
30
+ # When type="filepath", image.name gives us the local path
31
+ # HF automatically serves it as /file=path
32
+ image_url = f"/file={image.name}"
33
+ print(f"Using image URL: {image_url}")
34
+
35
+ yield "✅ Image ready! Creating video request...", None
36
+
37
+ progress(0.2, desc="Creating request...")
38
+
39
+ # Exactly your working code structure
40
+ print("----- create request -----")
41
+ create_result = client.content_generation.tasks.create(
42
+ model="seedance-1-5-pro-251215",
43
+ content=[
44
+ {
45
+ "type": "text",
46
+ "text": prompt_text
47
+ },
48
+ {
49
+ "type": "image_url",
50
+ "image_url": {
51
+ "url": image_url # Using HF temp URL!
52
+ }
53
+ }
54
+ ]
55
+ )
56
+
57
+ task_id = create_result.id
58
+ print(f"Task created: {task_id}")
59
+ yield f"✅ Task created: {task_id}", None
60
+
61
+ progress(0.3, desc="Polling for results...")
62
+
63
+ # Polling exactly like your working code
64
+ attempts = 0
65
+ max_attempts = 120 # 2 minutes max
66
+
67
+ while attempts < max_attempts:
68
+ get_result = client.content_generation.tasks.get(task_id=task_id)
69
+ status = get_result.status
70
+
71
+ if status == "succeeded":
72
+ progress(1.0, desc="Complete!")
73
+ # Extract video URL from the response structure we saw
74
+ video_url = get_result.content.video_url if hasattr(get_result, 'content') else None
75
+ print(f"Video URL: {video_url}")
76
+ yield "✅ Video generated successfully!", video_url
77
+ return
78
+
79
+ elif status == "failed":
80
+ error_msg = get_result.error if hasattr(get_result, 'error') else "Unknown error"
81
+ yield f"❌ Failed: {error_msg}", None
82
+ return
83
+ else:
84
+ progress(0.3 + (attempts/max_attempts)*0.7, desc=f"Status: {status}")
85
+ yield f"⏳ Status: {status}... (attempt {attempts + 1})", None
86
+ time.sleep(1)
87
+ attempts += 1
88
+
89
+ yield "⏰ Timeout after 2 minutes", None
90
+
91
+ except Exception as e:
92
+ print(f"Error: {e}")
93
+ yield f"❌ Error: {str(e)}", None
94
+
95
+ # Simple, clean interface
96
+ with gr.Blocks(title="BytePlus Video Generator", theme=gr.themes.Soft()) as demo:
97
+
98
+ gr.Markdown("""
99
+ # 🎥 BytePlus Video Generator
100
+
101
+ Upload an image and describe the video you want to generate.
102
+ """)
103
+
104
+ # Show API key status
105
+ if API_KEY:
106
+ gr.Markdown("✅ **API Key:** Configured")
107
+ else:
108
+ gr.Markdown("❌ **API Key:** Not configured - please add 'Key' secret")
109
+
110
+ with gr.Row():
111
+ with gr.Column():
112
+ # Image upload - CHANGED to type="filepath" to get the temp URL
113
+ image_input = gr.Image(
114
+ label="Upload Starting Image",
115
+ type="filepath", # This gives us image.name with the temp path
116
+ height=300
117
+ )
118
+
119
+ # Text prompt
120
+ prompt = gr.Textbox(
121
+ label="Video Description",
122
+ lines=4,
123
+ placeholder="Describe what you want to see...",
124
+ value="At breakneck speed, drones thread through intricate obstacles or stunning natural wonders, delivering an immersive, heart-pounding flying experience. --duration 5 --camerafixed false"
125
+ )
126
+
127
+ # Generate button
128
+ generate_btn = gr.Button("🚀 Generate Video", variant="primary", size="lg")
129
+
130
+ with gr.Column():
131
+ # Status
132
+ status = gr.Textbox(
133
+ label="Status",
134
+ lines=4,
135
+ interactive=False
136
+ )
137
+
138
+ # Video output
139
+ video_output = gr.Video(
140
+ label="Generated Video",
141
+ interactive=False
142
+ )
143
+
144
+ # Example prompts
145
+ gr.Markdown("---")
146
+ gr.Markdown("### Example Prompts")
147
+ with gr.Row():
148
+ gr.Button("Nature").click(
149
+ fn=lambda: "Aerial drone shot over mountains at sunrise, cinematic --duration 5 --camerafixed false",
150
+ outputs=prompt
151
+ )
152
+ gr.Button("City").click(
153
+ fn=lambda: "Fast drone racing through futuristic city streets --duration 5 --camerafixed false",
154
+ outputs=prompt
155
+ )
156
+ gr.Button("Ocean").click(
157
+ fn=lambda: "Drone following waves at golden hour --duration 5 --camerafixed false",
158
+ outputs=prompt
159
+ )
160
+
161
+ # Connect the generate button
162
+ generate_event = generate_btn.click(
163
+ fn=generate_video,
164
+ inputs=[image_input, prompt],
165
+ outputs=[status, video_output]
166
+ )
167
+
168
+ if __name__ == "__main__":
169
+ demo.launch(server_name="0.0.0.0")