Update yml/avatar.py
Browse files- yml/avatar.py +71 -51
yml/avatar.py
CHANGED
|
@@ -78,6 +78,7 @@ print(f' -> User Run ID: {user_run_id}')
|
|
| 78 |
print(f' -> Target prompt: "{prompt}"')
|
| 79 |
print(f' -> Params: Seed={seed}, Res={res}, Vocal={vocal_mode}, Accel={acceleration}')
|
| 80 |
|
|
|
|
| 81 |
img_url = f"{space_url}/static/images/{user_run_id}_avatar_img.{img_ext}"
|
| 82 |
aud_url = f"{space_url}/static/images/{user_run_id}_avatar_aud.{aud_ext}"
|
| 83 |
state_url = f"{space_url}/static/images/{user_run_id}_state.pt"
|
|
@@ -87,56 +88,74 @@ local_aud = f"input_aud.{aud_ext}"
|
|
| 87 |
local_state = "input_state.pt"
|
| 88 |
|
| 89 |
print('2. Downloading assets from your Space...')
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 107 |
sys.exit(1)
|
| 108 |
|
| 109 |
-
# بررسی
|
| 110 |
has_state = False
|
| 111 |
try:
|
| 112 |
-
|
| 113 |
-
if
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
f.write(req_state.content)
|
| 119 |
-
has_state = True
|
| 120 |
-
print(' -> State file loaded successfully.')
|
| 121 |
except Exception as e:
|
| 122 |
-
print(
|
| 123 |
|
| 124 |
print('3. Connecting to LongCat-Video-Avatar-1.5 Space on ZeroGPU...')
|
| 125 |
try:
|
| 126 |
client = Client("https://opera8-longcat-video-avatar-1-5-2nd2.hf.space")
|
| 127 |
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 140 |
|
| 141 |
while not job.done():
|
| 142 |
time.sleep(5)
|
|
@@ -146,7 +165,7 @@ try:
|
|
| 146 |
state_path = result[1]
|
| 147 |
status_msg = result[2]
|
| 148 |
|
| 149 |
-
# سناریوی اول:
|
| 150 |
if video_path is not None:
|
| 151 |
print('4. Final video generated successfully! Uploading back to your Space...')
|
| 152 |
actual_video_path = video_path.get('video') or video_path.get('path') if isinstance(video_path, dict) else video_path
|
|
@@ -155,7 +174,8 @@ try:
|
|
| 155 |
res_upload = requests.post(
|
| 156 |
f'{space_url}/api/webhook/upload',
|
| 157 |
data={'run_id': user_run_id, 'github_run_id': github_run_id, 'ext': 'mp4'},
|
| 158 |
-
files={'file': f}
|
|
|
|
| 159 |
)
|
| 160 |
|
| 161 |
if res_upload.status_code == 200:
|
|
@@ -164,25 +184,26 @@ try:
|
|
| 164 |
else:
|
| 165 |
raise Exception(f"Webhook upload failed. Status code: {res_upload.status_code}")
|
| 166 |
|
| 167 |
-
# سناریوی دوم:
|
| 168 |
elif state_path is not None:
|
| 169 |
print(f"4. Timeout reached securely. State file (.pt) received. Preparing next phase...")
|
| 170 |
actual_state_path = state_path.get('path') if isinstance(state_path, dict) else state_path
|
| 171 |
|
| 172 |
-
#
|
| 173 |
with open(actual_state_path, 'rb') as f:
|
| 174 |
res_state_upload = requests.post(
|
| 175 |
f'{space_url}/api/webhook/upload',
|
| 176 |
data={'run_id': f"{user_run_id}_state", 'github_run_id': github_run_id, 'ext': 'pt'},
|
| 177 |
-
files={'file': f}
|
|
|
|
| 178 |
)
|
| 179 |
|
| 180 |
if res_state_upload.status_code == 200:
|
| 181 |
-
print(' -> State file uploaded
|
| 182 |
|
| 183 |
-
#
|
| 184 |
dispatch_payload = {
|
| 185 |
-
"prompt": raw_prompt, # ارسال دقیق همان کانفیگ اولیه
|
| 186 |
"width": 1024,
|
| 187 |
"height": 1024,
|
| 188 |
"action_name": "avatar"
|
|
@@ -194,14 +215,13 @@ try:
|
|
| 194 |
timeout=20
|
| 195 |
)
|
| 196 |
|
| 197 |
-
if trigger_res.status_code
|
| 198 |
print('5. SUCCESS! Next phase dispatched to a new Action runner.')
|
| 199 |
-
sys.exit(0) # خروج موفق
|
| 200 |
else:
|
| 201 |
raise Exception(f"Failed to trigger next phase. Server returned {trigger_res.status_code}")
|
| 202 |
else:
|
| 203 |
raise Exception(f"Failed to upload state file. Server returned {res_state_upload.status_code}")
|
| 204 |
-
|
| 205 |
else:
|
| 206 |
raise Exception(f"Unexpected result from model: {status_msg}")
|
| 207 |
|
|
|
|
| 78 |
print(f' -> Target prompt: "{prompt}"')
|
| 79 |
print(f' -> Params: Seed={seed}, Res={res}, Vocal={vocal_mode}, Accel={acceleration}')
|
| 80 |
|
| 81 |
+
# مسیر فایلها در سرور اصلی شما
|
| 82 |
img_url = f"{space_url}/static/images/{user_run_id}_avatar_img.{img_ext}"
|
| 83 |
aud_url = f"{space_url}/static/images/{user_run_id}_avatar_aud.{aud_ext}"
|
| 84 |
state_url = f"{space_url}/static/images/{user_run_id}_state.pt"
|
|
|
|
| 88 |
local_state = "input_state.pt"
|
| 89 |
|
| 90 |
print('2. Downloading assets from your Space...')
|
| 91 |
+
# دانلود عکس با تلاش مجدد
|
| 92 |
+
for att in range(3):
|
| 93 |
+
try:
|
| 94 |
+
req_img = requests.get(img_url, timeout=45)
|
| 95 |
+
if req_img.status_code == 200:
|
| 96 |
+
with open(local_img, 'wb') as f:
|
| 97 |
+
f.write(req_img.content)
|
| 98 |
+
break
|
| 99 |
+
except:
|
| 100 |
+
time.sleep(2)
|
| 101 |
+
else:
|
| 102 |
+
report_failure("Image download failed.")
|
| 103 |
+
sys.exit(1)
|
| 104 |
+
|
| 105 |
+
# دانلود صدای اصلی با تلاش مجدد
|
| 106 |
+
for att in range(3):
|
| 107 |
+
try:
|
| 108 |
+
req_aud = requests.get(aud_url, timeout=45)
|
| 109 |
+
if req_aud.status_code == 200:
|
| 110 |
+
with open(local_aud, 'wb') as f:
|
| 111 |
+
f.write(req_aud.content)
|
| 112 |
+
break
|
| 113 |
+
except:
|
| 114 |
+
time.sleep(2)
|
| 115 |
+
else:
|
| 116 |
+
report_failure("Audio download failed.")
|
| 117 |
sys.exit(1)
|
| 118 |
|
| 119 |
+
# بررسی وجود فایل پیتی (نشاندهنده این که این اکشن، ادامه اکشن قبلی است)
|
| 120 |
has_state = False
|
| 121 |
try:
|
| 122 |
+
req_state = requests.get(state_url, timeout=45)
|
| 123 |
+
if req_state.status_code == 200:
|
| 124 |
+
with open(local_state, 'wb') as f:
|
| 125 |
+
f.write(req_state.content)
|
| 126 |
+
has_state = True
|
| 127 |
+
print(' -> State file (.pt) found and loaded to resume rendering.')
|
|
|
|
|
|
|
|
|
|
| 128 |
except Exception as e:
|
| 129 |
+
print(" -> No state file found. Starting fresh generation...")
|
| 130 |
|
| 131 |
print('3. Connecting to LongCat-Video-Avatar-1.5 Space on ZeroGPU...')
|
| 132 |
try:
|
| 133 |
client = Client("https://opera8-longcat-video-avatar-1-5-2nd2.hf.space")
|
| 134 |
|
| 135 |
+
# ارتباط با اسپیس هوش مصنوعی با قابلیت تلاش مجدد
|
| 136 |
+
max_submit_retries = 3
|
| 137 |
+
job = None
|
| 138 |
+
for att in range(max_submit_retries):
|
| 139 |
+
try:
|
| 140 |
+
print(f" -> Submitting job to ZeroGPU (Attempt {att+1})...")
|
| 141 |
+
job = client.submit(
|
| 142 |
+
handle_file(local_img),
|
| 143 |
+
handle_file(local_aud),
|
| 144 |
+
prompt,
|
| 145 |
+
res,
|
| 146 |
+
seed,
|
| 147 |
+
vocal_mode,
|
| 148 |
+
acceleration,
|
| 149 |
+
handle_file(local_state) if has_state else None,
|
| 150 |
+
api_name="/generate"
|
| 151 |
+
)
|
| 152 |
+
break
|
| 153 |
+
except Exception as e:
|
| 154 |
+
print(f" -> Submission error: {e}")
|
| 155 |
+
time.sleep(5)
|
| 156 |
+
|
| 157 |
+
if not job:
|
| 158 |
+
raise Exception("Failed to connect to ZeroGPU Space after multiple attempts.")
|
| 159 |
|
| 160 |
while not job.done():
|
| 161 |
time.sleep(5)
|
|
|
|
| 165 |
state_path = result[1]
|
| 166 |
status_msg = result[2]
|
| 167 |
|
| 168 |
+
# سناریوی اول: ویدیو با موفقیت ساخته شد
|
| 169 |
if video_path is not None:
|
| 170 |
print('4. Final video generated successfully! Uploading back to your Space...')
|
| 171 |
actual_video_path = video_path.get('video') or video_path.get('path') if isinstance(video_path, dict) else video_path
|
|
|
|
| 174 |
res_upload = requests.post(
|
| 175 |
f'{space_url}/api/webhook/upload',
|
| 176 |
data={'run_id': user_run_id, 'github_run_id': github_run_id, 'ext': 'mp4'},
|
| 177 |
+
files={'file': f},
|
| 178 |
+
timeout=120
|
| 179 |
)
|
| 180 |
|
| 181 |
if res_upload.status_code == 200:
|
|
|
|
| 184 |
else:
|
| 185 |
raise Exception(f"Webhook upload failed. Status code: {res_upload.status_code}")
|
| 186 |
|
| 187 |
+
# سناریوی دوم: نشست تمام شد و فایل pt دریافت شد (هدایت به اکشن جدید)
|
| 188 |
elif state_path is not None:
|
| 189 |
print(f"4. Timeout reached securely. State file (.pt) received. Preparing next phase...")
|
| 190 |
actual_state_path = state_path.get('path') if isinstance(state_path, dict) else state_path
|
| 191 |
|
| 192 |
+
# آپلود فایل وضعیت جدید برای ذخیره در سرور اصلی
|
| 193 |
with open(actual_state_path, 'rb') as f:
|
| 194 |
res_state_upload = requests.post(
|
| 195 |
f'{space_url}/api/webhook/upload',
|
| 196 |
data={'run_id': f"{user_run_id}_state", 'github_run_id': github_run_id, 'ext': 'pt'},
|
| 197 |
+
files={'file': f},
|
| 198 |
+
timeout=120
|
| 199 |
)
|
| 200 |
|
| 201 |
if res_state_upload.status_code == 200:
|
| 202 |
+
print(' -> State file uploaded. Triggering a NEW GitHub Action runner to continue...')
|
| 203 |
|
| 204 |
+
# ارسال دستور به سرور میانی برای اجرای مجدد یک گیتهاب اکشن کاملاً جدید
|
| 205 |
dispatch_payload = {
|
| 206 |
+
"prompt": raw_prompt, # ارسال دقیق همان کانفیگ اولیه (شامل آیدی یکسان)
|
| 207 |
"width": 1024,
|
| 208 |
"height": 1024,
|
| 209 |
"action_name": "avatar"
|
|
|
|
| 215 |
timeout=20
|
| 216 |
)
|
| 217 |
|
| 218 |
+
if trigger_res.status_code in [200, 204]:
|
| 219 |
print('5. SUCCESS! Next phase dispatched to a new Action runner.')
|
| 220 |
+
sys.exit(0) # خروج کاملا موفق و بدون خطا از اکشن فعلی
|
| 221 |
else:
|
| 222 |
raise Exception(f"Failed to trigger next phase. Server returned {trigger_res.status_code}")
|
| 223 |
else:
|
| 224 |
raise Exception(f"Failed to upload state file. Server returned {res_state_upload.status_code}")
|
|
|
|
| 225 |
else:
|
| 226 |
raise Exception(f"Unexpected result from model: {status_msg}")
|
| 227 |
|