bizyengine 1.2.53__py3-none-any.whl → 1.2.54__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 -0
- bizyengine/bizyair_extras/nodes_wan_api.py +289 -0
- bizyengine/bizyair_extras/utils/aliyun_oss.py +75 -0
- bizyengine/bizyair_extras/utils/audio.py +88 -0
- bizyengine/version.txt +1 -1
- {bizyengine-1.2.53.dist-info → bizyengine-1.2.54.dist-info}/METADATA +1 -1
- {bizyengine-1.2.53.dist-info → bizyengine-1.2.54.dist-info}/RECORD +9 -6
- {bizyengine-1.2.53.dist-info → bizyengine-1.2.54.dist-info}/WHEEL +0 -0
- {bizyengine-1.2.53.dist-info → bizyengine-1.2.54.dist-info}/top_level.txt +0 -0
|
@@ -28,6 +28,7 @@ from .nodes_trellis import *
|
|
|
28
28
|
from .nodes_ultimatesdupscale import *
|
|
29
29
|
from .nodes_upscale_model import *
|
|
30
30
|
from .nodes_utils import *
|
|
31
|
+
from .nodes_wan_api import *
|
|
31
32
|
from .nodes_wan_i2v import *
|
|
32
33
|
from .nodes_wan_video import *
|
|
33
34
|
from .route_bizyair_tools import *
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
import io
|
|
2
|
+
import json
|
|
3
|
+
import logging
|
|
4
|
+
|
|
5
|
+
import requests
|
|
6
|
+
from comfy_api.latest._input_impl import VideoFromFile
|
|
7
|
+
from comfy_api_nodes.apinode_utils import tensor_to_bytesio
|
|
8
|
+
|
|
9
|
+
from bizyengine.bizyair_extras.utils.audio import save_audio
|
|
10
|
+
from bizyengine.core import BizyAirBaseNode, pop_api_key_and_prompt_id
|
|
11
|
+
from bizyengine.core.common import client
|
|
12
|
+
from bizyengine.core.common.client import send_request
|
|
13
|
+
from bizyengine.core.common.env_var import BIZYAIR_X_SERVER
|
|
14
|
+
|
|
15
|
+
from .utils.aliyun_oss import upload_file_without_sdk
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def parse_upload_token(resp) -> dict:
|
|
19
|
+
logging.debug(f"parsing token resp: {resp}")
|
|
20
|
+
if "data" not in resp:
|
|
21
|
+
logging.error(f"Invalid response, data not found: {resp}")
|
|
22
|
+
raise ValueError(f"Invalid response: {resp}")
|
|
23
|
+
data = resp["data"]
|
|
24
|
+
if "file" not in data:
|
|
25
|
+
logging.error(f"Invalid response, file not found: {resp}")
|
|
26
|
+
raise ValueError(f"Invalid response: {resp}")
|
|
27
|
+
file = data["file"]
|
|
28
|
+
if "storage" not in data:
|
|
29
|
+
logging.error(f"Invalid response, storage not found: {resp}")
|
|
30
|
+
raise ValueError(f"Invalid response: {resp}")
|
|
31
|
+
storage = data["storage"]
|
|
32
|
+
return file | storage
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class Wan_V2_5_I2V_API(BizyAirBaseNode):
|
|
36
|
+
@classmethod
|
|
37
|
+
def INPUT_TYPES(cls):
|
|
38
|
+
return {
|
|
39
|
+
"required": {
|
|
40
|
+
"image": ("IMAGE",),
|
|
41
|
+
},
|
|
42
|
+
"optional": {
|
|
43
|
+
"audio": ("AUDIO",),
|
|
44
|
+
"prompt": (
|
|
45
|
+
"STRING",
|
|
46
|
+
{
|
|
47
|
+
"multiline": True,
|
|
48
|
+
"default": "",
|
|
49
|
+
},
|
|
50
|
+
),
|
|
51
|
+
"negative_prompt": (
|
|
52
|
+
"STRING",
|
|
53
|
+
{
|
|
54
|
+
"multiline": True,
|
|
55
|
+
"default": "",
|
|
56
|
+
},
|
|
57
|
+
),
|
|
58
|
+
"resolution": (
|
|
59
|
+
["480P", "720P", "1080P"],
|
|
60
|
+
{"default": "1080P"},
|
|
61
|
+
),
|
|
62
|
+
"duration": ([5, 10], {"default": 5}),
|
|
63
|
+
"prompt_extend": (
|
|
64
|
+
"BOOLEAN",
|
|
65
|
+
{
|
|
66
|
+
"default": True,
|
|
67
|
+
"tooltip": "是否开启prompt智能改写。开启后使用大模型对输入prompt进行智能改写。对于较短的prompt生成效果提升明显,但会增加耗时。",
|
|
68
|
+
},
|
|
69
|
+
),
|
|
70
|
+
"auto_audio": (
|
|
71
|
+
"BOOLEAN",
|
|
72
|
+
{
|
|
73
|
+
"default": True,
|
|
74
|
+
"tooltip": "是否由模型自动生成声音,优先级低于audio参数。",
|
|
75
|
+
},
|
|
76
|
+
),
|
|
77
|
+
},
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
NODE_DISPLAY_NAME = "Wan2.5 Image To Video"
|
|
81
|
+
RETURN_TYPES = ("VIDEO", "STRING")
|
|
82
|
+
RETURN_NAMES = ("video", "actual_prompt")
|
|
83
|
+
CATEGORY = "☁️BizyAir/External APIs/WanVideo"
|
|
84
|
+
FUNCTION = "api_call"
|
|
85
|
+
|
|
86
|
+
def api_call(self, image, **kwargs):
|
|
87
|
+
extra_data = pop_api_key_and_prompt_id(kwargs)
|
|
88
|
+
headers = client.headers(api_key=extra_data["api_key"])
|
|
89
|
+
prompt_id = extra_data["prompt_id"]
|
|
90
|
+
headers["X-BIZYAIR-PROMPT-ID"] = prompt_id
|
|
91
|
+
|
|
92
|
+
# 参数
|
|
93
|
+
prompt = kwargs.get("prompt", "")
|
|
94
|
+
negative_prompt = kwargs.get("negative_prompt", "")
|
|
95
|
+
audio = kwargs.get("audio", None)
|
|
96
|
+
resolution = kwargs.get("resolution", "1080P")
|
|
97
|
+
duration = kwargs.get("duration", 5)
|
|
98
|
+
prompt_extend = kwargs.get("prompt_extend", True)
|
|
99
|
+
auto_audio = kwargs.get("auto_audio", True)
|
|
100
|
+
|
|
101
|
+
input = {}
|
|
102
|
+
if prompt is not None and prompt.strip() != "":
|
|
103
|
+
input["prompt"] = prompt
|
|
104
|
+
if negative_prompt is not None and negative_prompt.strip() != "":
|
|
105
|
+
input["negative_prompt"] = negative_prompt
|
|
106
|
+
|
|
107
|
+
# 上传图片&音频
|
|
108
|
+
if image is not None:
|
|
109
|
+
oss_token_url = f"{BIZYAIR_X_SERVER}/upload/token?file_name={prompt_id}.png&file_type=inputs"
|
|
110
|
+
token_resp = send_request("GET", oss_token_url)
|
|
111
|
+
auth_info = parse_upload_token(token_resp)
|
|
112
|
+
input["img_url"] = upload_file_without_sdk(
|
|
113
|
+
tensor_to_bytesio(image), **auth_info
|
|
114
|
+
)
|
|
115
|
+
if audio is not None:
|
|
116
|
+
oss_token_url = f"{BIZYAIR_X_SERVER}/upload/token?file_name={prompt_id}.flac&file_type=inputs"
|
|
117
|
+
token_resp = send_request("GET", oss_token_url)
|
|
118
|
+
auth_info = parse_upload_token(token_resp)
|
|
119
|
+
audio_bytes = save_audio(audio)
|
|
120
|
+
input["audio_url"] = upload_file_without_sdk(audio_bytes, **auth_info)
|
|
121
|
+
|
|
122
|
+
# 调用API
|
|
123
|
+
model = "wan2.5-i2v-preview"
|
|
124
|
+
api_url = f"{BIZYAIR_X_SERVER}/proxy_inference/Wan/{model}"
|
|
125
|
+
data = {
|
|
126
|
+
"model": model,
|
|
127
|
+
"input": input,
|
|
128
|
+
"parameters": {
|
|
129
|
+
"resolution": resolution,
|
|
130
|
+
"prompt_extend": prompt_extend,
|
|
131
|
+
"duration": duration,
|
|
132
|
+
"audio": auto_audio,
|
|
133
|
+
},
|
|
134
|
+
}
|
|
135
|
+
json_payload = json.dumps(data).encode("utf-8")
|
|
136
|
+
logging.debug(f"json_payload: {json_payload}")
|
|
137
|
+
api_resp = send_request(
|
|
138
|
+
url=api_url,
|
|
139
|
+
data=json_payload,
|
|
140
|
+
headers=headers,
|
|
141
|
+
)
|
|
142
|
+
logging.debug(f"api resp: {api_resp}")
|
|
143
|
+
if "output" not in api_resp or "video_url" not in api_resp["output"]:
|
|
144
|
+
raise ValueError(f"Invalid response: {api_resp}")
|
|
145
|
+
video_url = api_resp["output"]["video_url"]
|
|
146
|
+
actual_prompt = api_resp["output"].get("actual_prompt", prompt)
|
|
147
|
+
# 下载视频
|
|
148
|
+
video_resp = requests.get(video_url, stream=True, timeout=30)
|
|
149
|
+
video_resp.raise_for_status() # 非 2xx 会抛异常
|
|
150
|
+
return (VideoFromFile(io.BytesIO(video_resp.content)), actual_prompt)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
class Wan_V2_5_T2V_API(BizyAirBaseNode):
|
|
154
|
+
@classmethod
|
|
155
|
+
def INPUT_TYPES(cls):
|
|
156
|
+
return {
|
|
157
|
+
"required": {
|
|
158
|
+
"prompt": (
|
|
159
|
+
"STRING",
|
|
160
|
+
{
|
|
161
|
+
"multiline": True,
|
|
162
|
+
"default": "",
|
|
163
|
+
},
|
|
164
|
+
),
|
|
165
|
+
},
|
|
166
|
+
"optional": {
|
|
167
|
+
"audio": ("AUDIO",),
|
|
168
|
+
"negative_prompt": (
|
|
169
|
+
"STRING",
|
|
170
|
+
{
|
|
171
|
+
"multiline": True,
|
|
172
|
+
"default": "",
|
|
173
|
+
},
|
|
174
|
+
),
|
|
175
|
+
"size": (
|
|
176
|
+
[
|
|
177
|
+
"832*480",
|
|
178
|
+
"480*832",
|
|
179
|
+
"624*624",
|
|
180
|
+
"1280*720",
|
|
181
|
+
"720*1280",
|
|
182
|
+
"960*960",
|
|
183
|
+
"1088*832",
|
|
184
|
+
"832*1088",
|
|
185
|
+
"1920*1080",
|
|
186
|
+
"1080*1920",
|
|
187
|
+
"1440*1440",
|
|
188
|
+
"1632*1248",
|
|
189
|
+
"1248*1632",
|
|
190
|
+
],
|
|
191
|
+
{"default": "1920*1080"},
|
|
192
|
+
),
|
|
193
|
+
"duration": ([5, 10], {"default": 5}),
|
|
194
|
+
"prompt_extend": (
|
|
195
|
+
"BOOLEAN",
|
|
196
|
+
{
|
|
197
|
+
"default": True,
|
|
198
|
+
"tooltip": "是否开启prompt智能改写。开启后使用大模型对输入prompt进行智能改写。对于较短的prompt生成效果提升明显,但会增加耗时。",
|
|
199
|
+
},
|
|
200
|
+
),
|
|
201
|
+
"auto_audio": (
|
|
202
|
+
"BOOLEAN",
|
|
203
|
+
{
|
|
204
|
+
"default": True,
|
|
205
|
+
"tooltip": "是否由模型自动生成声音,优先级低于audio参数。",
|
|
206
|
+
},
|
|
207
|
+
),
|
|
208
|
+
},
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
NODE_DISPLAY_NAME = "Wan2.5 Text To Video"
|
|
212
|
+
RETURN_TYPES = ("VIDEO", "STRING")
|
|
213
|
+
RETURN_NAMES = ("video", "actual_prompt")
|
|
214
|
+
CATEGORY = "☁️BizyAir/External APIs/WanVideo"
|
|
215
|
+
FUNCTION = "api_call"
|
|
216
|
+
|
|
217
|
+
def parse_upload_token(self, resp) -> dict:
|
|
218
|
+
logging.debug(f"parsing token resp: {resp}")
|
|
219
|
+
if "data" not in resp:
|
|
220
|
+
logging.error(f"Invalid response, data not found: {resp}")
|
|
221
|
+
raise ValueError(f"Invalid response: {resp}")
|
|
222
|
+
data = resp["data"]
|
|
223
|
+
if "file" not in data:
|
|
224
|
+
logging.error(f"Invalid response, file not found: {resp}")
|
|
225
|
+
raise ValueError(f"Invalid response: {resp}")
|
|
226
|
+
file = data["file"]
|
|
227
|
+
if "storage" not in data:
|
|
228
|
+
logging.error(f"Invalid response, storage not found: {resp}")
|
|
229
|
+
raise ValueError(f"Invalid response: {resp}")
|
|
230
|
+
storage = data["storage"]
|
|
231
|
+
return file | storage
|
|
232
|
+
|
|
233
|
+
def api_call(self, prompt, **kwargs):
|
|
234
|
+
extra_data = pop_api_key_and_prompt_id(kwargs)
|
|
235
|
+
headers = client.headers(api_key=extra_data["api_key"])
|
|
236
|
+
prompt_id = extra_data["prompt_id"]
|
|
237
|
+
headers["X-BIZYAIR-PROMPT-ID"] = prompt_id
|
|
238
|
+
|
|
239
|
+
# 参数
|
|
240
|
+
negative_prompt = kwargs.get("negative_prompt", "")
|
|
241
|
+
audio = kwargs.get("audio", None)
|
|
242
|
+
size = kwargs.get("size", "1920*1080")
|
|
243
|
+
duration = kwargs.get("duration", 5)
|
|
244
|
+
prompt_extend = kwargs.get("prompt_extend", True)
|
|
245
|
+
auto_audio = kwargs.get("auto_audio", True)
|
|
246
|
+
|
|
247
|
+
input = {}
|
|
248
|
+
if prompt is not None and prompt.strip() != "":
|
|
249
|
+
input["prompt"] = prompt
|
|
250
|
+
if negative_prompt is not None and negative_prompt.strip() != "":
|
|
251
|
+
input["negative_prompt"] = negative_prompt
|
|
252
|
+
|
|
253
|
+
# 上传音频
|
|
254
|
+
if audio is not None:
|
|
255
|
+
oss_token_url = f"{BIZYAIR_X_SERVER}/upload/token?file_name={prompt_id}.flac&file_type=inputs"
|
|
256
|
+
token_resp = send_request("GET", oss_token_url)
|
|
257
|
+
auth_info = parse_upload_token(token_resp)
|
|
258
|
+
audio_bytes = save_audio(audio)
|
|
259
|
+
input["audio_url"] = upload_file_without_sdk(audio_bytes, **auth_info)
|
|
260
|
+
|
|
261
|
+
# 调用API
|
|
262
|
+
model = "wan2.5-t2v-preview"
|
|
263
|
+
api_url = f"{BIZYAIR_X_SERVER}/proxy_inference/Wan/{model}"
|
|
264
|
+
data = {
|
|
265
|
+
"model": model,
|
|
266
|
+
"input": input,
|
|
267
|
+
"parameters": {
|
|
268
|
+
"size": size,
|
|
269
|
+
"prompt_extend": prompt_extend,
|
|
270
|
+
"duration": duration,
|
|
271
|
+
"audio": auto_audio,
|
|
272
|
+
},
|
|
273
|
+
}
|
|
274
|
+
json_payload = json.dumps(data).encode("utf-8")
|
|
275
|
+
logging.debug(f"json_payload: {json_payload}")
|
|
276
|
+
api_resp = send_request(
|
|
277
|
+
url=api_url,
|
|
278
|
+
data=json_payload,
|
|
279
|
+
headers=headers,
|
|
280
|
+
)
|
|
281
|
+
logging.debug(f"api resp: {api_resp}")
|
|
282
|
+
if "output" not in api_resp or "video_url" not in api_resp["output"]:
|
|
283
|
+
raise ValueError(f"Invalid response: {api_resp}")
|
|
284
|
+
video_url = api_resp["output"]["video_url"]
|
|
285
|
+
actual_prompt = api_resp["output"].get("actual_prompt", prompt)
|
|
286
|
+
# 下载视频
|
|
287
|
+
video_resp = requests.get(video_url, stream=True, timeout=30)
|
|
288
|
+
video_resp.raise_for_status() # 非 2xx 会抛异常
|
|
289
|
+
return (VideoFromFile(io.BytesIO(video_resp.content)), actual_prompt)
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
import datetime
|
|
3
|
+
import hashlib
|
|
4
|
+
import hmac
|
|
5
|
+
import io
|
|
6
|
+
import logging
|
|
7
|
+
|
|
8
|
+
import requests
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def sign_request(method, bucket, object_key, headers, access_key_id, access_key_secret):
|
|
12
|
+
# This is a simplified representation. Actual OSS signing is more complex.
|
|
13
|
+
# It involves creating a canonicalized resource and headers string.
|
|
14
|
+
# Refer to Alibaba Cloud OSS documentation for precise signing details.
|
|
15
|
+
|
|
16
|
+
canonical_string = f"{method}\n"
|
|
17
|
+
canonical_string += f"{headers.get('Content-MD5', '')}\n"
|
|
18
|
+
canonical_string += f"{headers.get('Content-Type', '')}\n"
|
|
19
|
+
canonical_string += f"{headers.get('Date', '')}\n"
|
|
20
|
+
|
|
21
|
+
# Add canonicalized OSS headers if present (e.g., x-oss-meta-*)
|
|
22
|
+
for key in sorted(headers.keys()):
|
|
23
|
+
if key.lower().startswith("x-oss-"):
|
|
24
|
+
canonical_string += f"{key.lower()}:{headers[key]}\n"
|
|
25
|
+
|
|
26
|
+
canonical_string += f"/{bucket}/{object_key}"
|
|
27
|
+
|
|
28
|
+
h = hmac.new(
|
|
29
|
+
access_key_secret.encode("utf-8"),
|
|
30
|
+
canonical_string.encode("utf-8"),
|
|
31
|
+
hashlib.sha1,
|
|
32
|
+
)
|
|
33
|
+
signature = base64.b64encode(h.digest()).decode("utf-8")
|
|
34
|
+
return f"OSS {access_key_id}:{signature}"
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def upload_file_without_sdk(
|
|
38
|
+
file_content: io.BytesIO,
|
|
39
|
+
bucket,
|
|
40
|
+
object_key,
|
|
41
|
+
endpoint,
|
|
42
|
+
access_key_id,
|
|
43
|
+
access_key_secret,
|
|
44
|
+
security_token,
|
|
45
|
+
**kwargs,
|
|
46
|
+
):
|
|
47
|
+
logging.info(f"Uploading file to {bucket}.{endpoint}/{object_key}")
|
|
48
|
+
date = datetime.datetime.now(datetime.timezone.utc).strftime(
|
|
49
|
+
"%a, %d %b %Y %H:%M:%S GMT"
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
headers = {
|
|
53
|
+
"Host": f"{bucket}.{endpoint}",
|
|
54
|
+
"Date": date,
|
|
55
|
+
"Content-Type": "application/octet-stream",
|
|
56
|
+
"Content-Length": str(file_content.getbuffer().nbytes),
|
|
57
|
+
"x-oss-security-token": security_token,
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
headers["Authorization"] = sign_request(
|
|
61
|
+
"PUT", bucket, object_key, headers, access_key_id, access_key_secret
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
url = f"https://{bucket}.{endpoint}/{object_key}"
|
|
65
|
+
|
|
66
|
+
try:
|
|
67
|
+
response = requests.put(url, headers=headers, data=file_content)
|
|
68
|
+
response.raise_for_status() # Raise an exception for bad status codes
|
|
69
|
+
logging.info(f"File '{object_key}' uploaded successfully.")
|
|
70
|
+
return url
|
|
71
|
+
except requests.exceptions.RequestException as e:
|
|
72
|
+
logging.error(f"Error uploading file: {e}")
|
|
73
|
+
if response is not None:
|
|
74
|
+
logging.error(f"Response content: {response.text}")
|
|
75
|
+
raise e
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import io
|
|
2
|
+
|
|
3
|
+
import av
|
|
4
|
+
import torchaudio
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# Adapted from ComfyUI save_audio function
|
|
8
|
+
def save_audio(
|
|
9
|
+
audio,
|
|
10
|
+
filename_prefix="ComfyUI",
|
|
11
|
+
format="flac",
|
|
12
|
+
prompt=None,
|
|
13
|
+
extra_pnginfo=None,
|
|
14
|
+
quality="128k",
|
|
15
|
+
) -> io.BytesIO:
|
|
16
|
+
# Opus supported sample rates
|
|
17
|
+
OPUS_RATES = [8000, 12000, 16000, 24000, 48000]
|
|
18
|
+
|
|
19
|
+
for batch_number, waveform in enumerate(audio["waveform"].cpu()):
|
|
20
|
+
# Use original sample rate initially
|
|
21
|
+
sample_rate = audio["sample_rate"]
|
|
22
|
+
|
|
23
|
+
# Handle Opus sample rate requirements
|
|
24
|
+
if format == "opus":
|
|
25
|
+
if sample_rate > 48000:
|
|
26
|
+
sample_rate = 48000
|
|
27
|
+
elif sample_rate not in OPUS_RATES:
|
|
28
|
+
# Find the next highest supported rate
|
|
29
|
+
for rate in sorted(OPUS_RATES):
|
|
30
|
+
if rate > sample_rate:
|
|
31
|
+
sample_rate = rate
|
|
32
|
+
break
|
|
33
|
+
if sample_rate not in OPUS_RATES: # Fallback if still not supported
|
|
34
|
+
sample_rate = 48000
|
|
35
|
+
|
|
36
|
+
# Resample if necessary
|
|
37
|
+
if sample_rate != audio["sample_rate"]:
|
|
38
|
+
waveform = torchaudio.functional.resample(
|
|
39
|
+
waveform, audio["sample_rate"], sample_rate
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
# Create output with specified format
|
|
43
|
+
output_buffer = io.BytesIO()
|
|
44
|
+
output_container = av.open(output_buffer, mode="w", format=format)
|
|
45
|
+
|
|
46
|
+
# Set up the output stream with appropriate properties
|
|
47
|
+
if format == "opus":
|
|
48
|
+
out_stream = output_container.add_stream("libopus", rate=sample_rate)
|
|
49
|
+
if quality == "64k":
|
|
50
|
+
out_stream.bit_rate = 64000
|
|
51
|
+
elif quality == "96k":
|
|
52
|
+
out_stream.bit_rate = 96000
|
|
53
|
+
elif quality == "128k":
|
|
54
|
+
out_stream.bit_rate = 128000
|
|
55
|
+
elif quality == "192k":
|
|
56
|
+
out_stream.bit_rate = 192000
|
|
57
|
+
elif quality == "320k":
|
|
58
|
+
out_stream.bit_rate = 320000
|
|
59
|
+
elif format == "mp3":
|
|
60
|
+
out_stream = output_container.add_stream("libmp3lame", rate=sample_rate)
|
|
61
|
+
if quality == "V0":
|
|
62
|
+
# TODO i would really love to support V3 and V5 but there doesn't seem to be a way to set the qscale level, the property below is a bool
|
|
63
|
+
out_stream.codec_context.qscale = 1
|
|
64
|
+
elif quality == "128k":
|
|
65
|
+
out_stream.bit_rate = 128000
|
|
66
|
+
elif quality == "320k":
|
|
67
|
+
out_stream.bit_rate = 320000
|
|
68
|
+
else: # format == "flac":
|
|
69
|
+
out_stream = output_container.add_stream("flac", rate=sample_rate)
|
|
70
|
+
|
|
71
|
+
frame = av.AudioFrame.from_ndarray(
|
|
72
|
+
waveform.movedim(0, 1).reshape(1, -1).float().numpy(),
|
|
73
|
+
format="flt",
|
|
74
|
+
layout="mono" if waveform.shape[0] == 1 else "stereo",
|
|
75
|
+
)
|
|
76
|
+
frame.sample_rate = sample_rate
|
|
77
|
+
frame.pts = 0
|
|
78
|
+
output_container.mux(out_stream.encode(frame))
|
|
79
|
+
|
|
80
|
+
# Flush encoder
|
|
81
|
+
output_container.mux(out_stream.encode(None))
|
|
82
|
+
|
|
83
|
+
# Close containers
|
|
84
|
+
output_container.close()
|
|
85
|
+
|
|
86
|
+
# Write the output to file
|
|
87
|
+
output_buffer.seek(0)
|
|
88
|
+
return output_buffer
|
bizyengine/version.txt
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.2.
|
|
1
|
+
1.2.54
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bizyengine
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.54
|
|
4
4
|
Summary: [a/BizyAir](https://github.com/siliconflow/BizyAir) Comfy Nodes that can run in any environment.
|
|
5
5
|
Author-email: SiliconFlow <yaochi@siliconflow.cn>
|
|
6
6
|
Project-URL: Repository, https://github.com/siliconflow/BizyAir
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
bizyengine/__init__.py,sha256=GP9V-JM07fz7uv_qTB43QEA2rKdrVJxi5I7LRnn_3ZQ,914
|
|
2
|
-
bizyengine/version.txt,sha256=
|
|
2
|
+
bizyengine/version.txt,sha256=Vaz5htQef9aVBmqDpSaUgks9i-T6vfWEwSPW9k8FWnY,7
|
|
3
3
|
bizyengine/bizy_server/__init__.py,sha256=SP9oSblnPo4KQyh7yOGD26YCskFAcQHAZy04nQBNRIw,200
|
|
4
4
|
bizyengine/bizy_server/api_client.py,sha256=Z7G5IjaEqSJkF6nLLw2R3bpgBAOi5ClQiUbel6NMXmE,43932
|
|
5
5
|
bizyengine/bizy_server/errno.py,sha256=RIyvegX3lzpx_1L1q2XVvu3on0kvYgKiUQ8U3ZtyF68,16823
|
|
@@ -10,7 +10,7 @@ bizyengine/bizy_server/resp.py,sha256=iOFT5Ud7VJBP2uqkojJIgc3y2ifMjjEXoj0ewneL9l
|
|
|
10
10
|
bizyengine/bizy_server/server.py,sha256=isOzHDk2kD6WjdlemeOA7j_xLnZ2vat_NvE1I0bsOFw,57490
|
|
11
11
|
bizyengine/bizy_server/stream_response.py,sha256=H2XHqlVRtQMhgdztAuG7l8-iV_Pm42u2x6WJ0gNVIW0,9654
|
|
12
12
|
bizyengine/bizy_server/utils.py,sha256=Kkn-AATZcdaDhg8Rg_EJW6aKqkyiSE2EYmuyOhUwXso,3863
|
|
13
|
-
bizyengine/bizyair_extras/__init__.py,sha256=
|
|
13
|
+
bizyengine/bizyair_extras/__init__.py,sha256=8WBnjvNTDOJoME-lWMUmr51WRqW4UJHCnq1KoUVpVWk,1151
|
|
14
14
|
bizyengine/bizyair_extras/nodes_advanced_refluxcontrol.py,sha256=cecfjrtnjJAty9aNkhz8BlmHUC1NImkFlUDiA0COEa4,2242
|
|
15
15
|
bizyengine/bizyair_extras/nodes_cogview4.py,sha256=Ni0TDOycczyDhYPvSR68TxGV_wE2uhaxd8MIj-J4-3o,2031
|
|
16
16
|
bizyengine/bizyair_extras/nodes_comfyui_detail_daemon.py,sha256=i71it24tiGvZ3h-XFWISr4CpZszUtPuz3UrZARYluLk,6169
|
|
@@ -40,6 +40,7 @@ bizyengine/bizyair_extras/nodes_trellis.py,sha256=GqSRM8FobuziOIxwyAs3BLztpjVIP4
|
|
|
40
40
|
bizyengine/bizyair_extras/nodes_ultimatesdupscale.py,sha256=-_SsLTAWAQDv4uw-4Z7IGP2tXTe73BJ3N5D6RqVVAK4,4133
|
|
41
41
|
bizyengine/bizyair_extras/nodes_upscale_model.py,sha256=lrzA1BFI2w5aEPCmNPMh07s-WDzG-xTT49uU6WCnlP8,1151
|
|
42
42
|
bizyengine/bizyair_extras/nodes_utils.py,sha256=whog_tmV-q7JvLEdb03JL3KKsC7wKe3kImzx_jPaQD8,2613
|
|
43
|
+
bizyengine/bizyair_extras/nodes_wan_api.py,sha256=YZLGENaEtsyHjMOblbfMuweAV1N86r3hEXohFzaMqUI,11037
|
|
43
44
|
bizyengine/bizyair_extras/nodes_wan_i2v.py,sha256=3XwcxLHmgrihgXDEzcVOjU6VjqnZa3mErINlY014PFA,8435
|
|
44
45
|
bizyengine/bizyair_extras/nodes_wan_video.py,sha256=aE2JBF0ZT-6BOM0bGu9R4yZ_eMeMnnjCW-YzFe4qg8Q,2804
|
|
45
46
|
bizyengine/bizyair_extras/route_bizyair_tools.py,sha256=EiP5pS6xoE3tULoNSN2hYZA29vgt7yCErsbRp34gGEg,3898
|
|
@@ -47,6 +48,8 @@ bizyengine/bizyair_extras/nodes_ipadapter_plus/__init__.py,sha256=ECKATm_EKi_4G4
|
|
|
47
48
|
bizyengine/bizyair_extras/nodes_ipadapter_plus/nodes_ipadapter_plus.py,sha256=lOKRem7oiPs8ZkA_p68HxagAgiCSvn3Rk-L4fSXIjyE,54846
|
|
48
49
|
bizyengine/bizyair_extras/nodes_kolors_mz/__init__.py,sha256=HsCCCphW8q0SrWEiFlZKK_W2lQr1T0UJIJL7gEn37ME,3729
|
|
49
50
|
bizyengine/bizyair_extras/oauth_callback/main.py,sha256=KQOZWor3kyNx8xvUNHYNMoHfCF9g_ht13_iPk4K_5YM,3633
|
|
51
|
+
bizyengine/bizyair_extras/utils/aliyun_oss.py,sha256=NBC8tB_xG33X9nAuoSzzgkN2VHSOpEMqOH8wTIAERCE,2407
|
|
52
|
+
bizyengine/bizyair_extras/utils/audio.py,sha256=cCmX080jtxsHFa7mCgn13R6cyfqE-1Gq37ZnRJdZNU8,3183
|
|
50
53
|
bizyengine/bizybot/__init__.py,sha256=NINN_7QECKQwtAwKPBTrrSiAK6KbxaZCkIvJ-e1J1xk,262
|
|
51
54
|
bizyengine/bizybot/client.py,sha256=PWdcjslMaW4xmNaAq3TwRGV8twg9yPEfDNyfuZzpCyY,26029
|
|
52
55
|
bizyengine/bizybot/config.py,sha256=F2uN-2z-VGDtwe0aK8mDQ6-2wzRzy6EI0gH7i8UkoPU,4398
|
|
@@ -92,7 +95,7 @@ bizyengine/misc/route_sam.py,sha256=-bMIR2QalfnszipGxSxvDAHGJa5gPSrjkYPb5baaRg4,
|
|
|
92
95
|
bizyengine/misc/segment_anything.py,sha256=wNKYwlYPMszfwj23524geFZJjZaG4eye65SGaUnh77I,8941
|
|
93
96
|
bizyengine/misc/supernode.py,sha256=STN9gaxfTSErH8OiHeZa47d8z-G9S0I7fXuJvHQOBFM,4532
|
|
94
97
|
bizyengine/misc/utils.py,sha256=CKduySGSMNGlJMImHyZmN-giABY5VUaB88f6Kq-HAV0,6831
|
|
95
|
-
bizyengine-1.2.
|
|
96
|
-
bizyengine-1.2.
|
|
97
|
-
bizyengine-1.2.
|
|
98
|
-
bizyengine-1.2.
|
|
98
|
+
bizyengine-1.2.54.dist-info/METADATA,sha256=T3YaW_I4Gyx6grUJxVyVDddsKpv7E6Jglf8QblmnSn0,734
|
|
99
|
+
bizyengine-1.2.54.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
100
|
+
bizyengine-1.2.54.dist-info/top_level.txt,sha256=2zapzqxX-we5cRyJkGf9bd5JinRtXp3-_uDI-xCAnc0,11
|
|
101
|
+
bizyengine-1.2.54.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|