MySafeCode commited on
Commit
ff5a21e
·
verified ·
1 Parent(s): 5571748

Update final.py

Browse files
Files changed (1) hide show
  1. final.py +319 -1
final.py CHANGED
@@ -1,3 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  def generate_video(image_path, prompt_text, progress=gr.Progress()):
2
  """Generate video with proper polling"""
3
 
@@ -89,4 +139,272 @@ def generate_video(image_path, prompt_text, progress=gr.Progress()):
89
  yield "⏰ Timeout after 2 minutes", None
90
 
91
  except Exception as e:
92
- yield f"❌ Error: {str(e)}", None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import time
3
+ import gradio as gr
4
+ from byteplussdkarkruntime import Ark
5
+ import requests
6
+ from datetime import datetime
7
+
8
+ # Get API key from Hugging Face secret "Key" and CLEAN it
9
+ API_KEY = os.environ.get("Key", "").strip()
10
+ print(f"✅ Key loaded, length: {len(API_KEY)}")
11
+
12
+ # Initialize client with proxy
13
+ client = Ark(
14
+ base_url="https://1hit.no/proxy/proxy.php",
15
+ api_key=API_KEY,
16
+ timeout=30.0,
17
+ max_retries=3,
18
+ )
19
+
20
+ # Fresh new prompts
21
+ DEFAULT_PROMPTS = {
22
+ "Cinematic Nature": "Majestic drone shot soaring above misty mountains at golden hour, sunlight breaking through clouds, cinematic 4k quality, smooth motion --duration 5 --camerafixed false",
23
+ "Urban Exploration": "Dynamic drone flight through narrow alleyways of a neon-lit Tokyo street at night, rain-slicked surfaces reflecting lights, cyberpunk aesthetic --duration 5 --camerafixed false",
24
+ "Action Sequence": "High-speed drone chasing a sports car through a winding coastal road, dramatic cliffside views, action movie style --duration 5 --camerafixed false",
25
+ "Abstract Art": "Surreal drone flight through floating geometric shapes in a dreamlike void, pastel colors, ethereal atmosphere --duration 5 --camerafixed false",
26
+ "Wildlife Documentary": "Drone following a herd of elephants across the African savanna at sunset, National Geographic style, majestic wildlife cinematography --duration 5 --camerafixed false",
27
+ "Sports Highlight": "Drone racing alongside professional skiers carving through fresh powder in the Alps, high-energy sports broadcast style --duration 5 --camerafixed false",
28
+ "Beach Paradise": "Drone gliding over turquoise waters and white sand beaches, palm trees swaying, tropical paradise aerial view --duration 5 --camerafixed false",
29
+ "Ancient Temple": "Drone circling around ancient Angkor Wat temple at dawn, mystical atmosphere, historical documentary style --duration 5 --camerafixed false"
30
+ }
31
+
32
+ def poll_via_json(task_id):
33
+ """Check io.json for task status"""
34
+ json_url = "https://1hit.no/proxy/io.json"
35
+ try:
36
+ response = requests.get(json_url)
37
+ data = response.json()
38
+ if task_id in data:
39
+ task_data = data[task_id]
40
+ status = task_data.get('status')
41
+ if status == 'succeeded':
42
+ return task_data.get('video_url')
43
+ elif status == 'failed':
44
+ return "FAILED"
45
+ else:
46
+ return "PROCESSING"
47
+ except:
48
+ pass
49
+ return None
50
+
51
  def generate_video(image_path, prompt_text, progress=gr.Progress()):
52
  """Generate video with proper polling"""
53
 
 
139
  yield "⏰ Timeout after 2 minutes", None
140
 
141
  except Exception as e:
