VCS 1.13.4 released

Prompted by a couple reports, here's a new bugfix release of VCS. It most importantly fixes an incompatibility with Bash 5.0 which made the script put all the captures in a single row.

A couple minor bugs are also fixed, where using mawk would produce some errors and print the wrong file sizes, and the evasion offsets (which are used to avoid blank screengrabs) weren't really being used.

See the full changelog for more details.

vcs 1.13.4
vcs-1.13.4.gz (script only)
vcs-1.13.4.tar.gz (script, sample configuration, manpage and profiles)
deb, rpm, PKGBUILD & xz
as usual at

Discover more from OutlyerNet

Subscribe to get the latest posts to your email.

39 thoughts on “VCS 1.13.4 released”

  1. I was looking for a similar tool for some time.
    I had to modify it a bit according to my needs.
    It was easy with almost zero BASH knowledge as the script is very well-organized.
    Thank you, tip granted!

    1. Thank you! I did my best to keep it organized and documented since it's a fairly complex and big script, I'm glad that was useful for someone else. If you think your modifications can be of use to others I'm always open to suggestions and patches.

  2. Hello Toni,
    sorry i just saw your reply now. 🙁
    I modified script behavior if output file exists.
    I use another bash script to invoke VCS for every video file on a folder recursively and for me it was handy to add an option to keep already existing output to reduce overall runtime.
    I send you the modified script via e-mail and you can decide if it is useful or not.
    Also i failed to find out where to add jpeg quality settings to reduce jpeg output sheet size. I think this feature would be useful as well.
    Thank you again for this great – and free – tool! 🙂

  3. Excellent! 🙂
    I am happy again, that I now can continue using the -S option, and that the Footer has finally returned.
    However, some new thing seems to have entered the realm of vcs: -T pc3
    I replaced the line "if [[ 8 = "$(tput -T pc3 colors)" ]]; then" with the line "if [[ 8 = "$(tput colors)" ]]; then" and colors returned. Before the change I always got the error: "tput: unknown terminal "pc3""
    The system I run the vcs script on is old, very old, so it has no knowledge of updated Terminal versions, if that might be the case.
    The code though, seems to me that you only need to compare the number 8 with how many colors the Terminal actually supports, and in my case that's 8. What the -T option has got to do with anything, I am not sure. Something more modern perhaps? Or has it something to do with your system? Personally I could live without the colors. They are not necessary for the functionality of the application.
    Anyway, great work! 🙂

    1. Thank you for your input. Getting tput to produce consistent output across different OSes is harder than I'd like and it involved some hair pulling when dealing with BSDs, so that may be the source of the pc3 type, I honestly can't remember right now.
      Nonetheless, I'm taking note of this for further testing.
      Best Regards.

  4. Thomas Palm

    I used vcs-1.13.2 for a long time, but after my system upgrade the media info on the upper right side shifted out from the contact-sheet.
    I upgraded to vcs-1.13.4 but it would not run as a script starting from my filebrowser (this is handy to right-click a file, start vcs and get an easy contactsheet for the file)
    As I found out the problem is the tput detection:
    "stty: 'standard input': Inappropriate ioctl for device"
    "tput: No value for $TERM and no -T specified"

    I went back to the old detection, pasted/replaced it into the new script and now it is working again:
    I thought I let you know. Perhaps you can improve your new detection to run without exiting if no Terminal is found.

    # Initialises the variables affecting colourised feedback
    init_feedback() {
    	# tput might be preferable (Linux: man console_codes), but it doesn't
    	# work on FreeBSD to set colors
    	# Is tput available?
    	if type -pf tput >/dev/null ; then
    		# Is it able to set colours?
    		if tput bold && tput setaf 0 && tput sgr0 ; then
    			PREFIX_ERR=$(tput bold; tput setaf 1)
    			PREFIX_WARN=$(tput bold; tput setaf 3)
    			PREFIX_INF=$(tput bold; tput setaf 2)
    			PREFIX_DBG=$(tput bold; tput setaf 4)
    			SUFFIX_FBACK=$(tput sgr0)
    		fi >/dev/null
    	if [[ -z $HAS_COLORS ]]; then
    		# tput was not an option, let's try ANSI escape codes instead [[AEC]]
    		# TODO: Detect support
    		# Alternatively: $ perl -e 'print "\e[31m\e[1m"'
    		# echo -e is not portable but echo $'' is bash-specific so it should be fine...
    		# except when ANSI escape codes aren't supported of course
    		PREFIX_ERR=$(echo $'\033[1m\033[31m')
    		PREFIX_WARN=$(echo $'\033[1m\033[33m')
    		PREFIX_INF=$(echo $'\033[1m\033[32m')
    		PREFIX_DBG=$(echo $'\033[1m\033[34m')
    		SUFFIX_FBACK=$(echo $'\033[0m')
    	# Finally, if there's no colour support, use prefixes instead
    	if [[ -z $HAS_COLORS ]]; then
    1. It definitely can be improved. As I replied above I ended up with some solution that seemed to work across systems at the time but it wasn't that solid, obviously.
      Thank you for your feedback, I'm taking note to refine it further.

  5. It seems the version 1.13.4 jumps over the function that was there in earlier versions (if memory serves me), the function that corrected timing for "decimal seconds". If a thumbnail landed on, say 05:24.100, the script corrected that to 05:25.00. But now it is left as an exercise to the reader to figure out what that 05:24.100 means. 🙂
    Not a big problem, it just looks a little weird with three digits instead of the "normal" two. I put that in quotes since nothing in 2020 so far has been "normal".
    Live well and prosper, and breathe carefully when you're out there. 😉

    1. I'm not sure what you mean, I can't remember having such correction, timestamps are explicitly printed with two decimals. I'm getting two decimals on my system, maybe it is some weird interaction with a newer version of some package?
      There was no rounding either as you seem to imply, the closest I can think of is when using MPlayer as capturer seeking doesn't have such precision. You can force using MPlayer with the -M switch if you prefer that behaviour.

    1. I've haven't encountered such problem yet, and it sounds fairly weird.

      You may try editing the script and adding -depth 8 to the final big convert command (on line 4135 in version 1.13.4) and see if that does the trick.

  6. Would it be possible to somehow specify to only screenshot half of the video image (for 180 side-by-side VR videos)?

    Or would this require new features to be added to the VCS?

  7. Hi,

    I was getting:
    Detected video length can't be reached. Safe measuring enabled.
    On a video with a length that was not an integer (it has N.51 seconds).

    The script did look at other length and produced a screensheet but I figured that a fractional second is probably not that useful so getting rid of it would get rid of the warning.
    So I slightly modified your script to get rid of it and it worked.
    I got some captured image off by a couple millisecond between the original version and the no fractional second version when there are only a few captured images, as is to be expected, but for me it worked well.

    In case you are interested, the diff for it is:

    --- vcs-1.13.4.bash     2019-11-26 19:15:09.000000000 +0000
    +++       2021-08-02 11:54:35.678398720 +0100
    @@ -3385,6 +3385,8 @@
                            VID[$LEN]=$(max $fflen $mplen)
                            delta=$QUIRKS_LEN_THRESHOLD # Ensure it's considered inconsistent
    +               # Get rid of any fractional seconds
    +               VID[$LEN]=${VID[$LEN]%.*}
                    # If they differ too much, enter safe mode. If one reports 0, they'll differ...
                    # FIXME: If $DECODER reports 0, can it seek??
                    if fptest "$delta" -ge $QUIRKS_LEN_THRESHOLD ; then
    1. Reaching the end shouldn't be affected by fractional seconds, so this may hint at other problems. I'm taking note of this, thank you for your contribution!

      1. (Output from a different video but has the same problem)

        Video Contact Sheet *NIX v1.13.4, (c) 2007-2019 Toni Corvera
        Testing internal consistency...
        Passed test (seq replacement): consistent result
        Passed test (Identity): 'rmultiply 1,1 1'.
        Passed test (Rounding): 'rmultiply 16/9,1 2'.
        Passed test (Rounding): 'rmultiply 4/3 1'.
        Passed test (Commutative property): 'rmultiply 1,16/9 2'.
        Passed test (Alternate syntax): 'rmultiply 1.7 2'.
        Passed test (unnamed): 'ceilmultiply 1,1 1'.
        Passed test (unnamed): 'ceilmultiply 4/3 2'.
        Passed test (unnamed): 'ceilmultiply 7,1/2 4'.
        Passed test (Alternative syntax): 'ceilmultiply 7/2 4'.
        Passed test (Commutative property): 'ceilmultiply 1/2,7 4'.
        Passed test (Padding): 'pad 10 0 0000000000'.
        Passed test (Unneeded padding): 'pad 1 20 20'.
        Passed test (Floating point padding): 'pad 5 23.3 023.3'.
        Passed test (DVD AR Guess): 'guess_aspect 720 576 4/3'.
        Couldn't guess aspect ratio.
        Passed test (Unsupported Wide AR Guess): 'guess_aspect 1024 576 1024/576'.
        Passed test (lowercase conversion): 'tolower ABC abc'.
        Passed test (Integer pythagorean theorem): 'pyth_th 4 3 5'.
        Passed test (FP pythagorean theorem): 'pyth_th 16 9 18.35755975068581946630'.
        Passed test (Hours parsing): 'get_interval 2h 7200'.
        Passed test (Minutes parsing): 'get_interval 2m 120'.
        Passed test (Seconds parsing): 'get_interval 30S 30'.
        Passed test (Milliseconds parsing): 'get_interval .30 .30'.
        Passed test (Parsing with leading zeroes): 'get_interval 09h010m09s1 33010'.
        Passed test (Parsing shorthand): 'get_interval 0400 400'.
        Passed test (Repeated minutes parsing): 'get_interval 30m30m1h 7200'.
        Passed test (Leading zeroes in file size (GiB)): 'get_pretty_size 1127428915 1.05 GiB'.
        Passed test (Leading zeroes in file size (MiB)): 'get_pretty_size 1132462 1.08 MiB'.
        Passed test (Leading zeroes in file size (KiB)): 'get_pretty_size 1116 1.09 KiB'.
        Passed test (Pretty-printed file size (GiB)): 'get_pretty_size 1889785610 1.76 GiB'.
        Passed test (Pretty-printed file size (MiB)): 'get_pretty_size 762650296 727.32 MiB'.
        Passed test (Pretty-printed file size (KiB)): 'get_pretty_size 524810 512.51 KiB'.
        Passed test (FP test): 'fptest 3 -eq 3; returns 0'.
        Passed test (FP test): 'fptest 3.2 -gt 1; returns 0'.
        Passed test (FP test): 'fptest 1/2 -le 2/3; returns 0'.
        Passed test (FP test): 'fptest 6.34 -gt 6.34; returns 1'.
        Passed test (FP -logical- test): 'fptest (1>0) -eq 1; returns 0'.
        Passed test (Numeric recognition): 'is_number 3; returns 0'.
        Passed test (Quoted numeric recognition): 'is_number '3'; returns 1'.
        Passed test (Non-numeric recognition): 'is_number 3.3; returns 1'.
        Passed test (Float recognition): 'is_float 3.33; returns 0'.
        Passed test (Float recognition): 'is_float 3; returns 0'.
        Passed test (Non-float recognition): 'is_float 1/3; returns 1'.
        Passed test (Fraction recognition): 'is_fraction 1/1; returns 0'.
        Passed test (Non-fraction recognition): 'is_fraction 1; returns 1'.
        Passed test (Non-fraction recognition): 'is_fraction 1.1; returns 1'.
        Passed test (Positive recognition): 'is_pos_or_percent 33; returns 0'.
        Passed test (Percent recognition): 'is_pos_or_percent 33%; returns 0'.
        Passed test (Percent recognition): 'is_pos_or_percent 4/4%; returns 1'.
        Passed test (Percent recognition): 'is_pos_or_percent %; returns 1'.
        All tests passed
        Command line: /home/user/bin/vcs-1.13.4.bash -DD Walking_Polperro_Cornwall_UK_2021_Village_and_Harbour_Tour-B0UWmWMubLc.mp4 -U0 -c 3 -o Walking_Polperro_Cornwall_UK_2021_Village_and_Harbour_Tour-B0UWmWMubLc.mp4.jpg
        [TRACE]: pick_tools 
        [TRACE]: set_capturer ffmpeg 0
        [ svn $Rev: 688 $ ]
        === Setup ===
        GETOPT:             /usr/bin/getopt
        FFMPEG:             /usr/bin/ffmpeg
        AWK:                /usr/bin/gawk
        sed:                /bin/sed
        POSIXLY_CORRECT:    {not set}
        Capturers (av.):    [ ffmpeg ]
        Identif. (av.):     [ ffmpeg ]
        Capturer:           ffmpeg
        Chosen capturer:    {default}
        Filterchain:        [ filt_resize filt_apply_stamp filt_softshadow ]
        Safe step:          0.5
        Blank evasion:      Enabled (-5 +5 -10 +10 -30 +30)
        === Versions ===
        Bash:               5.1.4(1)-release
        Getopt:             getopt from util-linux 2.36.1
        AWK:                GNU Awk 5.1.0, API: 3.0 (GNU MPFR 4.1.0, GNU MP 6.2.1)
        sed:                sed (GNU sed) 4.7
        FFMpeg:             ffmpeg version 4.3.2-0+deb11u2 Copyright (c) 2000-2021 the FFmpeg developers / libavcodec 58. 91.100 / 58. 91.100
        ImageMagick:        ImageMagick 6.9.11-60 Q16 x86_64 2021-01-25
        LSB Description:    Debian GNU/Linux 11 (bullseye)
    1. Sorry for the delay in aproving the message, I missed it. I can confirm the latest version of ImageMagick produces such warnings, I'll look into it.

      1. With the new script I'm getting issues the following error:
        No compatible version of getopt in path, can't continue.
        Enhanced getopt (i.e. GNU getopt) is required

      2. I observe the same issue as KW with the trunk version you linked above.

        The issue is on line 186. Brew version has this:
        declare GETOPT=/usr/local/opt/gnu-getopt/bin/getopt

        The trunk version has:
        declare GETOPT=getopt

        When I backport the most important change you did in the trunk version (`fx:image.mean` > `fx:mean`) then indeed the error messages on .mean*100 are gone.

  8. The homebrew's version of vcs has this at line 186:
    declare GETOPT=/opt/homebrew/opt/gnu-getopt/bin/getopt

    While Toni's just uses whatever is on path:
    declare GETOPT=getopt

    … which on macOS is non-gnu version of getopt.

  9. Recently got an update of ImageMagick:
    $ magick –version
    Version: ImageMagick 7.1.1-33 Q16-HDRI x86_64 22263
    Copyright: (C) 1999 ImageMagick Studio LLC
    Features: Cipher DPC HDRI Modules OpenCL OpenMP(4.5)
    Delegates (built-in): bzlib cairo djvu fftw fontconfig freetype heic jbig jng jp2 jpeg jxl lcms lqr ltdl lzma openexr pangocairo png raqm raw rsvg tiff webp wmf x xml zip zlib zstd
    Compiler: gcc (14.1)
    Because of that, the "convert" command now gives a deprecation warning:
    WARNING: The convert command is deprecated in IMv7, use "magick"
    Trying to do that, replacing all the calls to 'convert' for 'magick', the temp images seem to be problematic (I've added a few printouts of the suspected code blocks):
    [i] Capturing in range [04:49.49-19:17.95]. Total length: 20:25.35
    [i] Generating capture #1/4 (04:49.49)…
    magick: no images found for operation `-geometry' at CLI arg 7 @ error/operation.c/CLIOption/5479.
    magick: magick -background 'transparent' -fill 'transparent' '/dev/shm/vcs.SGteWR/vcs-ZQ0dJj-cap-000001.png' \( -geometry 267×200! \) -flatten \( -box '#000000aa' -fill 'White' -stroke none -pointsize '9' -gravity 'SouthEast' -font '/usr/share/fonts/TTF/DejaVuSans.ttf' -strokewidth 3 -annotate +5+5 ' 04:49.49 ' \) -flatten -gravity None -flatten \( -background black +clone -shadow 50×2+4+4 -background none \) +swap -flatten -trim +repage -flatten '/dev/shm/vcs.SGteWR/vcs-zQhKDd.png'
    If I try to cp those two temp images on the line below the 'magick' command, they become 0 byte files.

    The video renderer ffmpeg has also gone through a couple of steps of upgrades over the years, I now have:
    $ ffmpeg -version
    ffmpeg version n6.1.1 Copyright (c) 2000-2023 the FFmpeg developers
    built with gcc 13.2.1 (GCC) 20230801
    So commands like '-vframes' is now '-frames:v' and so on. No errors, just friendly suggestions in the man page. I replaced those also, but still the same problem.

    I should have listened more carefully when our kindergarten teacher went through Bash. 😉 IOW, I'm sure it's something simple I am not understanding.

    N.b. I can still use vcs with the normal 'convert' command, but depending on how "militia force" serious the ImageMagick gang is going to be about deprecation warnings and removal of old code, it might stop working at some point in the future and I think that would be sad.

    Any ideas? Thanks! 🙂

    1. I'm still using an older ImageMagick on my system but I've recently learnt about magick becoming the one command, yes. And I've seen a couple examples of it using a slightly different format for its arguments, likely the source of your problems, but I'm yet to look into it.
      I wouldn't worry about convert and the other separate IM tools disappearing overnight, but an update is in order to get rid of the warning.

      As for FFmpeg, I've been using the modern syntax you mention when using it to convert videos for quite a while now, and I can't tell if the older argument style will be removed anytime soon, but I'd prefer to delay any changes as much ad possible since I remember some inconsistency with ffmpeg's version numbering in the past for its versions in the wild, and I'd rather not try to guess what syntax to use.

      Thank you for your input, hopefully the next small update won't take too long to be ready.

      1. Thanks for the info. 🙂

        Another thing that is a little bit annoying, but isn't a very big deal, is the fact that videos made from a phone where the image is rotated in metadata, doesn't produce a correct aspect ratio. For example, a video that is stored as 1920×1080 (16:9), but shown as 1080×1920 (9:16), due to metadata rotation, vcs will create thumbnails in 1920×1080 aspect ratio (16:9) but show them rotated correctly, which means the image at 9:16 gets squashed to fit into 16:9. Like I said, not a very huge deal, but it looks somewhat silly and it would be great if it was possible to fix.
        I've tried to see if I could set the aspect parameter but it doesn't seem to do much when the rotation is made in metadata. Metadata usually state something like:
        Side data:
        displaymatrix: rotation of -90.00 degrees

  10. Hi, thanks for your tools! I'm wondering if vcs supports zero-padding mode(no padding between frames), as I see the sample picture bbb_excfgs_5x4_160px_config.jpg is. I want to use "-n 16 -c 4 -H 25%" args to make a 4×4 tile and make the output picture has the same width of video. Thank you!

    1. Sure, the --disable argument can do that, you'll need to disable padding and shadows, so add -dp -ds to remove all spacing between thumbnails

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top