mirror of
https://git.datalinker.icu/comfyanonymous/ComfyUI
synced 2026-09-06 11:47:03 +08:00
Improve audio upload utils (#128)
This commit is contained in:
parent
3a04204713
commit
7ead535d46
@ -361,7 +361,7 @@ def upload_video_to_comfyapi(
|
|||||||
Uses the specified container and codec for saving the video before upload.
|
Uses the specified container and codec for saving the video before upload.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
video: Input VideoInput object.
|
video: VideoInput object (Comfy VIDEO type).
|
||||||
auth_token: Optional authentication token.
|
auth_token: Optional authentication token.
|
||||||
container: The video container format to use (default: MP4).
|
container: The video container format to use (default: MP4).
|
||||||
codec: The video codec to use (default: H264).
|
codec: The video codec to use (default: H264).
|
||||||
@ -394,47 +394,41 @@ def upload_video_to_comfyapi(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def upload_audio_to_comfyapi(
|
def audio_tensor_to_contiguous_ndarray(waveform: torch.Tensor) -> np.ndarray:
|
||||||
audio: AudioInput,
|
|
||||||
auth_token: Optional[str] = None,
|
|
||||||
) -> str:
|
|
||||||
"""
|
"""
|
||||||
Uploads a single audio input to ComfyUI API and returns its download URL.
|
Prepares audio waveform for av library by converting to a contiguous numpy array.
|
||||||
Encodes the raw waveform into MP4/AAC format before uploading.
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
audio: Input AudioInput object (containing waveform tensor and sample_rate).
|
waveform: a tensor of shape (1, channels, samples) derived from a Comfy `AUDIO` type.
|
||||||
auth_token: Optional authentication token.
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The download URL for the uploaded audio file.
|
Contiguous numpy array of the audio waveform. If the audio was batched,
|
||||||
|
the first item is taken.
|
||||||
"""
|
"""
|
||||||
waveform: torch.Tensor = audio["waveform"]
|
if waveform.ndim != 3 or waveform.shape[0] != 1:
|
||||||
sample_rate: int = audio["sample_rate"]
|
raise ValueError("Expected waveform tensor shape (1, channels, samples)")
|
||||||
|
|
||||||
# If batch is > 1, take first item
|
# If batch is > 1, take first item
|
||||||
if waveform.shape[0] > 1:
|
if waveform.shape[0] > 1:
|
||||||
waveform = waveform[0]
|
waveform = waveform[0]
|
||||||
|
|
||||||
# Check waveform tensor shape
|
# Prepare for av: remove batch dim, move to CPU, make contiguous, convert to numpy array
|
||||||
if waveform.ndim != 3 or waveform.shape[0] != 1:
|
audio_data_np = waveform.squeeze(0).cpu().contiguous().numpy()
|
||||||
raise ValueError("Expected waveform tensor shape (1, channels, samples)")
|
|
||||||
|
|
||||||
# Prepare data for av library
|
|
||||||
audio_data_np = waveform.squeeze(0).cpu().numpy()
|
|
||||||
if audio_data_np.dtype != np.float32:
|
if audio_data_np.dtype != np.float32:
|
||||||
audio_data_np = audio_data_np.astype(np.float32)
|
audio_data_np = audio_data_np.astype(np.float32)
|
||||||
|
|
||||||
# Ensure the array is C-contiguous
|
return audio_data_np
|
||||||
if not audio_data_np.flags["C_CONTIGUOUS"]:
|
|
||||||
audio_data_np = np.ascontiguousarray(audio_data_np)
|
|
||||||
|
|
||||||
# Default to MP4/AAC
|
|
||||||
container_format = "mp4"
|
|
||||||
codec_name = "aac"
|
|
||||||
upload_mime_type = "audio/mp4"
|
|
||||||
filename = "uploaded_audio.mp4"
|
|
||||||
|
|
||||||
|
def audio_ndarray_to_bytesio(
|
||||||
|
audio_data_np: np.ndarray,
|
||||||
|
sample_rate: int,
|
||||||
|
container_format: str = "mp4",
|
||||||
|
codec_name: str = "aac",
|
||||||
|
) -> BytesIO:
|
||||||
|
"""
|
||||||
|
Encodes a numpy array of audio data into a BytesIO object.
|
||||||
|
"""
|
||||||
audio_bytes_io = io.BytesIO()
|
audio_bytes_io = io.BytesIO()
|
||||||
with av.open(audio_bytes_io, mode="w", format=container_format) as output_container:
|
with av.open(audio_bytes_io, mode="w", format=container_format) as output_container:
|
||||||
audio_stream = output_container.add_stream(codec_name, rate=sample_rate)
|
audio_stream = output_container.add_stream(codec_name, rate=sample_rate)
|
||||||
@ -453,12 +447,38 @@ def upload_audio_to_comfyapi(
|
|||||||
for packet in audio_stream.encode(None):
|
for packet in audio_stream.encode(None):
|
||||||
output_container.mux(packet)
|
output_container.mux(packet)
|
||||||
|
|
||||||
audio_bytes_io.seek(0) # Reset buffer position for reading
|
audio_bytes_io.seek(0)
|
||||||
|
return audio_bytes_io
|
||||||
|
|
||||||
return upload_file_to_comfyapi(
|
|
||||||
audio_bytes_io, filename, upload_mime_type, auth_token
|
def upload_audio_to_comfyapi(
|
||||||
|
audio: AudioInput,
|
||||||
|
auth_token: Optional[str] = None,
|
||||||
|
container_format: str = "mp4",
|
||||||
|
codec_name: str = "aac",
|
||||||
|
mime_type: str = "audio/mp4",
|
||||||
|
filename: str = "uploaded_audio.mp4",
|
||||||
|
) -> str:
|
||||||
|
"""
|
||||||
|
Uploads a single audio input to ComfyUI API and returns its download URL.
|
||||||
|
Encodes the raw waveform into the specified format before uploading.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
audio: a Comfy `AUDIO` type (contains waveform tensor and sample_rate)
|
||||||
|
auth_token: Optional authentication token.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The download URL for the uploaded audio file.
|
||||||
|
"""
|
||||||
|
sample_rate: int = audio["sample_rate"]
|
||||||
|
waveform: torch.Tensor = audio["waveform"]
|
||||||
|
audio_data_np = audio_tensor_to_contiguous_ndarray(waveform)
|
||||||
|
audio_bytes_io = audio_ndarray_to_bytesio(
|
||||||
|
audio_data_np, sample_rate, container_format, codec_name
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return upload_file_to_comfyapi(audio_bytes_io, filename, mime_type, auth_token)
|
||||||
|
|
||||||
|
|
||||||
def upload_images_to_comfyapi(
|
def upload_images_to_comfyapi(
|
||||||
image: torch.Tensor, max_images=8, auth_token=None, mime_type: Optional[str] = None
|
image: torch.Tensor, max_images=8, auth_token=None, mime_type: Optional[str] = None
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user