bizyengine 1.2.58__py3-none-any.whl → 1.2.71__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/bizy_server/server.py +2 -2
- bizyengine/bizy_server/utils.py +3 -0
- bizyengine/bizyair_extras/__init__.py +1 -3
- bizyengine/bizyair_extras/third_party_api/__init__.py +15 -0
- bizyengine/bizyair_extras/third_party_api/nodes_doubao.py +535 -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 +183 -0
- bizyengine/bizyair_extras/utils/aliyun_oss.py +17 -0
- bizyengine/core/__init__.py +1 -0
- bizyengine/core/commands/servers/prompt_server.py +10 -1
- bizyengine/version.txt +1 -1
- {bizyengine-1.2.58.dist-info → bizyengine-1.2.71.dist-info}/METADATA +3 -3
- {bizyengine-1.2.58.dist-info → bizyengine-1.2.71.dist-info}/RECORD +22 -14
- bizyengine/bizyair_extras/nodes_gemini.py +0 -311
- bizyengine/bizyair_extras/nodes_seedream.py +0 -195
- bizyengine/bizyair_extras/nodes_wan_api.py +0 -291
- {bizyengine-1.2.58.dist-info → bizyengine-1.2.71.dist-info}/WHEEL +0 -0
- {bizyengine-1.2.58.dist-info → bizyengine-1.2.71.dist-info}/top_level.txt +0 -0
bizyengine/bizy_server/server.py
CHANGED
|
@@ -871,7 +871,7 @@ class BizyAirServer:
|
|
|
871
871
|
),
|
|
872
872
|
"bizyait-image-gen": MCPServerConfig(
|
|
873
873
|
transport="streamable_http",
|
|
874
|
-
url="https://api.bizyair.cn/w/v1/mcp/
|
|
874
|
+
url="https://api.bizyair.cn/w/v1/mcp/67",
|
|
875
875
|
headers={
|
|
876
876
|
"Authorization": "Bearer " + api_key,
|
|
877
877
|
"X-BizyBot-Client": "bizybot",
|
|
@@ -879,7 +879,7 @@ class BizyAirServer:
|
|
|
879
879
|
),
|
|
880
880
|
"bizyait-image-edit": MCPServerConfig(
|
|
881
881
|
transport="streamable_http",
|
|
882
|
-
url="https://api.bizyair.cn/w/v1/mcp/
|
|
882
|
+
url="https://api.bizyair.cn/w/v1/mcp/68",
|
|
883
883
|
headers={
|
|
884
884
|
"Authorization": "Bearer " + api_key,
|
|
885
885
|
"X-BizyBot-Client": "bizybot",
|
bizyengine/bizy_server/utils.py
CHANGED
|
@@ -127,6 +127,9 @@ def is_allow_ext_name(local_file_name):
|
|
|
127
127
|
def decrypt_apikey(apikey_ciphertext):
|
|
128
128
|
if not BIZYAIR_SERVER_MODE_RSA_PRIVATE_KEY_PATH:
|
|
129
129
|
return apikey_ciphertext, None
|
|
130
|
+
# v4.public开头不用解密
|
|
131
|
+
if apikey_ciphertext.startswith("v4.public"):
|
|
132
|
+
return apikey_ciphertext, None
|
|
130
133
|
global _RSA_CIPHER
|
|
131
134
|
if not _RSA_CIPHER:
|
|
132
135
|
with open(BIZYAIR_SERVER_MODE_RSA_PRIVATE_KEY_PATH, "rb") as f:
|
|
@@ -10,7 +10,6 @@ modules = [
|
|
|
10
10
|
".nodes_dataset",
|
|
11
11
|
".nodes_differential_diffusion",
|
|
12
12
|
".nodes_flux",
|
|
13
|
-
".nodes_gemini",
|
|
14
13
|
".nodes_hunyuan3d",
|
|
15
14
|
".nodes_image_utils",
|
|
16
15
|
".nodes_ip2p",
|
|
@@ -22,17 +21,16 @@ modules = [
|
|
|
22
21
|
".nodes_reactor",
|
|
23
22
|
".nodes_sam2",
|
|
24
23
|
".nodes_sd3",
|
|
25
|
-
".nodes_seedream",
|
|
26
24
|
".nodes_segment_anything",
|
|
27
25
|
".nodes_testing_utils",
|
|
28
26
|
".nodes_trellis",
|
|
29
27
|
".nodes_ultimatesdupscale",
|
|
30
28
|
".nodes_upscale_model",
|
|
31
29
|
".nodes_utils",
|
|
32
|
-
".nodes_wan_api",
|
|
33
30
|
".nodes_wan_i2v",
|
|
34
31
|
".nodes_wan_video",
|
|
35
32
|
".route_bizyair_tools",
|
|
33
|
+
".third_party_api",
|
|
36
34
|
]
|
|
37
35
|
from bizyengine.core.common.utils import safe_star_import
|
|
38
36
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
modules = [
|
|
2
|
+
".nodes_hailuo",
|
|
3
|
+
".nodes_gemini",
|
|
4
|
+
".nodes_gpt",
|
|
5
|
+
".nodes_kling",
|
|
6
|
+
".nodes_doubao",
|
|
7
|
+
".nodes_flux",
|
|
8
|
+
".nodes_sora",
|
|
9
|
+
".nodes_veo3",
|
|
10
|
+
".nodes_wan_api",
|
|
11
|
+
]
|
|
12
|
+
from bizyengine.core.common.utils import safe_star_import
|
|
13
|
+
|
|
14
|
+
for mod in modules:
|
|
15
|
+
safe_star_import(mod, package=__package__)
|
|
@@ -0,0 +1,535 @@
|
|
|
1
|
+
from bizyairsdk import tensor_to_bytesio
|
|
2
|
+
|
|
3
|
+
from .trd_nodes_base import BizyAirTrdApiBaseNode
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Seedream4(BizyAirTrdApiBaseNode):
|
|
7
|
+
RETURN_TYPES = ("IMAGE",)
|
|
8
|
+
RETURN_NAMES = ("images",)
|
|
9
|
+
CATEGORY = "☁️BizyAir/External APIs/Doubao"
|
|
10
|
+
NODE_DISPLAY_NAME = "Seedream4"
|
|
11
|
+
|
|
12
|
+
@classmethod
|
|
13
|
+
def INPUT_TYPES(s):
|
|
14
|
+
return {
|
|
15
|
+
"required": {
|
|
16
|
+
"prompt": (
|
|
17
|
+
"STRING",
|
|
18
|
+
{
|
|
19
|
+
"multiline": True,
|
|
20
|
+
"default": "",
|
|
21
|
+
},
|
|
22
|
+
),
|
|
23
|
+
"size": (
|
|
24
|
+
[
|
|
25
|
+
"1K Square (1024x1024)",
|
|
26
|
+
"2K Square (2048x2048)",
|
|
27
|
+
"4K Square (4096x4096)",
|
|
28
|
+
"HD 16:9 (1920x1080)",
|
|
29
|
+
"2K 16:9 (2560x1440)",
|
|
30
|
+
"4K 16:9 (3840x2160)",
|
|
31
|
+
"Portrait 9:16 (1080x1920)",
|
|
32
|
+
"Portrait 3:4 (1536x2048)",
|
|
33
|
+
"Landscape 4:3 (2048x1536)",
|
|
34
|
+
"Ultra-wide 21:9 (3440x1440)",
|
|
35
|
+
"Custom",
|
|
36
|
+
],
|
|
37
|
+
{
|
|
38
|
+
"default": "HD 16:9 (1920x1080)",
|
|
39
|
+
},
|
|
40
|
+
),
|
|
41
|
+
"custom_width": ("INT", {"default": 1920, "min": 1024, "max": 4096}),
|
|
42
|
+
"custom_height": ("INT", {"default": 1080, "min": 1024, "max": 4096}),
|
|
43
|
+
"model": (
|
|
44
|
+
["doubao-seedream-4-0-250828"],
|
|
45
|
+
{"default": "doubao-seedream-4-0-250828"},
|
|
46
|
+
),
|
|
47
|
+
},
|
|
48
|
+
"optional": {
|
|
49
|
+
"image": ("IMAGE",),
|
|
50
|
+
"image2": ("IMAGE",),
|
|
51
|
+
"image3": ("IMAGE",),
|
|
52
|
+
"image4": ("IMAGE",),
|
|
53
|
+
"image5": ("IMAGE",),
|
|
54
|
+
"image6": ("IMAGE",),
|
|
55
|
+
"image7": ("IMAGE",),
|
|
56
|
+
"image8": ("IMAGE",),
|
|
57
|
+
"image9": ("IMAGE",),
|
|
58
|
+
"image10": ("IMAGE",),
|
|
59
|
+
},
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
def handle_inputs(self, headers, prompt_id, **kwargs):
|
|
63
|
+
model = kwargs.get("model", "doubao-seedream-4-0-250828")
|
|
64
|
+
prompt = kwargs.get("prompt", "")
|
|
65
|
+
size = kwargs.get("size", "1K Square (1024x1024)")
|
|
66
|
+
|
|
67
|
+
match size:
|
|
68
|
+
case "1K Square (1024x1024)":
|
|
69
|
+
width = 1024
|
|
70
|
+
height = 1024
|
|
71
|
+
case "2K Square (2048x2048)":
|
|
72
|
+
width = 2048
|
|
73
|
+
height = 2048
|
|
74
|
+
case "4K Square (4096x4096)":
|
|
75
|
+
width = 4096
|
|
76
|
+
height = 4096
|
|
77
|
+
case "HD 16:9 (1920x1080)":
|
|
78
|
+
width = 1920
|
|
79
|
+
height = 1080
|
|
80
|
+
case "2K 16:9 (2560x1440)":
|
|
81
|
+
width = 2560
|
|
82
|
+
height = 1440
|
|
83
|
+
case "4K 16:9 (3840x2160)":
|
|
84
|
+
width = 3840
|
|
85
|
+
height = 2160
|
|
86
|
+
case "Portrait 9:16 (1080x1920)":
|
|
87
|
+
width = 1080
|
|
88
|
+
height = 1920
|
|
89
|
+
case "Portrait 3:4 (1536x2048)":
|
|
90
|
+
width = 1536
|
|
91
|
+
height = 2048
|
|
92
|
+
case "Landscape 4:3 (2048x1536)":
|
|
93
|
+
width = 2048
|
|
94
|
+
height = 1536
|
|
95
|
+
case "Ultra-wide 21:9 (3440x1440)":
|
|
96
|
+
width = 3440
|
|
97
|
+
height = 1440
|
|
98
|
+
case "Custom":
|
|
99
|
+
width = kwargs.get("custom_width", 1920)
|
|
100
|
+
height = kwargs.get("custom_height", 1080)
|
|
101
|
+
|
|
102
|
+
case _:
|
|
103
|
+
raise ValueError(f"Invalid size: {size}")
|
|
104
|
+
|
|
105
|
+
sizeStr = f"{width}x{height}"
|
|
106
|
+
|
|
107
|
+
images = []
|
|
108
|
+
total_size = 0
|
|
109
|
+
for i, img in enumerate(
|
|
110
|
+
[
|
|
111
|
+
kwargs.get("image", None),
|
|
112
|
+
kwargs.get("image2", None),
|
|
113
|
+
kwargs.get("image3", None),
|
|
114
|
+
kwargs.get("image4", None),
|
|
115
|
+
kwargs.get("image5", None),
|
|
116
|
+
kwargs.get("image6", None),
|
|
117
|
+
kwargs.get("image7", None),
|
|
118
|
+
kwargs.get("image8", None),
|
|
119
|
+
kwargs.get("image9", None),
|
|
120
|
+
kwargs.get("image10", None),
|
|
121
|
+
],
|
|
122
|
+
1,
|
|
123
|
+
):
|
|
124
|
+
if img is not None:
|
|
125
|
+
# 都当作PNG就行
|
|
126
|
+
bio = tensor_to_bytesio(image=img, total_pixels=4096 * 4096)
|
|
127
|
+
length = bio.getbuffer().nbytes
|
|
128
|
+
if length > 10 * 1024 * 1024:
|
|
129
|
+
raise ValueError(
|
|
130
|
+
"Image size is too large, Seedream 4.0 only supports up to 10MB"
|
|
131
|
+
)
|
|
132
|
+
total_size += length
|
|
133
|
+
if total_size > 50 * 1024 * 1024:
|
|
134
|
+
raise ValueError(
|
|
135
|
+
"Total size of images is too large, BizyAir only supports up to 50MB"
|
|
136
|
+
)
|
|
137
|
+
images.append(self.upload_file(bio, f"{prompt_id}_{i}.png", headers))
|
|
138
|
+
|
|
139
|
+
data = {
|
|
140
|
+
"prompt": prompt,
|
|
141
|
+
"size": sizeStr,
|
|
142
|
+
"image": images,
|
|
143
|
+
"model": model,
|
|
144
|
+
"watermark": False,
|
|
145
|
+
"response_format": "url",
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return data, model
|
|
149
|
+
|
|
150
|
+
def handle_outputs(self, outputs):
|
|
151
|
+
images = self.combine_images(outputs[1])
|
|
152
|
+
return (images,)
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
class Seedream4_5(BizyAirTrdApiBaseNode):
|
|
156
|
+
RETURN_TYPES = ("IMAGE",)
|
|
157
|
+
RETURN_NAMES = ("images",)
|
|
158
|
+
CATEGORY = "☁️BizyAir/External APIs/Doubao"
|
|
159
|
+
NODE_DISPLAY_NAME = "Seedream 4.5"
|
|
160
|
+
|
|
161
|
+
@classmethod
|
|
162
|
+
def INPUT_TYPES(s):
|
|
163
|
+
return {
|
|
164
|
+
"required": {
|
|
165
|
+
"prompt": (
|
|
166
|
+
"STRING",
|
|
167
|
+
{
|
|
168
|
+
"multiline": True,
|
|
169
|
+
"default": "",
|
|
170
|
+
},
|
|
171
|
+
),
|
|
172
|
+
"model": (
|
|
173
|
+
["doubao-seedream-4-5-251128"],
|
|
174
|
+
{"default": "doubao-seedream-4-5-251128"},
|
|
175
|
+
),
|
|
176
|
+
"size": (
|
|
177
|
+
[
|
|
178
|
+
"2K",
|
|
179
|
+
"4K",
|
|
180
|
+
"Custom",
|
|
181
|
+
],
|
|
182
|
+
{
|
|
183
|
+
"default": "2K",
|
|
184
|
+
},
|
|
185
|
+
),
|
|
186
|
+
"custom_width": (
|
|
187
|
+
"INT",
|
|
188
|
+
{
|
|
189
|
+
"default": 2048,
|
|
190
|
+
"min": 480,
|
|
191
|
+
"max": 4096,
|
|
192
|
+
"tooltip": "总像素取值范围 [2560x1440=3686400, 4096x4096=16777216], 宽高比取值范围:[1/16, 16]",
|
|
193
|
+
},
|
|
194
|
+
),
|
|
195
|
+
"custom_height": (
|
|
196
|
+
"INT",
|
|
197
|
+
{
|
|
198
|
+
"default": 2048,
|
|
199
|
+
"min": 480,
|
|
200
|
+
"max": 4096,
|
|
201
|
+
"tooltip": "总像素取值范围 [2560x1440=3686400, 4096x4096=16777216], 宽高比取值范围:[1/16, 16]",
|
|
202
|
+
},
|
|
203
|
+
),
|
|
204
|
+
"max_images": (
|
|
205
|
+
"INT",
|
|
206
|
+
{
|
|
207
|
+
"default": 1,
|
|
208
|
+
"min": 1,
|
|
209
|
+
"max": 15,
|
|
210
|
+
"tooltip": "实际可生成的图片数量,除受到 max_images 影响外,还受到输入的参考图数量影响。输入的参考图数量+最终生成的图片数量≤15张。",
|
|
211
|
+
},
|
|
212
|
+
),
|
|
213
|
+
"optimize_prompt": (
|
|
214
|
+
["disabled", "standard"],
|
|
215
|
+
{
|
|
216
|
+
"default": "disabled",
|
|
217
|
+
"tooltip": "提示词优化功能的配置。standard:标准模式,生成内容的质量更高,耗时较长。",
|
|
218
|
+
},
|
|
219
|
+
),
|
|
220
|
+
},
|
|
221
|
+
"optional": {
|
|
222
|
+
"images": (
|
|
223
|
+
"IMAGE",
|
|
224
|
+
{"tooltip": "参考图,数量不超过14张。会影响组图生成数量"},
|
|
225
|
+
),
|
|
226
|
+
},
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
def handle_inputs(self, headers, prompt_id, **kwargs):
|
|
230
|
+
# up to 14 ref images
|
|
231
|
+
# 10mb each
|
|
232
|
+
# custom total pixels [3686400, 16777216]
|
|
233
|
+
# custom size ratio [1/16, 16]
|
|
234
|
+
model = kwargs.get("model", "doubao-seedream-4-0-250828")
|
|
235
|
+
prompt = kwargs.get("prompt", "")
|
|
236
|
+
size = kwargs.get("size", "2K")
|
|
237
|
+
images = kwargs.get("images", None)
|
|
238
|
+
optimize_prompt = kwargs.get("optimize_prompt", "disabled")
|
|
239
|
+
max_images = kwargs.get("max_images", 1)
|
|
240
|
+
|
|
241
|
+
if images is not None and len(images) > 14:
|
|
242
|
+
raise ValueError("Maximum number of images is 14")
|
|
243
|
+
if size == "Custom":
|
|
244
|
+
width = kwargs.get("custom_width", 2048)
|
|
245
|
+
height = kwargs.get("custom_height", 2048)
|
|
246
|
+
if width * height < 3686400 or width * height > 16777216:
|
|
247
|
+
raise ValueError("Total pixels must be between 3686400 and 16777216")
|
|
248
|
+
if width / height < 1 / 16 or width / height > 16:
|
|
249
|
+
raise ValueError("Width/height ratio must be between 1/16 and 16")
|
|
250
|
+
size = f"{width}x{height}"
|
|
251
|
+
|
|
252
|
+
parts = []
|
|
253
|
+
for batch_number, img in enumerate(images if images is not None else []):
|
|
254
|
+
if img is not None:
|
|
255
|
+
bio = tensor_to_bytesio(image=img, total_pixels=4096 * 4096)
|
|
256
|
+
length = bio.getbuffer().nbytes
|
|
257
|
+
if length > 10 * 1024 * 1024:
|
|
258
|
+
raise ValueError(
|
|
259
|
+
"Image size is too large, Seedream 4.5 only supports up to 10MB"
|
|
260
|
+
)
|
|
261
|
+
url = self.upload_file(
|
|
262
|
+
bio,
|
|
263
|
+
f"{prompt_id}_{batch_number}.png",
|
|
264
|
+
headers,
|
|
265
|
+
)
|
|
266
|
+
parts.append(url)
|
|
267
|
+
|
|
268
|
+
data = {
|
|
269
|
+
"prompt": prompt,
|
|
270
|
+
"size": size,
|
|
271
|
+
"model": model,
|
|
272
|
+
"max_images": max_images,
|
|
273
|
+
}
|
|
274
|
+
if len(parts) > 0:
|
|
275
|
+
data["image"] = parts
|
|
276
|
+
if optimize_prompt != "disabled":
|
|
277
|
+
data["optimize_prompt"] = optimize_prompt
|
|
278
|
+
|
|
279
|
+
return data, model
|
|
280
|
+
|
|
281
|
+
def handle_outputs(self, outputs):
|
|
282
|
+
images = self.combine_images(outputs[1])
|
|
283
|
+
return (images,)
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
class Seededit3(BizyAirTrdApiBaseNode):
|
|
287
|
+
RETURN_TYPES = ("IMAGE",)
|
|
288
|
+
RETURN_NAMES = ("image",)
|
|
289
|
+
CATEGORY = "☁️BizyAir/External APIs/Doubao"
|
|
290
|
+
NODE_DISPLAY_NAME = "Seededit3"
|
|
291
|
+
|
|
292
|
+
@classmethod
|
|
293
|
+
def INPUT_TYPES(cls):
|
|
294
|
+
return {
|
|
295
|
+
"required": {
|
|
296
|
+
"image": ("IMAGE",),
|
|
297
|
+
"prompt": (
|
|
298
|
+
"STRING",
|
|
299
|
+
{
|
|
300
|
+
"multiline": True,
|
|
301
|
+
"default": "",
|
|
302
|
+
},
|
|
303
|
+
),
|
|
304
|
+
"model": (
|
|
305
|
+
["doubao-seededit-3-0-i2i-250628"],
|
|
306
|
+
{"default": "doubao-seededit-3-0-i2i-250628"},
|
|
307
|
+
),
|
|
308
|
+
"seed": ("INT", {"default": -1, "min": -1, "max": 2147483647}),
|
|
309
|
+
"guidance_scale": ("FLOAT", {"default": 5.5, "min": 1.0, "max": 10.0}),
|
|
310
|
+
},
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
def handle_inputs(self, headers, prompt_id, **kwargs):
|
|
314
|
+
model = kwargs.get("model", "doubao-seededit-3-0-i2i-250628")
|
|
315
|
+
prompt = kwargs.get("prompt", "")
|
|
316
|
+
image = kwargs.get("image", None)
|
|
317
|
+
seed = kwargs.get("seed", -1)
|
|
318
|
+
guidance_scale = kwargs.get("guidance_scale", 5.5)
|
|
319
|
+
if image is None:
|
|
320
|
+
raise ValueError("Image is required")
|
|
321
|
+
# 上传图片
|
|
322
|
+
image_url = self.upload_file(
|
|
323
|
+
tensor_to_bytesio(image=image, total_pixels=4096 * 4096),
|
|
324
|
+
f"{prompt_id}.png",
|
|
325
|
+
headers,
|
|
326
|
+
)
|
|
327
|
+
data = {
|
|
328
|
+
"prompt": prompt,
|
|
329
|
+
"model": model,
|
|
330
|
+
"image": image_url,
|
|
331
|
+
"seed": seed,
|
|
332
|
+
"guidance_scale": guidance_scale,
|
|
333
|
+
"size": "adaptive",
|
|
334
|
+
"response_format": "url",
|
|
335
|
+
"watermark": False,
|
|
336
|
+
}
|
|
337
|
+
return data, model
|
|
338
|
+
|
|
339
|
+
def handle_outputs(self, outputs):
|
|
340
|
+
images = self.combine_images(outputs[1])
|
|
341
|
+
return (images,)
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
class Seedance_1_0_T2V_API(BizyAirTrdApiBaseNode):
|
|
345
|
+
RETURN_TYPES = ("VIDEO",)
|
|
346
|
+
RETURN_NAMES = ("video",)
|
|
347
|
+
CATEGORY = "☁️BizyAir/External APIs/Doubao"
|
|
348
|
+
NODE_DISPLAY_NAME = "Seedance 1.0 Pro Text To Video"
|
|
349
|
+
|
|
350
|
+
@classmethod
|
|
351
|
+
def INPUT_TYPES(cls):
|
|
352
|
+
return {
|
|
353
|
+
"required": {
|
|
354
|
+
"prompt": (
|
|
355
|
+
"STRING",
|
|
356
|
+
{
|
|
357
|
+
"multiline": True,
|
|
358
|
+
"default": "",
|
|
359
|
+
},
|
|
360
|
+
),
|
|
361
|
+
"model": (
|
|
362
|
+
[
|
|
363
|
+
"doubao-seedance-1-0-pro-250528",
|
|
364
|
+
"doubao-seedance-1-0-pro-fast-251015",
|
|
365
|
+
],
|
|
366
|
+
{"default": "doubao-seedance-1-0-pro-250528"},
|
|
367
|
+
),
|
|
368
|
+
"resolution": (
|
|
369
|
+
["480p", "720p", "1080p"],
|
|
370
|
+
{
|
|
371
|
+
"default": "1080p",
|
|
372
|
+
"tooltip": "分辨率+比例共同决定视频尺寸,具体尺寸请参考官方文档说明",
|
|
373
|
+
},
|
|
374
|
+
),
|
|
375
|
+
"ratio": (
|
|
376
|
+
["16:9", "4:3", "1:1", "3:4", "9:16", "21:9", "adaptive"],
|
|
377
|
+
{
|
|
378
|
+
"default": "adaptive",
|
|
379
|
+
"tooltip": "比例+分辨率共同决定视频尺寸,具体尺寸请参考官方文档说明",
|
|
380
|
+
},
|
|
381
|
+
),
|
|
382
|
+
"duration": ("INT", {"default": 12, "min": 2, "max": 12}),
|
|
383
|
+
"fps": (
|
|
384
|
+
[24],
|
|
385
|
+
{
|
|
386
|
+
"default": 24,
|
|
387
|
+
"tooltip": "帧率固定24",
|
|
388
|
+
},
|
|
389
|
+
),
|
|
390
|
+
"camerafixed": (
|
|
391
|
+
"BOOLEAN",
|
|
392
|
+
{
|
|
393
|
+
"default": False,
|
|
394
|
+
"tooltip": "平台可能在提示词中追加固定摄像机指令(效果不保证) ",
|
|
395
|
+
},
|
|
396
|
+
),
|
|
397
|
+
"seed": ("INT", {"default": -1, "min": -1, "max": 2147483647}),
|
|
398
|
+
},
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
def handle_inputs(self, headers, prompt_id, **kwargs):
|
|
402
|
+
model = kwargs.get("model", "doubao-seedance-1-0-pro-250528")
|
|
403
|
+
prompt = kwargs.get("prompt", "")
|
|
404
|
+
resolution = kwargs.get("resolution", "1080p")
|
|
405
|
+
ratio = kwargs.get("ratio", "adaptive")
|
|
406
|
+
duration = kwargs.get("duration", 12)
|
|
407
|
+
camerafixed = kwargs.get("camerafixed", False)
|
|
408
|
+
seed = kwargs.get("seed", -1)
|
|
409
|
+
if prompt is None or prompt.strip() == "":
|
|
410
|
+
raise ValueError("Prompt is required")
|
|
411
|
+
data = {
|
|
412
|
+
"prompt": prompt,
|
|
413
|
+
"model": model,
|
|
414
|
+
"resolution": resolution,
|
|
415
|
+
"ratio": ratio,
|
|
416
|
+
"duration": duration,
|
|
417
|
+
"camerafixed": camerafixed,
|
|
418
|
+
"seed": seed,
|
|
419
|
+
"watermark": False,
|
|
420
|
+
"fps": 24,
|
|
421
|
+
}
|
|
422
|
+
return data, "doubao-seedance-1-0"
|
|
423
|
+
|
|
424
|
+
def handle_outputs(self, outputs):
|
|
425
|
+
return (outputs[0][0],)
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
class Seedance_1_0_I2V_API(BizyAirTrdApiBaseNode):
|
|
429
|
+
RETURN_TYPES = ("VIDEO",)
|
|
430
|
+
RETURN_NAMES = ("video",)
|
|
431
|
+
CATEGORY = "☁️BizyAir/External APIs/Doubao"
|
|
432
|
+
NODE_DISPLAY_NAME = "Seedance 1.0 Pro Image To Video"
|
|
433
|
+
|
|
434
|
+
@classmethod
|
|
435
|
+
def INPUT_TYPES(cls):
|
|
436
|
+
return {
|
|
437
|
+
"required": {
|
|
438
|
+
"first_frame_image": ("IMAGE",),
|
|
439
|
+
"prompt": (
|
|
440
|
+
"STRING",
|
|
441
|
+
{
|
|
442
|
+
"multiline": True,
|
|
443
|
+
"default": "",
|
|
444
|
+
},
|
|
445
|
+
),
|
|
446
|
+
"model": (
|
|
447
|
+
[
|
|
448
|
+
"doubao-seedance-1-0-pro-250528",
|
|
449
|
+
"doubao-seedance-1-0-pro-fast-251015",
|
|
450
|
+
],
|
|
451
|
+
{"default": "doubao-seedance-1-0-pro-250528"},
|
|
452
|
+
),
|
|
453
|
+
"resolution": (
|
|
454
|
+
["480p", "720p", "1080p"],
|
|
455
|
+
{
|
|
456
|
+
"default": "1080p",
|
|
457
|
+
"tooltip": "分辨率+比例共同决定视频尺寸,具体尺寸请参考官方文档说明",
|
|
458
|
+
},
|
|
459
|
+
),
|
|
460
|
+
"ratio": (
|
|
461
|
+
["16:9", "4:3", "1:1", "3:4", "9:16", "21:9", "adaptive"],
|
|
462
|
+
{
|
|
463
|
+
"default": "adaptive",
|
|
464
|
+
"tooltip": "比例+分辨率共同决定视频尺寸,具体尺寸请参考官方文档说明",
|
|
465
|
+
},
|
|
466
|
+
),
|
|
467
|
+
"duration": ("INT", {"default": 12, "min": 2, "max": 12}),
|
|
468
|
+
"fps": (
|
|
469
|
+
[24],
|
|
470
|
+
{
|
|
471
|
+
"default": 24,
|
|
472
|
+
"tooltip": "帧率固定24",
|
|
473
|
+
},
|
|
474
|
+
),
|
|
475
|
+
"camerafixed": (
|
|
476
|
+
"BOOLEAN",
|
|
477
|
+
{
|
|
478
|
+
"default": False,
|
|
479
|
+
"tooltip": "平台可能在提示词中追加固定摄像机指令(效果不保证) ",
|
|
480
|
+
},
|
|
481
|
+
),
|
|
482
|
+
"seed": ("INT", {"default": -1, "min": -1, "max": 2147483647}),
|
|
483
|
+
},
|
|
484
|
+
"optional": {
|
|
485
|
+
"last_frame_image": ("IMAGE",),
|
|
486
|
+
},
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
def handle_inputs(self, headers, prompt_id, **kwargs):
|
|
490
|
+
model = kwargs.get("model", "doubao-seedance-1-0-pro-250528")
|
|
491
|
+
prompt = kwargs.get("prompt", "")
|
|
492
|
+
resolution = kwargs.get("resolution", "1080p")
|
|
493
|
+
ratio = kwargs.get("ratio", "adaptive")
|
|
494
|
+
duration = kwargs.get("duration", 12)
|
|
495
|
+
camerafixed = kwargs.get("camerafixed", False)
|
|
496
|
+
seed = kwargs.get("seed", -1)
|
|
497
|
+
first_frame_image = kwargs.get("first_frame_image", None)
|
|
498
|
+
last_frame_image = kwargs.get("last_frame_image", None)
|
|
499
|
+
if first_frame_image is None:
|
|
500
|
+
raise ValueError("First frame image is required")
|
|
501
|
+
if (
|
|
502
|
+
last_frame_image is not None
|
|
503
|
+
and model == "doubao-seedance-1-0-pro-fast-251015"
|
|
504
|
+
):
|
|
505
|
+
raise ValueError(
|
|
506
|
+
"Last frame image is not supported for doubao-seedance-1-0-pro-fast-251015"
|
|
507
|
+
)
|
|
508
|
+
first_frame_image_url = self.upload_file(
|
|
509
|
+
tensor_to_bytesio(image=first_frame_image, total_pixels=4096 * 4096),
|
|
510
|
+
f"{prompt_id}_first.png",
|
|
511
|
+
headers,
|
|
512
|
+
)
|
|
513
|
+
data = {
|
|
514
|
+
"prompt": prompt,
|
|
515
|
+
"model": model,
|
|
516
|
+
"resolution": resolution,
|
|
517
|
+
"ratio": ratio,
|
|
518
|
+
"duration": duration,
|
|
519
|
+
"camerafixed": camerafixed,
|
|
520
|
+
"seed": seed,
|
|
521
|
+
"watermark": False,
|
|
522
|
+
"fps": 24,
|
|
523
|
+
"first_frame_image": first_frame_image_url,
|
|
524
|
+
}
|
|
525
|
+
if last_frame_image is not None:
|
|
526
|
+
last_frame_image_url = self.upload_file(
|
|
527
|
+
tensor_to_bytesio(image=last_frame_image, total_pixels=4096 * 4096),
|
|
528
|
+
f"{prompt_id}_last.png",
|
|
529
|
+
headers,
|
|
530
|
+
)
|
|
531
|
+
data["last_frame_image"] = last_frame_image_url
|
|
532
|
+
return data, "doubao-seedance-1-0"
|
|
533
|
+
|
|
534
|
+
def handle_outputs(self, outputs):
|
|
535
|
+
return (outputs[0][0],)
|