142
+ yield f"❌ Error: {str(e)}", None
143
+
144
+ def update_prompt(choice):
145
+ return DEFAULT_PROMPTS.get(choice, "")
146
+
147
+ # MANUAL POLLING FUNCTIONS
148
+ def manual_poll(task_id):
149
+ """Manually poll a specific task and update io.json"""
150
+ if not task_id:
151
+ return "❌ Please enter a task ID"
152
+
153
+ try:
154
+ # Call proxy to poll this specific task
155
+ url = f"https://1hit.no/proxy/proxy.php?task_id={task_id}"
156
+ headers = {"Authorization": f"Bearer {API_KEY}"}
157
+
158
+ response = requests.get(url, headers=headers)
159
+
160
+ # Also fetch updated io.json
161
+ io_response = requests.get("https://1hit.no/proxy/io.json")
162
+ io_data = io_response.json()
163
+
164
+ if task_id in io_data:
165
+ status = io_data[task_id].get('status')
166
+ video_url = io_data[task_id].get('video_url')
167
+
168
+ result = f"✅ Task {task_id}\n"
169
+ result += f"Status: {status}\n"
170
+ if video_url:
171
+ result += f"Video URL: {video_url}\n"
172
+ if 'response' in io_data[task_id]:
173
+ result += f"Full response: {io_data[task_id]['response']}\n"
174
+ return result
175
+ else:
176
+ return f"❌ Task {task_id} not found in io.json"
177
+
178
+ except Exception as e:
179
+ return f"❌ Error: {str(e)}"
180
+
181
+ def get_raw_json():
182
+ """Fetch raw io.json"""
183
+ try:
184
+ r = requests.get("https://1hit.no/proxy/io.json")
185
+ return r.json()
186
+ except:
187
+ return {"error": "Could not fetch io.json"}
188
+
189
+ # WATCH & DOWNLOAD FUNCTIONS
190
+ def get_task_list():
191
+ """Get list of all tasks from io.json"""
192
+ try:
193
+ r = requests.get("https://1hit.no/proxy/io.json")
194
+ data = r.json()
195
+ tasks = []
196
+ for task_id, task_data in data.items():
197
+ status = task_data.get('status', 'unknown')
198
+ created = task_data.get('created', 0)
199
+ # Format time
200
+ time_str = datetime.fromtimestamp(created).strftime('%Y-%m-%d %H:%M:%S')
201
+
202
+ # Get prompt preview
203
+ prompt = task_data.get('request', {}).get('content', [{}])[0].get('text', 'No prompt')
204
+ prompt_preview = prompt[:50] + '...' if len(prompt) > 50 else prompt
205
+
206
+ tasks.append({
207
+ "id": task_id,
208
+ "status": status,
209
+ "created": time_str,
210
+ "created_ts": created,
211
+ "video_url": task_data.get('video_url', ''),
212
+ "prompt": prompt_preview
213
+ })
214
+ # Sort by created time, newest first
215
+ tasks.sort(key=lambda x: x['created_ts'], reverse=True)
216
+ return tasks
217
+ except Exception as e:
218
+ print(f"Error getting task list: {e}")
219
+ return []
220
+
221
+ def refresh_task_list():
222
+ """Refresh the task list dropdown"""
223
+ tasks = get_task_list()
224
+ choices = [f"{t['id']} | {t['status']} | {t['created']}" for t in tasks]
225
+ return gr.Dropdown(choices=choices, value=choices[0] if choices else None)
226
+
227
+ def load_task(selection):
228
+ """Load selected task details"""
229
+ if not selection:
230
+ return "No task selected", None, None
231
+
232
+ task_id = selection.split(' | ')[0]
233
+ try:
234
+ r = requests.get("https://1hit.no/proxy/io.json")
235
+ data = r.json()
236
+ task = data.get(task_id, {})
237
+
238
+ video_url = task.get('video_url', '')
239
+ status = task.get('status', 'unknown')
240
+
241
+ # Get full prompt
242
+ prompt = task.get('request', {}).get('content', [{}])[0].get('text', 'No prompt')
243
+
244
+ # Get created time
245
+ created = task.get('created', 0)
246
+ created_str = datetime.fromtimestamp(created).strftime('%Y-%m-%d %H:%M:%S')
247
+
248
+ # Get response data if available
249
+ response = task.get('response', {})
250
+
251
+ info = f"### Task Details\n\n"
252
+ info += f"**Task ID:** `{task_id}`\n"
253
+ info += f"**Status:** `{status}`\n"
254
+ info += f"**Created:** {created_str}\n"
255
+ info += f"**Prompt:** {prompt}\n\n"
256
+
257
+ if status == 'succeeded' and video_url:
258
+ info += f"✅ **Video ready!**\n"
259
+ info += f"**Download:** [Click here]({video_url})\n"
260
+ elif status == 'failed':
261
+ error = task.get('response', {}).get('error', 'Unknown error')
262
+ info += f"❌ **Failed:** {error}\n"
263
+
264
+ return info, video_url, video_url
265
+ except Exception as e:
266
+ return f"Error loading task: {e}", None, None
267
+
268
+ # Create the interface
269
+ with gr.Blocks(title="BytePlus Video Generator", theme=gr.themes.Soft()) as demo:
270
+
271
+ gr.Markdown("# 🎥 BytePlus Video Generator")
272
+
273
+ with gr.Row():
274
+ if API_KEY:
275
+ gr.Markdown("✅ **API Key:** Configured")
276
+ else:
277
+ gr.Markdown("❌ **API Key:** Not configured - please add 'Key' secret")
278
+
279
+ # Create tabs
280
+ with gr.Tabs():
281
+ # Tab 1: Generate Video
282
+ with gr.TabItem("🎬 Generate Video"):
283
+ with gr.Row():
284
+ with gr.Column():
285
+ image_input = gr.Image(
286
+ label="Upload Starting Image",
287
+ type="filepath",
288
+ height=300
289
+ )
290
+
291
+ shot_type = gr.Dropdown(
292
+ choices=list(DEFAULT_PROMPTS.keys()),
293
+ label="🎬 Shot Type",
294
+ value="Cinematic Nature"
295
+ )
296
+
297
+ prompt = gr.Textbox(
298
+ label="📝 Custom Prompt",
299
+ lines=3,
300
+ value=DEFAULT_PROMPTS["Cinematic Nature"]
301
+ )
302
+
303
+ shot_type.change(fn=update_prompt, inputs=shot_type, outputs=prompt)
304
+
305
+ generate_btn = gr.Button("🚀 Generate Video", variant="primary", size="lg")
306
+
307
+ with gr.Column():
308
+ status = gr.Textbox(label="Status", lines=6)
309
+ video_output = gr.Video(label="Generated Video")
310
+
311
+ # Quick shot buttons
312
+ gr.Markdown("### Quick Shot Select")
313
+ with gr.Row():
314
+ gr.Button("🏔️ Nature").click(fn=lambda: "Cinematic Nature", outputs=shot_type)
315
+ gr.Button("🌃 City").click(fn=lambda: "Urban Exploration", outputs=shot_type)
316
+ gr.Button("🏎️ Action").click(fn=lambda: "Action Sequence", outputs=shot_type)
317
+ gr.Button("🎨 Abstract").click(fn=lambda: "Abstract Art", outputs=shot_type)
318
+ gr.Button("🦁 Wildlife").click(fn=lambda: "Wildlife Documentary", outputs=shot_type)
319
+ gr.Button("⛷️ Sports").click(fn=lambda: "Sports Highlight", outputs=shot_type)
320
+
321
+ # Tab 2: Manual Polling
322
+ with gr.TabItem("🔧 Manual Polling"):
323
+ gr.Markdown("### 🔧 Manual Polling & Debug")
324
+
325
+ with gr.Row():
326
+ with gr.Column():
327
+ gr.Markdown("#### Poll Specific Task")
328
+ task_id_input = gr.Textbox(
329
+ label="Task ID",
330
+ placeholder="Enter task ID (cgt-...)"
331
+ )
332
+ poll_btn = gr.Button("🔄 Poll Now", variant="primary")
333
+ poll_result = gr.Textbox(label="Poll Result", lines=10)
334
+
335
+ poll_btn.click(
336
+ fn=manual_poll,
337
+ inputs=task_id_input,
338
+ outputs=poll_result
339
+ )
340
+
341
+ with gr.Column():
342
+ gr.Markdown("#### Current io.json")
343
+ refresh_btn = gr.Button("🔄 Refresh io.json", variant="secondary")
344
+ raw_json = gr.JSON(label="io.json Contents")
345
+
346
+ refresh_btn.click(
347
+ fn=get_raw_json,
348
+ outputs=raw_json
349
+ )
350
+
351
+ gr.Markdown("""
352
+ ### 📝 Instructions
353
+ 1. Copy a task ID from above (like `cgt-20260217072358-hszt9`)
354
+ 2. Paste it in the Task ID field
355
+ 3. Click "Poll Now" to force an update
356
+ 4. Check io.json to see if status changed
357
+ """)
358
+
359
+ # Tab 3: Watch & Download
360
+ with gr.TabItem("📺 Watch & Download"):
361
+ gr.Markdown("### 📺 Browse and Download Generated Videos")
362
+
363
+ with gr.Row():
364
+ with gr.Column(scale=1):
365
+ refresh_list_btn = gr.Button("🔄 Refresh Task List", variant="primary")
366
+ task_list = gr.Dropdown(
367
+ label="Select Task",
368
+ choices=[],
369
+ interactive=True
370
+ )
371
+
372
+ with gr.Column(scale=2):
373
+ task_info = gr.Markdown("Select a task to view details")
374
+
375
+ with gr.Row():
376
+ with gr.Column():
377
+ video_player = gr.Video(label="Video Player")
378
+ download_link = gr.File(label="Download Video")
379
+
380
+ # Load task list on button click
381
+ refresh_list_btn.click(
382
+ fn=refresh_task_list,
383
+ outputs=task_list
384
+ )
385
+
386
+ # Load task when selected
387
+ task_list.change(
388
+ fn=load_task,
389
+ inputs=task_list,
390
+ outputs=[task_info, video_player, download_link]
391
+ )
392
+
393
+ # Auto-load task list when tab is opened
394
+ demo.load(
395
+ fn=refresh_task_list,
396
+ outputs=task_list
397
+ )
398
+
399
+ # Connect generate button
400
+ generate_btn.click(
401
+ fn=generate_video,
402
+ inputs=[image_input, prompt],
403
+ outputs=[status, video_output]
404
+ )
405
+
406
+ if __name__ == "__main__":
407
+ demo.launch(server_name="0.0.0.0")
408
+
409
+
410
+