_save_transcoded had no subtitle output path, so every stream was dropped
whenever save_to re-encoded: both on the explicit format/codec/trim route and
on the fallback out of _save_remuxed. Compatible subtitles survived a remux and
vanished the moment anything forced a transcode.
Subtitle streams are now carried through untouched, rebased onto the same
trimmed timeline as the video and clipped to the trim window. There is no
subtitle encoder binding in PyAV, so a stream the output container cannot store
as-is is still dropped -- but named in a warning, matching what _save_remuxed
already does rather than disappearing silently.
The remux fallback warning no longer claims subtitles are dropped, because the
transcode it hands off to now keeps the ones it can.
A WebM source with format=MP4 never entered the remux path: "mp4" is
absent from the source demuxer's name, so the pre-existing
reuse_streams guard already forced a transcode and the test passed
against an unfixed tree. A mov source carrying pcm_u8 keeps
reuse_streams true and is refused by the mp4 muxer, which is the case
the test was meant to describe, and it is the only test that reaches
the BytesIO truncate.
Also decode the outputs rather than trusting stream headers, encode the
audio-fallback source as mpeg4 so the h264 assertion distinguishes a
re-encode from a copy, stop pinning the mp4 demuxer's full alias list,
and skip rather than error when a build lacks an encoder the sources
need.
The transcode fallback needs a video stream, so an audio-only source
whose codec the destination cannot store failed with "No video stream
found in file", hiding the codec that actually stopped the save.
OutputContainer.supported_codecs only keeps codecs for which
avformat_query_codec returns 1, while add_stream_from_template rejects
only a falsy result. Muxers that implement neither a query_codec
callback nor a codec_tag table return AVERROR_PATCHWELCOME, so they
accept a stream copy that supported_codecs reports as impossible: an
h264 mpegts source saved with format=auto was fully re-encoded and
silently rehoused in mp4.
Attempt the copy and let PyAV answer instead. All streams are added
before the first packet is muxed, so a stream the destination rejects
is caught before anything is written. Handling it per stream also means
a subtitle track the destination cannot store is dropped on its own
rather than diverting the video alongside it into a needless re-encode.
Log the whole-file re-encode at warning, since it is lossy and discards
the extra audio and subtitle streams the transcode path does not carry.
Saving a VP8 WebM with format=auto named the file .mp4 and then stream
copied VP8 into it, which PyAV rejects. Check the destination muxer's
supported codecs before copying and fall back to re-encoding when any
source stream cannot be stored.
preview_url was assembled from a /api/view link whose type was chosen by
matching the asset's tags against "input" then "output". Anything written
anywhere else - temp above all, where preview nodes put their images - fell
off the end of that chain and came back with no preview at all. Tags are
user-editable, so removing one also silently destroyed the URL.
Derive the URL from where the file actually sits instead. That covers every
root /api/view serves, temp included, and no longer depends on tags or on a
filename in user_metadata. A file outside those roots, or content no client
can render from its own bytes, gets no preview URL rather than one that
cannot work.
Nominated previews are resolved a page at a time rather than per row, so a
list costs one extra query however long it is. A preview that is soft-deleted
or not visible to the caller drops out of that lookup and is no longer
advertised.
Co-authored-by: guill <jacob.e.segal@gmail.com>
* Keep temp-directory assets visible while their files exist
Assets written to the temp directory were flagged as missing and dropped
from GET /api/assets, even with the file sitting on disk. One list of
directories was answering two different questions -- where the scanner
looks for new files, and which files ComfyUI considers its own -- and
temp belongs only in the second, so every temp reference was disowned by
the prune that runs at startup and on POST /api/assets/prune.
Ownership now covers temp. Discovery still does not: the temp directory
is wiped before the scan runs, and assets written there are already
registered with a hash, mime type and dimensions, so walking it would
find nothing. Temp references are instead reconciled against the
filesystem directly, so a temp file that really is gone is still retired
rather than lingering as a broken entry.
get_prefixes_for_root becomes get_scan_prefixes_for_root so the two
questions are told apart by name rather than by comment.
* Cover the unhashed temp asset in the reconciliation tests
The existing temp tests all registered hashed assets, so they never
exercised the path an unhashed asset takes when its file is gone: the
orphaned rows are removed rather than kept as missing, exactly as under
any other root.
* Stop adding an opaque alpha channel to API node images
bytesio_to_image_tensor converted every downloaded image to RGBA, so nodes
whose API returns no transparency still emitted a 4 channel IMAGE. Keep the
alpha when the decoded image has one, stay RGB when it does not.
---------
Signed-off-by: bigcat88 <bigcat88@icloud.com>
Co-authored-by: bigcat88 <bigcat88@icloud.com>