The prior implementation made a best effort to continue in the event of
an error, but immediately threw an error afterwards since there was no
output from the subprocess.
As get_audio isn't called until the audio connection from a Load Video
is used, it's safe to raise an exception here and properly expose the
error message from ffmpeg as is done elsewhere.
See #250
Executable preference is
VHS_YTDL environment variable > yt-dlp > youtube-dl
Downloaded videos are cached in temp so they are not preserved between
reboots
Both Load Video (Path) and Load Audio (Path) are supported
Known issues:
- need legacy node to convert from AUDIO to VHS_AUDIO
- add js to automate adding said node to workflows?
- need to parse number of channels when loading audio
All path stripping is now performed by a dedicated strip_path function.
First all whitespace is stripped, then a single double-quote is stripped
from the start and end of the path. Subsequent double quotes or white
space inside of the quotes is maintained.
Fixed a number of places paths received no stripping
- Load Video (Path) execution
- Path queries
- Advanced Previews
- Load Audio
See #224
Since updating to Python12, I've been graced with warnings about
improper escape sequences. This change should make no functional
difference, but resolves the warnings.
While it made sense to quietly proceed when io nodes were rolled into
animate diff, the process of hiding unusable formats has caused frequent
confusion in addition to being a logic path that should not be formally
supported (imageio-ffmpeg is in requirements.txt so a lack of ffmpeg
is best considered an invalid install.)
While an angry warning was displayed on boot, this error message is
frequently missed by end users. Now, all format options are
displayed and, if an unusable format is selected, an error is raised
which provides a list of options for how to install ffmpeg
Additionally, an extra search path was added to run an ffmpeg executable
that is placed in the base ComfyUI directory. For those struggling with
virtual environments or the system path, this provides a third
installation option that works regardless of os, or venv and requires no
need for external configuration or environment variables.
See #188, among others.
Before, if an attempt is made to load audio from a media file that lacks
audio, an exception is raised which, inconveniently, is incorrectly
captured and handled by a higher level try-catch block.
Instead, exceptions in the ffmpeg call to extract audio from a file are
handled inside the get_audio function call and False is passed on
failure. False is used largely as a matter of convenience so that the
failed output is cached between runs and not re-executed
Since this output is cached, it's then easy to just check if audio
resolves to False and skip the code to embed audio (as if there was not
an audio input wired). This allows reuse of a single workflow that will
embed audio when it's available.
Resolves#153
In order to eliminate the issues related to old system versions of
ffmpeg, a system was added for ranking the suitability of available
ffmpeg versions. This has a fairly high startup cost, so it's now
skipped when only one option exists.
Adds support for a gifski_pass in video_formats and a gifski format
which utilizes it. Resolves#79
Much consideration was put into how best to implement this. Gifski does
not support piped input, and implementing such functionality is
infeasible as the ffmpeg library used by Gifski requires inputs be
physical files. Consequentially, an intermediate file of some sort is
required. While an implementation that would not require a prior ffmpeg
pass was investigated, the only viable intermediary format
between Pillow and Gifski's ffmpeg decoder is an animated png and gifski
will never pass this png to it's ffmpeg decoder as it sees the png
header and instead interprets the file as a single frame image.
js uses doubles for all numbers, as a result, the maximum number that
could be entered by the ui and still allow for functioning of
increment/decrement.
Of consideration, ComfyUI uses a lower cap of 2**50 for seeds
The hash function used for IS_CHANGED had particularly poor performance
characteristics when combined with the new batch functionality. The
larger video files take a while to scan through and the scan occurs for
every sub-batch step. Consequentially, hash calculation has an
exponential performance cost when batching larger videos.
calculate_file_hash has been changed to instead use the modified
timestamp on the file. In profiling this brought the time cost for a
single call to IS_CHANGED from ~600 ms to <1 ms
The 16bit-png format was not being matched by the file counter regex and
resulted repeat counter values when combined with Prune Outputs.
The regex has been relaxed to prevent this discrepancy.
Add a 16bit-png video_format which supports output transparency. Other
formats could be updated for similar capabilities, but are likely to
have issues with device support and unlikely to see widespread adoption.
Modifies the preview server code to properly parse and check for the
existence of sequence filenames.
After substantial rewriting, paths are declared as strings in the python
code, and converted to path widgets in the webui if they include an
option for vhs_path_extensions. resolves#104
VALIDATE_INPUT and IS_CHANGED for path nodes were rewritten and largely
consolidated in utils to accommodate validation of inputs not known before
execution.
Known issue: VALIDATE_INPUT is never called for load_audio which results
in error messages that aren't very helpful if a bad path is provided
An error is no longer immediately raised if ffmpeg is not found
Internal paths are now absolute for load images advanced previews
While I have previously shied away from using imageio-ffmpeg as the
default version because the included version is 4 years old and
specifically does not work with the av1 format, there have been specific
issues from people with a system version of ffmpeg that is even older.
There has been a longstanding desire to create a system for determining
the best version of ffmpeg, but this has proved a reasonably involved
task. Some version information uses git commit hashes instead of a
potentially sortable semvar and there are a large number of compile time
flags that could result in a newer binary having less functionality.
Thus a sysstem has been added that parses compile flags for desired
encoders as well as the copyright year to determine which ffmpeg version
is more feature full.
Support loop_count with videos, fixes#83
Add support for forcing usage of ffmpeg bundled with imageio by setting
VHS_USE_IMAGEIO_FFMPEG to ease testing and as a temporary fix for #80
When saving with metadata, if an error occurred after initialization, an
empty output video would be produced which caused the without metadata
retry to fail with a less helpful error message. Now, if the pass with
metadata failed, but produced an output file, that error is raised and
the retry does not occur. This should not change the effectiveness of
the fallback for those who were experiencing the metadata issue.
Basic support for loading urls has been added to Load Video.
Most of the work is made trivial by both ffmpeg and opencv automatically
fetching a url if it's provided instead of a path.
A more sophisticated fix for error passing from ffmpeg during preview
generation. If a request is aborted, the ffmpeg process is immediately
killed instead of being allowed to respond to stdin being closed and
waited on at the end of the with block
save_metadata is now a format flag
- This allows saving to different tag and hides for image formats
Implement high bit depth support
- Disabled by default, but works for images and has shown in testing to
produce objectively higher quality output than base Save Image
Fix target_size from load video not applying when 2 dimensions are set
When an input video is scaled to a new aspect ratio, it is now cropped
Removed try wrapping of load video nodes. This creates more confusion
now a system of fallbacks isn't used
A fix for parsing format_widgets when applied outside a '_pass'
Fixed missing import of logger in utils
Animated images are now included in the animated preview code
- This improves performance and allows for pausing
Cleaned up injection of code to load metadata
Audio settings are now stored in video_formats
Updated video_formats with reasonable defaults for audio
A Load Audio (Path) node has been added
Audio Loads are cached with load state and only occur once.