bizyengine 1.2.68__py3-none-any.whl → 1.2.69__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bizyengine/bizyair_extras/__init__.py +1 -5
- bizyengine/bizyair_extras/third_party_api/__init__.py +15 -0
- bizyengine/bizyair_extras/third_party_api/nodes_doubao.py +404 -0
- bizyengine/bizyair_extras/third_party_api/nodes_flux.py +173 -0
- bizyengine/bizyair_extras/third_party_api/nodes_gemini.py +403 -0
- bizyengine/bizyair_extras/third_party_api/nodes_gpt.py +101 -0
- bizyengine/bizyair_extras/third_party_api/nodes_hailuo.py +115 -0
- bizyengine/bizyair_extras/third_party_api/nodes_kling.py +404 -0
- bizyengine/bizyair_extras/third_party_api/nodes_sora.py +218 -0
- bizyengine/bizyair_extras/third_party_api/nodes_veo3.py +193 -0
- bizyengine/bizyair_extras/third_party_api/nodes_wan_api.py +198 -0
- bizyengine/bizyair_extras/third_party_api/trd_nodes_base.py +182 -0
- bizyengine/core/__init__.py +1 -0
- bizyengine/version.txt +1 -1
- {bizyengine-1.2.68.dist-info → bizyengine-1.2.69.dist-info}/METADATA +2 -2
- {bizyengine-1.2.68.dist-info → bizyengine-1.2.69.dist-info}/RECORD +18 -12
- bizyengine/bizyair_extras/nodes_gemini.py +0 -605
- bizyengine/bizyair_extras/nodes_seedream.py +0 -192
- bizyengine/bizyair_extras/nodes_sora2.py +0 -217
- bizyengine/bizyair_extras/nodes_veo3.py +0 -294
- bizyengine/bizyair_extras/nodes_wan_api.py +0 -299
- {bizyengine-1.2.68.dist-info → bizyengine-1.2.69.dist-info}/WHEEL +0 -0
- {bizyengine-1.2.68.dist-info → bizyengine-1.2.69.dist-info}/top_level.txt +0 -0
|
@@ -1,294 +0,0 @@
|
|
|
1
|
-
import io
|
|
2
|
-
import json
|
|
3
|
-
import logging
|
|
4
|
-
import time
|
|
5
|
-
|
|
6
|
-
import requests
|
|
7
|
-
from bizyairsdk import tensor_to_bytesio
|
|
8
|
-
from comfy_api.latest._input_impl import VideoFromFile
|
|
9
|
-
|
|
10
|
-
from bizyengine.bizyair_extras.utils.audio import save_audio
|
|
11
|
-
from bizyengine.core import BizyAirBaseNode, pop_api_key_and_prompt_id
|
|
12
|
-
from bizyengine.core.common import client
|
|
13
|
-
from bizyengine.core.common.client import send_request
|
|
14
|
-
from bizyengine.core.common.env_var import BIZYAIR_X_SERVER
|
|
15
|
-
|
|
16
|
-
from .utils.aliyun_oss import parse_upload_token, upload_file_without_sdk
|
|
17
|
-
|
|
18
|
-
_GRSAI_FAILED_STATUS = ["failed"]
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def veo_create_task_and_wait_for_completion(data, model, prompt, headers):
|
|
22
|
-
# 创建任务
|
|
23
|
-
create_task_url = f"{BIZYAIR_X_SERVER}/proxy_inference/GRSAI/{model}"
|
|
24
|
-
json_payload = json.dumps(data).encode("utf-8")
|
|
25
|
-
logging.debug(f"json_payload: {json_payload}")
|
|
26
|
-
create_api_resp = send_request(
|
|
27
|
-
url=create_task_url,
|
|
28
|
-
data=json_payload,
|
|
29
|
-
headers=headers,
|
|
30
|
-
)
|
|
31
|
-
logging.debug(f"create task api resp: {create_api_resp}")
|
|
32
|
-
|
|
33
|
-
# 检查任务创建是否成功
|
|
34
|
-
if (
|
|
35
|
-
"code" not in create_api_resp
|
|
36
|
-
or create_api_resp["code"] != 0
|
|
37
|
-
or "data" not in create_api_resp
|
|
38
|
-
or "id" not in create_api_resp["data"]
|
|
39
|
-
):
|
|
40
|
-
raise ValueError(f"Invalid response: {create_api_resp}")
|
|
41
|
-
|
|
42
|
-
# 轮询获取结果,最多等待1小时
|
|
43
|
-
task_id = create_api_resp["data"]["id"]
|
|
44
|
-
logging.info(f"Veo3.1 task created, task_id: {task_id}")
|
|
45
|
-
start_time = time.time()
|
|
46
|
-
status_url = f"{BIZYAIR_X_SERVER}/proxy_inference/GRSAI/{model}/{task_id}"
|
|
47
|
-
while time.time() - start_time < 3600:
|
|
48
|
-
time.sleep(10)
|
|
49
|
-
try:
|
|
50
|
-
status_api_resp = send_request(
|
|
51
|
-
method="GET",
|
|
52
|
-
url=status_url,
|
|
53
|
-
headers=headers,
|
|
54
|
-
)
|
|
55
|
-
logging.debug(f"status api resp: {status_api_resp}")
|
|
56
|
-
except Exception as e:
|
|
57
|
-
logging.error(f"Veo3.1 task {task_id} status api error: {e}")
|
|
58
|
-
continue
|
|
59
|
-
|
|
60
|
-
if (
|
|
61
|
-
"data" in status_api_resp
|
|
62
|
-
and "status" in status_api_resp["data"]
|
|
63
|
-
and status_api_resp["data"]["status"] == "succeeded"
|
|
64
|
-
and "url" in status_api_resp["data"]
|
|
65
|
-
and status_api_resp["data"]["url"]
|
|
66
|
-
):
|
|
67
|
-
video_url = status_api_resp["data"]["url"]
|
|
68
|
-
logging.info(f"Veo3.1 task {task_id} success, video_url: {video_url}")
|
|
69
|
-
# 下载视频
|
|
70
|
-
video_resp = requests.get(video_url, stream=True, timeout=3600)
|
|
71
|
-
video_resp.raise_for_status() # 非 2xx 会抛异常
|
|
72
|
-
return (VideoFromFile(io.BytesIO(video_resp.content)),)
|
|
73
|
-
if (
|
|
74
|
-
"data" not in status_api_resp
|
|
75
|
-
or "status" not in status_api_resp["data"]
|
|
76
|
-
or "code" not in status_api_resp
|
|
77
|
-
or status_api_resp["code"] != 0
|
|
78
|
-
):
|
|
79
|
-
raise ValueError(f"Invalid response: {status_api_resp}")
|
|
80
|
-
if status_api_resp["data"]["status"] in _GRSAI_FAILED_STATUS:
|
|
81
|
-
raise ValueError(f"Veo3.1 task failed: {status_api_resp}")
|
|
82
|
-
logging.debug(
|
|
83
|
-
f"Veo3.1 task {task_id} status: {status_api_resp['data']['status']}"
|
|
84
|
-
)
|
|
85
|
-
|
|
86
|
-
raise ValueError(f"Veo3.1 task timed out, request ID: {task_id}")
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
class Veo_V3_1_I2V_API(BizyAirBaseNode):
|
|
90
|
-
@classmethod
|
|
91
|
-
def INPUT_TYPES(cls):
|
|
92
|
-
return {
|
|
93
|
-
"required": {
|
|
94
|
-
"prompt": (
|
|
95
|
-
"STRING",
|
|
96
|
-
{
|
|
97
|
-
"multiline": True,
|
|
98
|
-
"default": "",
|
|
99
|
-
},
|
|
100
|
-
),
|
|
101
|
-
"first_frame_image": ("IMAGE", {"tooltip": "首帧图片"}),
|
|
102
|
-
"model": (["veo3.1-fast", "veo3.1-pro"], {"default": "veo3.1-fast"}),
|
|
103
|
-
},
|
|
104
|
-
"optional": {
|
|
105
|
-
"last_frame_image": ("IMAGE", {"tooltip": "尾帧图片"}),
|
|
106
|
-
"aspect_ratio": (
|
|
107
|
-
["9:16", "16:9"],
|
|
108
|
-
{"default": "16:9"},
|
|
109
|
-
),
|
|
110
|
-
},
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
NODE_DISPLAY_NAME = "Veo3.1 Image To Video"
|
|
114
|
-
RETURN_TYPES = ("VIDEO",)
|
|
115
|
-
RETURN_NAMES = ("video",)
|
|
116
|
-
CATEGORY = "☁️BizyAir/External APIs/Veo"
|
|
117
|
-
FUNCTION = "api_call"
|
|
118
|
-
|
|
119
|
-
def api_call(self, first_frame_image, model, prompt, **kwargs):
|
|
120
|
-
extra_data = pop_api_key_and_prompt_id(kwargs)
|
|
121
|
-
headers = client.headers(api_key=extra_data["api_key"])
|
|
122
|
-
prompt_id = extra_data["prompt_id"]
|
|
123
|
-
headers["X-BIZYAIR-PROMPT-ID"] = prompt_id
|
|
124
|
-
headers["X-Bizyair-Async-Result"] = "enable"
|
|
125
|
-
|
|
126
|
-
# 参数
|
|
127
|
-
aspect_ratio = kwargs.get("aspect_ratio", "16:9")
|
|
128
|
-
last_frame_image = kwargs.get("last_frame_image", None)
|
|
129
|
-
|
|
130
|
-
input = {
|
|
131
|
-
"webHook": "-1",
|
|
132
|
-
"aspectRatio": aspect_ratio,
|
|
133
|
-
"model": model,
|
|
134
|
-
}
|
|
135
|
-
if prompt is not None and prompt.strip() != "":
|
|
136
|
-
input["prompt"] = prompt
|
|
137
|
-
else:
|
|
138
|
-
raise ValueError("Prompt is required")
|
|
139
|
-
|
|
140
|
-
# 上传图片
|
|
141
|
-
if first_frame_image is not None:
|
|
142
|
-
oss_token_url = f"{BIZYAIR_X_SERVER}/upload/token?file_name={prompt_id}_first.png&file_type=inputs"
|
|
143
|
-
token_resp = send_request("GET", oss_token_url, headers=headers)
|
|
144
|
-
auth_info = parse_upload_token(token_resp)
|
|
145
|
-
input["firstFrameUrl"] = upload_file_without_sdk(
|
|
146
|
-
tensor_to_bytesio(first_frame_image), **auth_info
|
|
147
|
-
)
|
|
148
|
-
if last_frame_image is not None:
|
|
149
|
-
oss_token_url = f"{BIZYAIR_X_SERVER}/upload/token?file_name={prompt_id}_last.png&file_type=inputs"
|
|
150
|
-
token_resp = send_request("GET", oss_token_url, headers=headers)
|
|
151
|
-
auth_info = parse_upload_token(token_resp)
|
|
152
|
-
input["lastFrameUrl"] = upload_file_without_sdk(
|
|
153
|
-
tensor_to_bytesio(last_frame_image), **auth_info
|
|
154
|
-
)
|
|
155
|
-
|
|
156
|
-
# 调用API
|
|
157
|
-
return veo_create_task_and_wait_for_completion(
|
|
158
|
-
data=input, model=model, prompt=prompt, headers=headers
|
|
159
|
-
)
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
class Veo_V3_1_I2V_REF_API(BizyAirBaseNode):
|
|
163
|
-
@classmethod
|
|
164
|
-
def INPUT_TYPES(cls):
|
|
165
|
-
return {
|
|
166
|
-
"required": {
|
|
167
|
-
"prompt": (
|
|
168
|
-
"STRING",
|
|
169
|
-
{
|
|
170
|
-
"multiline": True,
|
|
171
|
-
"default": "",
|
|
172
|
-
},
|
|
173
|
-
),
|
|
174
|
-
"ref_image_1": ("IMAGE", {"tooltip": "参考图片1"}),
|
|
175
|
-
"model": (["veo3.1-fast"], {"default": "veo3.1-fast"}),
|
|
176
|
-
},
|
|
177
|
-
"optional": {
|
|
178
|
-
"ref_image_2": ("IMAGE", {"tooltip": "参考图片2"}),
|
|
179
|
-
"ref_image_3": ("IMAGE", {"tooltip": "参考图片3"}),
|
|
180
|
-
"aspect_ratio": (["16:9"], {"default": "16:9"}),
|
|
181
|
-
},
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
NODE_DISPLAY_NAME = "Veo3.1 Image To Video (Reference Images)"
|
|
185
|
-
RETURN_TYPES = ("VIDEO",)
|
|
186
|
-
RETURN_NAMES = ("video",)
|
|
187
|
-
CATEGORY = "☁️BizyAir/External APIs/Veo"
|
|
188
|
-
FUNCTION = "api_call"
|
|
189
|
-
|
|
190
|
-
def api_call(self, ref_image_1, model, prompt, **kwargs):
|
|
191
|
-
extra_data = pop_api_key_and_prompt_id(kwargs)
|
|
192
|
-
headers = client.headers(api_key=extra_data["api_key"])
|
|
193
|
-
prompt_id = extra_data["prompt_id"]
|
|
194
|
-
headers["X-BIZYAIR-PROMPT-ID"] = prompt_id
|
|
195
|
-
headers["X-Bizyair-Async-Result"] = "enable"
|
|
196
|
-
|
|
197
|
-
# 参数
|
|
198
|
-
aspect_ratio = kwargs.get("aspect_ratio", "16:9")
|
|
199
|
-
ref_image_2 = kwargs.get("ref_image_2", None)
|
|
200
|
-
ref_image_3 = kwargs.get("ref_image_3", None)
|
|
201
|
-
|
|
202
|
-
input = {
|
|
203
|
-
"webHook": "-1",
|
|
204
|
-
"aspectRatio": aspect_ratio,
|
|
205
|
-
"model": model,
|
|
206
|
-
}
|
|
207
|
-
if prompt is not None and prompt.strip() != "":
|
|
208
|
-
input["prompt"] = prompt
|
|
209
|
-
else:
|
|
210
|
-
raise ValueError("Prompt is required")
|
|
211
|
-
|
|
212
|
-
# 上传图片
|
|
213
|
-
ref_images = []
|
|
214
|
-
if ref_image_1 is not None:
|
|
215
|
-
oss_token_url = f"{BIZYAIR_X_SERVER}/upload/token?file_name={prompt_id}_ref_1.png&file_type=inputs"
|
|
216
|
-
token_resp = send_request("GET", oss_token_url, headers=headers)
|
|
217
|
-
auth_info = parse_upload_token(token_resp)
|
|
218
|
-
ref_images.append(
|
|
219
|
-
upload_file_without_sdk(tensor_to_bytesio(ref_image_1), **auth_info)
|
|
220
|
-
)
|
|
221
|
-
if ref_image_2 is not None:
|
|
222
|
-
oss_token_url = f"{BIZYAIR_X_SERVER}/upload/token?file_name={prompt_id}_ref_2.png&file_type=inputs"
|
|
223
|
-
token_resp = send_request("GET", oss_token_url, headers=headers)
|
|
224
|
-
auth_info = parse_upload_token(token_resp)
|
|
225
|
-
ref_images.append(
|
|
226
|
-
upload_file_without_sdk(tensor_to_bytesio(ref_image_2), **auth_info)
|
|
227
|
-
)
|
|
228
|
-
if ref_image_3 is not None:
|
|
229
|
-
oss_token_url = f"{BIZYAIR_X_SERVER}/upload/token?file_name={prompt_id}_ref_3.png&file_type=inputs"
|
|
230
|
-
token_resp = send_request("GET", oss_token_url, headers=headers)
|
|
231
|
-
auth_info = parse_upload_token(token_resp)
|
|
232
|
-
ref_images.append(
|
|
233
|
-
upload_file_without_sdk(tensor_to_bytesio(ref_image_3), **auth_info)
|
|
234
|
-
)
|
|
235
|
-
input["urls"] = ref_images
|
|
236
|
-
|
|
237
|
-
# 调用API
|
|
238
|
-
return veo_create_task_and_wait_for_completion(
|
|
239
|
-
data=input, model=model, prompt=prompt, headers=headers
|
|
240
|
-
)
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
class Veo_V3_1_T2V_API(BizyAirBaseNode):
|
|
244
|
-
@classmethod
|
|
245
|
-
def INPUT_TYPES(cls):
|
|
246
|
-
return {
|
|
247
|
-
"required": {
|
|
248
|
-
"prompt": (
|
|
249
|
-
"STRING",
|
|
250
|
-
{
|
|
251
|
-
"multiline": True,
|
|
252
|
-
"default": "",
|
|
253
|
-
},
|
|
254
|
-
),
|
|
255
|
-
"model": (["veo3.1-fast", "veo3.1-pro"], {"default": "veo3.1-fast"}),
|
|
256
|
-
},
|
|
257
|
-
"optional": {
|
|
258
|
-
"aspect_ratio": (
|
|
259
|
-
["9:16", "16:9"],
|
|
260
|
-
{"default": "16:9"},
|
|
261
|
-
),
|
|
262
|
-
},
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
NODE_DISPLAY_NAME = "Veo3.1 Text To Video"
|
|
266
|
-
RETURN_TYPES = ("VIDEO",)
|
|
267
|
-
RETURN_NAMES = ("video",)
|
|
268
|
-
CATEGORY = "☁️BizyAir/External APIs/Veo"
|
|
269
|
-
FUNCTION = "api_call"
|
|
270
|
-
|
|
271
|
-
def api_call(self, prompt, model, **kwargs):
|
|
272
|
-
extra_data = pop_api_key_and_prompt_id(kwargs)
|
|
273
|
-
headers = client.headers(api_key=extra_data["api_key"])
|
|
274
|
-
prompt_id = extra_data["prompt_id"]
|
|
275
|
-
headers["X-BIZYAIR-PROMPT-ID"] = prompt_id
|
|
276
|
-
headers["X-Bizyair-Async-Result"] = "enable"
|
|
277
|
-
|
|
278
|
-
# 参数
|
|
279
|
-
aspect_ratio = kwargs.get("aspect_ratio", "16:9")
|
|
280
|
-
|
|
281
|
-
input = {
|
|
282
|
-
"webHook": "-1",
|
|
283
|
-
"aspectRatio": aspect_ratio,
|
|
284
|
-
"model": model,
|
|
285
|
-
}
|
|
286
|
-
if prompt is not None and prompt.strip() != "":
|
|
287
|
-
input["prompt"] = prompt
|
|
288
|
-
else:
|
|
289
|
-
raise ValueError("Prompt is required")
|
|
290
|
-
|
|
291
|
-
# 调用API
|
|
292
|
-
return veo_create_task_and_wait_for_completion(
|
|
293
|
-
data=input, model=model, prompt=prompt, headers=headers
|
|
294
|
-
)
|
|
@@ -1,299 +0,0 @@
|
|
|
1
|
-
import io
|
|
2
|
-
import json
|
|
3
|
-
import logging
|
|
4
|
-
import time
|
|
5
|
-
|
|
6
|
-
import requests
|
|
7
|
-
from bizyairsdk import tensor_to_bytesio
|
|
8
|
-
from comfy_api.latest._input_impl import VideoFromFile
|
|
9
|
-
|
|
10
|
-
from bizyengine.bizyair_extras.utils.audio import save_audio
|
|
11
|
-
from bizyengine.core import BizyAirBaseNode, pop_api_key_and_prompt_id
|
|
12
|
-
from bizyengine.core.common import client
|
|
13
|
-
from bizyengine.core.common.client import send_request
|
|
14
|
-
from bizyengine.core.common.env_var import BIZYAIR_X_SERVER
|
|
15
|
-
|
|
16
|
-
from .utils.aliyun_oss import parse_upload_token, upload_file_without_sdk
|
|
17
|
-
|
|
18
|
-
_FAILED_STATUS = ["FAILED", "CANCELED", "UNKNOWN"]
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def wan_create_task_and_wait_for_completion(data, model, prompt, headers):
|
|
22
|
-
# 创建任务
|
|
23
|
-
create_task_url = f"{BIZYAIR_X_SERVER}/proxy_inference/Wan/{model}"
|
|
24
|
-
json_payload = json.dumps(data).encode("utf-8")
|
|
25
|
-
logging.debug(f"json_payload: {json_payload}")
|
|
26
|
-
create_api_resp = send_request(
|
|
27
|
-
url=create_task_url,
|
|
28
|
-
data=json_payload,
|
|
29
|
-
headers=headers,
|
|
30
|
-
)
|
|
31
|
-
logging.debug(f"create task api resp: {create_api_resp}")
|
|
32
|
-
|
|
33
|
-
# 检查任务创建是否成功
|
|
34
|
-
if (
|
|
35
|
-
"request_id" not in create_api_resp
|
|
36
|
-
or "output" not in create_api_resp
|
|
37
|
-
or "task_status" not in create_api_resp["output"]
|
|
38
|
-
or "task_id" not in create_api_resp["output"]
|
|
39
|
-
):
|
|
40
|
-
raise ValueError(f"Invalid response: {create_api_resp}")
|
|
41
|
-
# 检查任务状态,是否已经报错,如果报错则抛出异常
|
|
42
|
-
if create_api_resp["output"]["task_status"] in _FAILED_STATUS:
|
|
43
|
-
raise ValueError(f"Wan2.5 create task failed: {create_api_resp}")
|
|
44
|
-
|
|
45
|
-
# 轮询获取结果,最多等待1小时
|
|
46
|
-
task_id = create_api_resp["output"]["task_id"]
|
|
47
|
-
logging.info(
|
|
48
|
-
f'Wan2.5 task created, task_id: {task_id}, request_id: {create_api_resp["request_id"]}'
|
|
49
|
-
)
|
|
50
|
-
start_time = time.time()
|
|
51
|
-
status_url = f"{BIZYAIR_X_SERVER}/proxy_inference/Wan/{model}/{task_id}"
|
|
52
|
-
while time.time() - start_time < 3600:
|
|
53
|
-
time.sleep(10)
|
|
54
|
-
try:
|
|
55
|
-
status_api_resp = send_request(
|
|
56
|
-
method="GET",
|
|
57
|
-
url=status_url,
|
|
58
|
-
headers=headers,
|
|
59
|
-
)
|
|
60
|
-
except Exception as e:
|
|
61
|
-
logging.error(f"Wan2.5 task {task_id} status api error: {e}")
|
|
62
|
-
continue
|
|
63
|
-
|
|
64
|
-
if "output" in status_api_resp and "video_url" in status_api_resp["output"]:
|
|
65
|
-
video_url = status_api_resp["output"]["video_url"]
|
|
66
|
-
logging.info(f"Wan2.5 task {task_id} success, video_url: {video_url}")
|
|
67
|
-
actual_prompt = status_api_resp["output"].get("actual_prompt", prompt)
|
|
68
|
-
# 下载视频
|
|
69
|
-
video_resp = requests.get(video_url, stream=True, timeout=3600)
|
|
70
|
-
video_resp.raise_for_status() # 非 2xx 会抛异常
|
|
71
|
-
return (VideoFromFile(io.BytesIO(video_resp.content)), actual_prompt)
|
|
72
|
-
if (
|
|
73
|
-
"output" not in status_api_resp
|
|
74
|
-
or "task_status" not in status_api_resp["output"]
|
|
75
|
-
):
|
|
76
|
-
raise ValueError(f"Invalid response: {status_api_resp}")
|
|
77
|
-
if status_api_resp["output"]["task_status"] in _FAILED_STATUS:
|
|
78
|
-
raise ValueError(f"Wan2.5 task failed: {status_api_resp}")
|
|
79
|
-
logging.debug(
|
|
80
|
-
f"Wan2.5 task {task_id} status: {status_api_resp['output']['task_status']}"
|
|
81
|
-
)
|
|
82
|
-
|
|
83
|
-
raise ValueError(f"Wan2.5 task timed out, request ID: {task_id}")
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
class Wan_V2_5_I2V_API(BizyAirBaseNode):
|
|
87
|
-
@classmethod
|
|
88
|
-
def INPUT_TYPES(cls):
|
|
89
|
-
return {
|
|
90
|
-
"required": {
|
|
91
|
-
"image": ("IMAGE",),
|
|
92
|
-
},
|
|
93
|
-
"optional": {
|
|
94
|
-
"audio": ("AUDIO",),
|
|
95
|
-
"prompt": (
|
|
96
|
-
"STRING",
|
|
97
|
-
{
|
|
98
|
-
"multiline": True,
|
|
99
|
-
"default": "",
|
|
100
|
-
},
|
|
101
|
-
),
|
|
102
|
-
"negative_prompt": (
|
|
103
|
-
"STRING",
|
|
104
|
-
{
|
|
105
|
-
"multiline": True,
|
|
106
|
-
"default": "",
|
|
107
|
-
},
|
|
108
|
-
),
|
|
109
|
-
"resolution": (
|
|
110
|
-
["480P", "720P", "1080P"],
|
|
111
|
-
{"default": "1080P"},
|
|
112
|
-
),
|
|
113
|
-
"duration": ([5, 10], {"default": 5}),
|
|
114
|
-
"prompt_extend": (
|
|
115
|
-
"BOOLEAN",
|
|
116
|
-
{
|
|
117
|
-
"default": True,
|
|
118
|
-
"tooltip": "是否开启prompt智能改写。开启后使用大模型对输入prompt进行智能改写。对于较短的prompt生成效果提升明显,但会增加耗时。",
|
|
119
|
-
},
|
|
120
|
-
),
|
|
121
|
-
"auto_audio": (
|
|
122
|
-
"BOOLEAN",
|
|
123
|
-
{
|
|
124
|
-
"default": True,
|
|
125
|
-
"tooltip": "是否由模型自动生成声音,优先级低于audio参数。",
|
|
126
|
-
},
|
|
127
|
-
),
|
|
128
|
-
},
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
NODE_DISPLAY_NAME = "Wan2.5 Image To Video"
|
|
132
|
-
RETURN_TYPES = ("VIDEO", "STRING")
|
|
133
|
-
RETURN_NAMES = ("video", "actual_prompt")
|
|
134
|
-
CATEGORY = "☁️BizyAir/External APIs/WanVideo"
|
|
135
|
-
FUNCTION = "api_call"
|
|
136
|
-
|
|
137
|
-
def api_call(self, image, **kwargs):
|
|
138
|
-
extra_data = pop_api_key_and_prompt_id(kwargs)
|
|
139
|
-
headers = client.headers(api_key=extra_data["api_key"])
|
|
140
|
-
prompt_id = extra_data["prompt_id"]
|
|
141
|
-
headers["X-BIZYAIR-PROMPT-ID"] = prompt_id
|
|
142
|
-
headers["X-Bizyair-Async-Result"] = "enable"
|
|
143
|
-
|
|
144
|
-
# 参数
|
|
145
|
-
prompt = kwargs.get("prompt", "")
|
|
146
|
-
negative_prompt = kwargs.get("negative_prompt", "")
|
|
147
|
-
audio = kwargs.get("audio", None)
|
|
148
|
-
resolution = kwargs.get("resolution", "1080P")
|
|
149
|
-
duration = kwargs.get("duration", 5)
|
|
150
|
-
prompt_extend = kwargs.get("prompt_extend", True)
|
|
151
|
-
auto_audio = kwargs.get("auto_audio", True)
|
|
152
|
-
|
|
153
|
-
input = {}
|
|
154
|
-
if prompt is not None and prompt.strip() != "":
|
|
155
|
-
input["prompt"] = prompt
|
|
156
|
-
if negative_prompt is not None and negative_prompt.strip() != "":
|
|
157
|
-
input["negative_prompt"] = negative_prompt
|
|
158
|
-
|
|
159
|
-
# 上传图片&音频
|
|
160
|
-
if image is not None:
|
|
161
|
-
oss_token_url = f"{BIZYAIR_X_SERVER}/upload/token?file_name={prompt_id}.png&file_type=inputs"
|
|
162
|
-
token_resp = send_request("GET", oss_token_url, headers=headers)
|
|
163
|
-
auth_info = parse_upload_token(token_resp)
|
|
164
|
-
input["img_url"] = upload_file_without_sdk(
|
|
165
|
-
tensor_to_bytesio(image), **auth_info
|
|
166
|
-
)
|
|
167
|
-
if audio is not None:
|
|
168
|
-
oss_token_url = f"{BIZYAIR_X_SERVER}/upload/token?file_name={prompt_id}.flac&file_type=inputs"
|
|
169
|
-
token_resp = send_request("GET", oss_token_url, headers=headers)
|
|
170
|
-
auth_info = parse_upload_token(token_resp)
|
|
171
|
-
audio_bytes = save_audio(audio)
|
|
172
|
-
input["audio_url"] = upload_file_without_sdk(audio_bytes, **auth_info)
|
|
173
|
-
|
|
174
|
-
# 调用API
|
|
175
|
-
model = "wan2.5-i2v-preview"
|
|
176
|
-
data = {
|
|
177
|
-
"model": model,
|
|
178
|
-
"input": input,
|
|
179
|
-
"parameters": {
|
|
180
|
-
"resolution": resolution,
|
|
181
|
-
"prompt_extend": prompt_extend,
|
|
182
|
-
"duration": duration,
|
|
183
|
-
"audio": auto_audio,
|
|
184
|
-
},
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
return wan_create_task_and_wait_for_completion(
|
|
188
|
-
data=data, model=model, prompt=prompt, headers=headers
|
|
189
|
-
)
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
class Wan_V2_5_T2V_API(BizyAirBaseNode):
|
|
193
|
-
@classmethod
|
|
194
|
-
def INPUT_TYPES(cls):
|
|
195
|
-
return {
|
|
196
|
-
"required": {
|
|
197
|
-
"prompt": (
|
|
198
|
-
"STRING",
|
|
199
|
-
{
|
|
200
|
-
"multiline": True,
|
|
201
|
-
"default": "",
|
|
202
|
-
},
|
|
203
|
-
),
|
|
204
|
-
},
|
|
205
|
-
"optional": {
|
|
206
|
-
"audio": ("AUDIO",),
|
|
207
|
-
"negative_prompt": (
|
|
208
|
-
"STRING",
|
|
209
|
-
{
|
|
210
|
-
"multiline": True,
|
|
211
|
-
"default": "",
|
|
212
|
-
},
|
|
213
|
-
),
|
|
214
|
-
"size": (
|
|
215
|
-
[
|
|
216
|
-
"832*480",
|
|
217
|
-
"480*832",
|
|
218
|
-
"624*624",
|
|
219
|
-
"1280*720",
|
|
220
|
-
"720*1280",
|
|
221
|
-
"960*960",
|
|
222
|
-
"1088*832",
|
|
223
|
-
"832*1088",
|
|
224
|
-
"1920*1080",
|
|
225
|
-
"1080*1920",
|
|
226
|
-
"1440*1440",
|
|
227
|
-
"1632*1248",
|
|
228
|
-
"1248*1632",
|
|
229
|
-
],
|
|
230
|
-
{"default": "1920*1080"},
|
|
231
|
-
),
|
|
232
|
-
"duration": ([5, 10], {"default": 5}),
|
|
233
|
-
"prompt_extend": (
|
|
234
|
-
"BOOLEAN",
|
|
235
|
-
{
|
|
236
|
-
"default": True,
|
|
237
|
-
"tooltip": "是否开启prompt智能改写。开启后使用大模型对输入prompt进行智能改写。对于较短的prompt生成效果提升明显,但会增加耗时。",
|
|
238
|
-
},
|
|
239
|
-
),
|
|
240
|
-
"auto_audio": (
|
|
241
|
-
"BOOLEAN",
|
|
242
|
-
{
|
|
243
|
-
"default": True,
|
|
244
|
-
"tooltip": "是否由模型自动生成声音,优先级低于audio参数。",
|
|
245
|
-
},
|
|
246
|
-
),
|
|
247
|
-
},
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
NODE_DISPLAY_NAME = "Wan2.5 Text To Video"
|
|
251
|
-
RETURN_TYPES = ("VIDEO", "STRING")
|
|
252
|
-
RETURN_NAMES = ("video", "actual_prompt")
|
|
253
|
-
CATEGORY = "☁️BizyAir/External APIs/WanVideo"
|
|
254
|
-
FUNCTION = "api_call"
|
|
255
|
-
|
|
256
|
-
def api_call(self, prompt, **kwargs):
|
|
257
|
-
extra_data = pop_api_key_and_prompt_id(kwargs)
|
|
258
|
-
headers = client.headers(api_key=extra_data["api_key"])
|
|
259
|
-
prompt_id = extra_data["prompt_id"]
|
|
260
|
-
headers["X-BIZYAIR-PROMPT-ID"] = prompt_id
|
|
261
|
-
headers["X-Bizyair-Async-Result"] = "enable"
|
|
262
|
-
|
|
263
|
-
# 参数
|
|
264
|
-
negative_prompt = kwargs.get("negative_prompt", "")
|
|
265
|
-
audio = kwargs.get("audio", None)
|
|
266
|
-
size = kwargs.get("size", "1920*1080")
|
|
267
|
-
duration = kwargs.get("duration", 5)
|
|
268
|
-
prompt_extend = kwargs.get("prompt_extend", True)
|
|
269
|
-
auto_audio = kwargs.get("auto_audio", True)
|
|
270
|
-
|
|
271
|
-
input = {}
|
|
272
|
-
if prompt is not None and prompt.strip() != "":
|
|
273
|
-
input["prompt"] = prompt
|
|
274
|
-
if negative_prompt is not None and negative_prompt.strip() != "":
|
|
275
|
-
input["negative_prompt"] = negative_prompt
|
|
276
|
-
|
|
277
|
-
# 上传音频
|
|
278
|
-
if audio is not None:
|
|
279
|
-
oss_token_url = f"{BIZYAIR_X_SERVER}/upload/token?file_name={prompt_id}.flac&file_type=inputs"
|
|
280
|
-
token_resp = send_request("GET", oss_token_url, headers=headers)
|
|
281
|
-
auth_info = parse_upload_token(token_resp)
|
|
282
|
-
audio_bytes = save_audio(audio)
|
|
283
|
-
input["audio_url"] = upload_file_without_sdk(audio_bytes, **auth_info)
|
|
284
|
-
|
|
285
|
-
# 调用API
|
|
286
|
-
model = "wan2.5-t2v-preview"
|
|
287
|
-
data = {
|
|
288
|
-
"model": model,
|
|
289
|
-
"input": input,
|
|
290
|
-
"parameters": {
|
|
291
|
-
"size": size,
|
|
292
|
-
"prompt_extend": prompt_extend,
|
|
293
|
-
"duration": duration,
|
|
294
|
-
"audio": auto_audio,
|
|
295
|
-
},
|
|
296
|
-
}
|
|
297
|
-
return wan_create_task_and_wait_for_completion(
|
|
298
|
-
data=data, model=model, prompt=prompt, headers=headers
|
|
299
|
-
)
|
|
File without changes
|
|
File without changes
|