mirror of
https://github.com/vladmandic/automatic
synced 2026-09-20 01:31:13 +02:00
fix(processing): preserve pipeline audio across process_decode
process_decode strips video pipeline output to a flat list of frames at the PIL early-return (processing_diffusers.py:461-465), so any output.audio is lost before processing.process_images returns. video pipelines that produce synchronized audio (LTX-2 audio-capable models) were getting silent mp4s on the non-latent path. stash output.audio on p.audio_capture before process_decode runs and let processing read it back as a fallback when samples is a flat list. ltx_process non-latent branch strips the (B, 2, N) batch dim with [0] so write_audio's .T+contiguous() path produces interleaved bytes for AAC s16.
This commit is contained in:
@@ -360,8 +360,11 @@ def run_ltx(task_id,
|
||||
yield from abort('Video: process_images returned no frames', ok=True, p=p)
|
||||
return
|
||||
pixels = processed.images
|
||||
if getattr(processed, 'audio', None) is not None:
|
||||
audio = processed.audio
|
||||
raw_audio = getattr(processed, 'audio', None)
|
||||
if raw_audio is not None:
|
||||
# Strip batch dim from (B, 2, N); write_audio expects (2, N) for the
|
||||
# transpose-to-interleaved path used by AAC s16.
|
||||
audio = raw_audio[0].float().cpu() if raw_audio.ndim == 3 else raw_audio.float().cpu()
|
||||
latents = None
|
||||
except AssertionError as e:
|
||||
yield from abort(e, ok=True, p=p)
|
||||
|
||||
@@ -528,7 +528,7 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
|
||||
output_images.append(batch_image)
|
||||
infotexts.append(batch_infotext)
|
||||
|
||||
audio = getattr(samples, 'audio', None)
|
||||
audio = getattr(samples, 'audio', None) or getattr(p, 'audio_capture', None)
|
||||
|
||||
if shared.cmd_opts.lowvram:
|
||||
devices.torch_gc(force=True, reason='lowvram')
|
||||
|
||||
@@ -628,6 +628,10 @@ def process_diffusers(p: processing.StableDiffusionProcessing):
|
||||
timer.process.add('lora', lora_common.timer.total)
|
||||
lora_common.timer.clear(complete=True)
|
||||
|
||||
# process_decode flattens video output to a frame list and drops the audio attribute;
|
||||
# stash it on `p` so video pipelines can recover it after process_images returns.
|
||||
if output is not None and getattr(output, 'audio', None) is not None:
|
||||
p.audio_capture = output.audio
|
||||
results = process_decode(p, output)
|
||||
timer.process.record('decode')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user