Repository navigation
Conversation
With `-i DURATION[,MIN[,MAX]]`, each scene gets floor(length / DURATION) + 1 images instead of a fixed `-n`, clamped to [MIN, MAX] (default 1, no limit; an empty MIN or MAX uses the default, e.g. `-i 2s,,10`). The images are chosen the same way as with `-n`, including the frame margin. `-n` and `-i` are mutually exclusive, on the command line and in the config file. The API gets `interval`, `min_images` and `max_images` arguments on `save_images()`. `num_images` now defaults to None (3 unless `interval` is set) so that setting both can be rejected, and `min_images`/`max_images` are rejected without `interval`. Closes Breakthrough#280 Co-Authored-By: Claude Opus 5.5 <[email protected]>
Breakthrough
left a comment
There was a problem hiding this comment.
Thanks, this looks great! Appreciate you taking the time to kick this off.
I left a few comments - would like to understand the tradeoffs a bit better between the different CLI approaches we already discussed. I would be okay landing this as-is, so feel free to push back if you think this is the right way to go.
If possible, can you look into how other projects handle cases like this and if there's a standardized/recommended way to specify options such as this on a command line tool? Hopefully the comments and concerns I added are useful, let me know if you have any questions.
| metavar="DURATION[,MIN[,MAX]]", | ||
| default=None, | ||
| type=click.STRING, | ||
| help="Generate one image per DURATION of each scene instead of a fixed number, so longer scenes get more images. Each scene gets floor(length / DURATION) + 1 images, chosen the same way as with -n/--num-images. MIN and MAX limit the number of images per scene (default: 1, no limit). Leave MIN empty to only set MAX (-i 2s,,10). DURATION can be specified in frames (-i 24), in seconds with `s` suffix (-i 1.5s), or timecode (-i 00:00:01.500). Cannot be used with -n/--num-images.{}".format( |
There was a problem hiding this comment.
Do we need to support leaving MIN empty? Can we require it be declared? I'm assuming if we don't specify it just defaults to 1. I'm also curious, can we use nargs here or does that not work because of the subcommands?
E.g. it would be cool if we made -i take 1/2/3 args conditionally using spaces as separators rather than requiring commas. Not sure how much effort that would be though, so happy to punt on this if it becomes a rabbit hole - just curious as to your thoughts.
Context: It's possible in some locales timecodes use commas, so eventually we might need to support that. The key word being eventually though, which is why for today I'd say this is optional, but I do want to explore what options we have and the tradeoffs for each before shipping something.
| duration_secs = max((end - start).seconds, 0.0) | ||
| # The epsilon keeps a scene that is a whole number of intervals long from getting one | ||
| # image less due to floating point error. | ||
| scene_images = max(math.floor(duration_secs / interval_secs + 1e-9) + 1, min_images) |
There was a problem hiding this comment.
Please use a named constant for this (we might have an epsilon value declared elsewhere as well).
Closes #280
Adds
-i/--intervaltosave-images, as discussed in #280, so the number of images per scene depends on its length:Each scene gets
floor(scene length / DURATION) + 1images, clamped to[MIN, MAX](default 1 and no limit; an empty MIN or MAX uses its default). The images are chosen the same way as with-n, so the first and last frames are included and the frame margin applies. DURATION takes the same formats as-m/--frame-margin: frames (24), seconds (1.5s), or a timecode (00:00:01.500).Design notes
-i 2s,1,10. The config file accepts the same format (spaces after the commas are fine):interval = 2s, 1, 10. If you'd rather have separate--min-images/--max-imagesoptions, that's an easy change.-nand-iare mutually exclusive: setting both on the command line is an error, and so is setting bothnum-imagesandintervalin the config file. An option given on the command line takes precedence over the config file:-noverridesinterval, and-ioverridesnum-images.save_images()getsinterval,min_imagesandmax_imagesarguments. To rejectnum_imagesandintervaltogether, the default fornum_imagesis nowNone, which means 3 unlessintervalis set. Existing calls behave the same.min_imagesandmax_imagesare rejected withoutinterval.$IMAGE_NUMBERpadding and the progress bar total use the actual image counts.save-htmlalready handles a different number of images per scene.-ndoes the same, so I left it alone.Tests
tests/test_output.py: image counts per scene for frame, second and timecode intervals, with and without MIN/MAX, on both the threaded and non-threaded paths; invalid arguments raiseValueError.tests/test_cli.py: parsing ofDURATION[,MIN[,MAX]]and its error messages;-iend to end with each format and with MIN/MAX;-nwith-iand invalid values fail with the expected message; theintervalconfig option, including invalid values, thenum-imagesconflict, and precedence between the command line and the config file. The new error checks run in-process.docs/cli.rstmatches the output ofdocs/generate_cli_docs.pyforsave-images, andscenedetect.cfgand the changelog are updated.🤖 Generated with Claude Code