Update app.py
Browse files
app.py
CHANGED
@@ -13,7 +13,7 @@ from huggingface_hub import login
|
|
13 |
# --- 1. Configuration and Authentication ---
|
14 |
|
15 |
# IMPORTANT: Replace with your Google Cloud Project ID
|
16 |
-
GCP_PROJECT_ID = "
|
17 |
GCP_LOCATION = "us-central1"
|
18 |
MODEL_ID = "veo-3.0-generate-preview"
|
19 |
API_ENDPOINT = f"{GCP_LOCATION}-aiplatform.googleapis.com"
|
@@ -51,7 +51,7 @@ else:
|
|
51 |
credentials.refresh(auth_req)
|
52 |
return credentials.token
|
53 |
|
54 |
-
# --- 2. Core Video Generation Logic (WITH FIX) ---
|
55 |
|
56 |
def generate_video(prompt: str):
|
57 |
if not prompt:
|
@@ -66,17 +66,12 @@ else:
|
|
66 |
"Content-Type": "application/json",
|
67 |
}
|
68 |
|
69 |
-
# --- Step A: Submit the long-running prediction job ---
|
70 |
payload = {
|
71 |
"instances": [{"prompt": prompt}],
|
72 |
"parameters": {
|
73 |
-
"aspectRatio": "16:9",
|
74 |
-
"
|
75 |
-
"
|
76 |
-
"personGeneration": "allow_all",
|
77 |
-
"addWatermark": True,
|
78 |
-
"includeRaiReason": True,
|
79 |
-
"generateAudio": True,
|
80 |
}
|
81 |
}
|
82 |
|
@@ -86,7 +81,6 @@ else:
|
|
86 |
operation_name = response.json()["name"]
|
87 |
print(f"Successfully submitted job. Operation Name: {operation_name}")
|
88 |
|
89 |
-
# --- Step B: Poll for the result ---
|
90 |
MAX_POLL_ATTEMPTS = 60
|
91 |
for i in range(MAX_POLL_ATTEMPTS):
|
92 |
status_message = f"Status: Job submitted. Polling for result (Attempt {i+1}/{MAX_POLL_ATTEMPTS})... Please wait."
|
@@ -103,16 +97,13 @@ else:
|
|
103 |
|
104 |
if poll_result.get("done"):
|
105 |
print("Job finished successfully.")
|
106 |
-
# --- START: ROBUST RESPONSE HANDLING FIX ---
|
107 |
-
|
108 |
-
# For debugging, print the entire final response from Google
|
109 |
print(f"Full successful response payload: {json.dumps(poll_result, indent=2)}")
|
110 |
|
111 |
response_data = poll_result.get("response", {})
|
112 |
|
113 |
-
#
|
114 |
-
if "
|
115 |
-
video_base64 = response_data["
|
116 |
video_bytes = base64.b64decode(video_base64)
|
117 |
|
118 |
temp_video_path = "generated_video.mp4"
|
@@ -122,23 +113,18 @@ else:
|
|
122 |
yield "Status: Done! Video generated successfully.", temp_video_path
|
123 |
return
|
124 |
else:
|
125 |
-
# This branch handles cases where the job is "done" but no video was returned,
|
126 |
-
# most likely due to safety filters.
|
127 |
error_message = "Video generation finished, but the content was blocked by safety filters or another issue prevented video creation."
|
128 |
print(f"ERROR: {error_message}")
|
129 |
raise gr.Error(error_message)
|
130 |
-
|
131 |
-
# --- END: ROBUST RESPONSE HANDLING FIX ---
|
132 |
|
133 |
time.sleep(10)
|
134 |
|
135 |
-
raise gr.Error("Operation timed out after several minutes.
|
136 |
|
137 |
except requests.exceptions.HTTPError as e:
|
138 |
print(f"HTTP Error: {e.response.text}")
|
139 |
raise gr.Error(f"API Error: {e.response.status_code}. Details: {e.response.text}")
|
140 |
except Exception as e:
|
141 |
-
# Catch the specific Gradio error we raised, and any other unexpected errors.
|
142 |
print(f"An error occurred in the generation process: {e}")
|
143 |
raise gr.Error(str(e))
|
144 |
|
|
|
13 |
# --- 1. Configuration and Authentication ---
|
14 |
|
15 |
# IMPORTANT: Replace with your Google Cloud Project ID
|
16 |
+
GCP_PROJECT_ID = "YOUR_GCP_PROJECT_ID" # Make sure this is replaced!
|
17 |
GCP_LOCATION = "us-central1"
|
18 |
MODEL_ID = "veo-3.0-generate-preview"
|
19 |
API_ENDPOINT = f"{GCP_LOCATION}-aiplatform.googleapis.com"
|
|
|
51 |
credentials.refresh(auth_req)
|
52 |
return credentials.token
|
53 |
|
54 |
+
# --- 2. Core Video Generation Logic (WITH FINAL FIX) ---
|
55 |
|
56 |
def generate_video(prompt: str):
|
57 |
if not prompt:
|
|
|
66 |
"Content-Type": "application/json",
|
67 |
}
|
68 |
|
|
|
69 |
payload = {
|
70 |
"instances": [{"prompt": prompt}],
|
71 |
"parameters": {
|
72 |
+
"aspectRatio": "16:9", "sampleCount": 1, "durationSeconds": 8,
|
73 |
+
"personGeneration": "allow_all", "addWatermark": True,
|
74 |
+
"includeRaiReason": True, "generateAudio": True,
|
|
|
|
|
|
|
|
|
75 |
}
|
76 |
}
|
77 |
|
|
|
81 |
operation_name = response.json()["name"]
|
82 |
print(f"Successfully submitted job. Operation Name: {operation_name}")
|
83 |
|
|
|
84 |
MAX_POLL_ATTEMPTS = 60
|
85 |
for i in range(MAX_POLL_ATTEMPTS):
|
86 |
status_message = f"Status: Job submitted. Polling for result (Attempt {i+1}/{MAX_POLL_ATTEMPTS})... Please wait."
|
|
|
97 |
|
98 |
if poll_result.get("done"):
|
99 |
print("Job finished successfully.")
|
|
|
|
|
|
|
100 |
print(f"Full successful response payload: {json.dumps(poll_result, indent=2)}")
|
101 |
|
102 |
response_data = poll_result.get("response", {})
|
103 |
|
104 |
+
# <<< FIX: Changed "predictions" to "videos" to match the actual API response >>>
|
105 |
+
if "videos" in response_data and response_data["videos"]:
|
106 |
+
video_base64 = response_data["videos"][0]["bytesBase64Encoded"]
|
107 |
video_bytes = base64.b64decode(video_base64)
|
108 |
|
109 |
temp_video_path = "generated_video.mp4"
|
|
|
113 |
yield "Status: Done! Video generated successfully.", temp_video_path
|
114 |
return
|
115 |
else:
|
|
|
|
|
116 |
error_message = "Video generation finished, but the content was blocked by safety filters or another issue prevented video creation."
|
117 |
print(f"ERROR: {error_message}")
|
118 |
raise gr.Error(error_message)
|
|
|
|
|
119 |
|
120 |
time.sleep(10)
|
121 |
|
122 |
+
raise gr.Error("Operation timed out after several minutes.")
|
123 |
|
124 |
except requests.exceptions.HTTPError as e:
|
125 |
print(f"HTTP Error: {e.response.text}")
|
126 |
raise gr.Error(f"API Error: {e.response.status_code}. Details: {e.response.text}")
|
127 |
except Exception as e:
|
|
|
128 |
print(f"An error occurred in the generation process: {e}")
|
129 |
raise gr.Error(str(e))
|
130 |
|