{"id":13579805,"url":"https://github.com/amietn/vcsi","last_synced_at":"2026-01-12T02:03:48.867Z","repository":{"id":31250940,"uuid":"34812452","full_name":"amietn/vcsi","owner":"amietn","description":"Create video contact sheets, thumbnails","archived":false,"fork":false,"pushed_at":"2025-07-01T17:44:58.000Z","size":212,"stargazers_count":578,"open_issues_count":36,"forks_count":71,"subscribers_count":14,"default_branch":"master","last_synced_at":"2025-11-28T11:50:56.829Z","etag":null,"topics":["contact-sheet","python","screenshots","thumbnail","thumbnail-grids","thumbnailer","thumbnails","video"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/amietn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-04-29T18:58:11.000Z","updated_at":"2025-11-27T06:23:14.000Z","dependencies_parsed_at":"2023-10-04T13:46:30.033Z","dependency_job_id":"8d986aa0-7028-4372-9d82-4df70e16f682","html_url":"https://github.com/amietn/vcsi","commit_stats":{"total_commits":188,"total_committers":22,"mean_commits":8.545454545454545,"dds":"0.13829787234042556","last_synced_commit":"fa7aa8ca781d0fe3188eea76f79c5702bf9b7330"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/amietn/vcsi","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amietn%2Fvcsi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amietn%2Fvcsi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amietn%2Fvcsi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amietn%2Fvcsi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/amietn","download_url":"https://codeload.github.com/amietn/vcsi/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amietn%2Fvcsi/sbom","scorecard":{"id":189313,"data":{"date":"2025-08-11","repo":{"name":"github.com/amietn/vcsi","commit":"06b66ebb3c316150a7fda0709253a835ed400ab9"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.1,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":4,"reason":"5 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 4","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":3,"reason":"Found 9/29 approved changesets -- score normalized to 3","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/testing.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/testing.yml:11: update your workflow using https://app.stepsecurity.io/secureworkflow/amietn/vcsi/testing.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/testing.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/amietn/vcsi/testing.yml/master?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/testing.yml:18","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 21 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-16T20:20:09.105Z","repository_id":31250940,"created_at":"2025-08-16T20:20:09.105Z","updated_at":"2025-08-16T20:20:09.105Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28331510,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T00:36:25.062Z","status":"online","status_checked_at":"2026-01-12T02:00:08.677Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["contact-sheet","python","screenshots","thumbnail","thumbnail-grids","thumbnailer","thumbnails","video"],"created_at":"2024-08-01T15:01:43.401Z","updated_at":"2026-01-12T02:03:48.862Z","avatar_url":"https://github.com/amietn.png","language":"Python","readme":"# vcsi\n\n![Build Status](https://github.com/amietn/vcsi/actions/workflows/testing.yml/badge.svg)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](http://opensource.org/licenses/MIT)\n[![PyPI version](https://badge.fury.io/py/vcsi.svg)](https://badge.fury.io/py/vcsi)\n\nCreate video contact sheets. A video contact sheet is an image composed of video capture thumbnails arranged on a grid.\n\n## Examples\n\n```\n$ vcsi bbb_sunflower_2160p_60fps_normal.mp4 \\\n-t \\\n-w 830 \\\n-g 4x4 \\\n--background-color 000000 \\\n--metadata-font-color ffffff \\\n--end-delay-percent 20 \\\n--metadata-font /usr/share/fonts/TTF/DejaVuSans-Bold.ttf\n```\n\n![Example image 1](https://github.com/amietn/vcsi/assets/5566087/4ef4e631-eca6-43d0-8400-89f1bbbda73d)\n\n```\n$ vcsi bbb_sunflower_2160p_60fps_normal.mp4 \\\n-t \\\n-w 830 \\\n-g 3x5 \\\n--end-delay-percent 20 \\\n--timestamp-font /usr/share/fonts/TTF/DejaVuSans.ttf \\\n-o output.png\n```\n\n![Example image 2](https://github.com/amietn/vcsi/assets/5566087/5c6e88f3-29af-44dc-b36c-5e493e6d8dee)\n\n\nThe above contact sheets were generated from a movie called \"Big Buck Bunny\".\n\n## Installation\n\nFirst, install [uv](https://docs.astral.sh/uv/getting-started/installation/).\n\n\n### uv\n\n`vcsi` can be installed from PyPi:\n\n```\n$ uv tool install vcsi\n```\n\nor from local sources:\n\n```\n$ uv tool install .\n```\n\n### pip\n\n```\npip install vcsi\n```\n\n### Distribution packages\n\nvcsi is currently packaged for the following systems:\n\n| Linux packages | |\n| -------------- | --- |\n| Arch (AUR) | https://aur.archlinux.org/packages/vcsi/ |\n| Arch (AUR, git master) | https://aur.archlinux.org/packages/vcsi-git/ |\n| Gentoo | https://packages.gentoo.org/packages/media-video/vcsi |\n\nYour system is not listed?\n\n```\n$ apt-get install ffmpeg\n```\n\nThen use the uv installation method above.\n\nRunning Windows? See the note below.\n\n\n## Note for Windows users\n\nDownload a binary build of ffmpeg from Zeranoe here (e.g. 64bit static): http://ffmpeg.zeranoe.com/builds/\n\nExtract the archive and add the `bin` directory to your PATH so that `ffmpeg` and `ffprobe` can be invoked from the command line.\n\nIf you have issues installing numpy with pip, download an already built version of numpy here: http://sourceforge.net/projects/numpy/files/NumPy/\n\n\n## Requirements\n\nPython modules:\n\n* numpy\n* pillow\n* jinja2\n* texttable\n* parsedatetime\n\n\nMust be in your PATH:\n\n* ffmpeg\n* ffprobe\n\n\n## Usage\n\n```\n$ vcsi -h\nusage: vcsi [-h] [-o OUTPUT_PATH] [-c CONFIG]\n            [--start-delay-percent START_DELAY_PERCENT]\n            [--end-delay-percent END_DELAY_PERCENT]\n            [--delay-percent DELAY_PERCENT] [--grid-spacing GRID_SPACING]\n            [--grid-horizontal-spacing GRID_HORIZONTAL_SPACING]\n            [--grid-vertical-spacing GRID_VERTICAL_SPACING] [-w VCS_WIDTH]\n            [-g GRID] [-s NUM_SAMPLES] [-t]\n            [--metadata-font-size METADATA_FONT_SIZE]\n            [--metadata-font METADATA_FONT]\n            [--timestamp-font-size TIMESTAMP_FONT_SIZE]\n            [--timestamp-font TIMESTAMP_FONT]\n            [--metadata-position METADATA_POSITION]\n            [--background-color BACKGROUND_COLOR]\n            [--metadata-font-color METADATA_FONT_COLOR]\n            [--timestamp-font-color TIMESTAMP_FONT_COLOR]\n            [--timestamp-background-color TIMESTAMP_BACKGROUND_COLOR]\n            [--timestamp-border-color TIMESTAMP_BORDER_COLOR]\n            [--template METADATA_TEMPLATE_PATH] [-m MANUAL_TIMESTAMPS] [-v]\n            [-a] [-A ACCURATE_DELAY_SECONDS]\n            [--metadata-margin METADATA_MARGIN]\n            [--metadata-horizontal-margin METADATA_HORIZONTAL_MARGIN]\n            [--metadata-vertical-margin METADATA_VERTICAL_MARGIN]\n            [--timestamp-horizontal-padding TIMESTAMP_HORIZONTAL_PADDING]\n            [--timestamp-vertical-padding TIMESTAMP_VERTICAL_PADDING]\n            [--timestamp-horizontal-margin TIMESTAMP_HORIZONTAL_MARGIN]\n            [--timestamp-vertical-margin TIMESTAMP_VERTICAL_MARGIN]\n            [--quality IMAGE_QUALITY] [-f IMAGE_FORMAT]\n            [-T TIMESTAMP_POSITION] [-r] [--timestamp-border-mode]\n            [--timestamp-border-size TIMESTAMP_BORDER_SIZE]\n            [--capture-alpha CAPTURE_ALPHA] [--version]\n            [--list-template-attributes] [--frame-type FRAME_TYPE]\n            [--interval INTERVAL] [--ignore-errors] [--no-overwrite]\n            [--exclude-extensions EXCLUDE_EXTENSIONS] [--fast]\n            [-O THUMBNAIL_OUTPUT_PATH] [-S]\n            [--timestamp-format TIMESTAMP_FORMAT]\n            filenames [filenames ...]\n\nCreate a video contact sheet\n\npositional arguments:\n  filenames\n\noptional arguments:\n  -h, --help            show this help message and exit\n  -o OUTPUT_PATH, --output OUTPUT_PATH\n                        save to output file (default: None)\n  -c CONFIG, --config CONFIG\n                        Config file to load defaults from (default:\n                        C:\\Users\\zacke\\.config/vcsi.conf)\n  --start-delay-percent START_DELAY_PERCENT\n                        do not capture frames in the first n percent of total\n                        time (default: 7)\n  --end-delay-percent END_DELAY_PERCENT\n                        do not capture frames in the last n percent of total\n                        time (default: 7)\n  --delay-percent DELAY_PERCENT\n                        do not capture frames in the first and last n percent\n                        of total time (default: None)\n  --grid-spacing GRID_SPACING\n                        number of pixels spacing captures both vertically and\n                        horizontally (default: None)\n  --grid-horizontal-spacing GRID_HORIZONTAL_SPACING\n                        number of pixels spacing captures horizontally\n                        (default: 5)\n  --grid-vertical-spacing GRID_VERTICAL_SPACING\n                        number of pixels spacing captures vertically (default:\n                        5)\n  -w VCS_WIDTH, --width VCS_WIDTH\n                        width of the generated contact sheet (default: 1500)\n  -g GRID, --grid GRID  display frames on a mxn grid (for example 4x5). The\n                        special value zero (as in 2x0 or 0x5 or 0x0) is only\n                        allowed when combined with --interval or with\n                        --manual. Zero means that the component should be\n                        automatically deduced based on other arguments passed.\n                        (default: 4x4)\n  -s NUM_SAMPLES, --num-samples NUM_SAMPLES\n                        number of samples (default: None)\n  -t, --show-timestamp  display timestamp for each frame (default: False)\n  --metadata-font-size METADATA_FONT_SIZE\n                        size of the font used for metadata (default: 16)\n  --metadata-font METADATA_FONT\n                        TTF font used for metadata (default:\n                        C:/Windows/Fonts/msgothic.ttc)\n  --timestamp-font-size TIMESTAMP_FONT_SIZE\n                        size of the font used for timestamps (default: 12)\n  --timestamp-font TIMESTAMP_FONT\n                        TTF font used for timestamps (default:\n                        C:/Windows/Fonts/msgothic.ttc)\n  --metadata-position METADATA_POSITION\n                        Position of the metadata header. Must be one of\n                        ['top', 'bottom', 'hidden'] (default: top)\n  --background-color BACKGROUND_COLOR\n                        Color of the background in hexadecimal, for example\n                        AABBCC (default: 000000FF)\n  --metadata-font-color METADATA_FONT_COLOR\n                        Color of the metadata font in hexadecimal, for example\n                        AABBCC (default: FFFFFFFF)\n  --timestamp-font-color TIMESTAMP_FONT_COLOR\n                        Color of the timestamp font in hexadecimal, for\n                        example AABBCC (default: FFFFFFFF)\n  --timestamp-background-color TIMESTAMP_BACKGROUND_COLOR\n                        Color of the timestamp background rectangle in\n                        hexadecimal, for example AABBCC (default: 000000AA)\n  --timestamp-border-color TIMESTAMP_BORDER_COLOR\n                        Color of the timestamp border in hexadecimal, for\n                        example AABBCC (default: 000000FF)\n  --template METADATA_TEMPLATE_PATH\n                        Path to metadata template file (default: None)\n  -m MANUAL_TIMESTAMPS, --manual MANUAL_TIMESTAMPS\n                        Comma-separated list of frame timestamps to use, for\n                        example 1:11:11.111,2:22:22.222 (default: None)\n  -v, --verbose         display verbose messages (default: False)\n  -a, --accurate        Make accurate captures. This capture mode is way\n                        slower than the default one but it helps when\n                        capturing frames from HEVC videos. (default: False)\n  -A ACCURATE_DELAY_SECONDS, --accurate-delay-seconds ACCURATE_DELAY_SECONDS\n                        Fast skip to N seconds before capture time, then do\n                        accurate capture (decodes N seconds of video before\n                        each capture). This is used with accurate capture mode\n                        only. (default: 1)\n  --metadata-margin METADATA_MARGIN\n                        Margin (in pixels) in the metadata header. (default:\n                        10)\n  --metadata-horizontal-margin METADATA_HORIZONTAL_MARGIN\n                        Horizontal margin (in pixels) in the metadata header.\n                        (default: 10)\n  --metadata-vertical-margin METADATA_VERTICAL_MARGIN\n                        Vertical margin (in pixels) in the metadata header.\n                        (default: 10)\n  --timestamp-horizontal-padding TIMESTAMP_HORIZONTAL_PADDING\n                        Horizontal padding (in pixels) for timestamps.\n                        (default: 3)\n  --timestamp-vertical-padding TIMESTAMP_VERTICAL_PADDING\n                        Vertical padding (in pixels) for timestamps. (default:\n                        1)\n  --timestamp-horizontal-margin TIMESTAMP_HORIZONTAL_MARGIN\n                        Horizontal margin (in pixels) for timestamps.\n                        (default: 5)\n  --timestamp-vertical-margin TIMESTAMP_VERTICAL_MARGIN\n                        Vertical margin (in pixels) for timestamps. (default:\n                        5)\n  --quality IMAGE_QUALITY\n                        Output image quality. Must be an integer in the range\n                        0-100. 100 = best quality. (default: 100)\n  -f IMAGE_FORMAT, --format IMAGE_FORMAT\n                        Output image format. Can be any format supported by\n                        pillow. For example 'png' or 'jpg'. (default: jpg)\n  -T TIMESTAMP_POSITION, --timestamp-position TIMESTAMP_POSITION\n                        Timestamp position. Must be one of ['north', 'south',\n                        'east', 'west', 'ne', 'nw', 'se', 'sw', 'center'].\n                        (default: TimestampPosition.se)\n  -r, --recursive       Process every file in the specified directory\n                        recursively. (default: False)\n  --timestamp-border-mode\n                        Draw timestamp text with a border instead of the\n                        default rectangle. (default: False)\n  --timestamp-border-size TIMESTAMP_BORDER_SIZE\n                        Size of the timestamp border in pixels (used only with\n                        --timestamp-border-mode). (default: 1)\n  --capture-alpha CAPTURE_ALPHA\n                        Alpha channel value for the captures (transparency in\n                        range [0, 255]). Defaults to 255 (opaque) (default:\n                        255)\n  --version             show program's version number and exit\n  --list-template-attributes\n  --frame-type FRAME_TYPE\n                        Frame type passed to ffmpeg\n                        'select=eq(pict_type,FRAME_TYPE)' filter. Should be\n                        one of ('I', 'B', 'P') or the special type 'key' which\n                        will use the 'select=key' filter instead. (default:\n                        None)\n  --interval INTERVAL   Capture frames at specified interval. Interval format\n                        is any string supported by `parsedatetime`. For\n                        example '5m', '3 minutes 5 seconds', '1 hour 15 min\n                        and 20 sec' etc. (default: None)\n  --ignore-errors       Ignore any error encountered while processing files\n                        recursively and continue to the next file. (default:\n                        False)\n  --no-overwrite        Do not overwrite output file if it already exists,\n                        simply ignore this file and continue processing other\n                        unprocessed files. (default: False)\n  --exclude-extensions EXCLUDE_EXTENSIONS\n                        Do not process files that end with the given\n                        extensions. (default: [])\n  --fast                Fast mode. Just make a contact sheet as fast as\n                        possible, regardless of output image quality. May mess\n                        up the terminal. (default: False)\n  -O THUMBNAIL_OUTPUT_PATH, --thumbnail-output THUMBNAIL_OUTPUT_PATH\n                        Save thumbnail files to the specified output\n                        directory. If set, the thumbnail files will not be\n                        deleted after successful creation of the contact\n                        sheet. (default: None)\n  -S, --actual-size     Make thumbnails of actual size. In other words,\n                        thumbnails will have the actual 1:1 size of the video\n                        resolution. (default: False)\n  --timestamp-format TIMESTAMP_FORMAT\n                        Use specified timestamp format. Replaced values\n                        include: {TIME}, {DURATION}, {THUMBNAIL_NUMBER}, {H}\n                        (hours), {M} (minutes), {S} (seconds), {c}\n                        (centiseconds), {m} (milliseconds), {dH}, {dM}, {dS},\n                        {dc} and {dm} (same as previous values but for the\n                        total duration). Example format: '{TIME} /\n                        {DURATION}'. Another example: '{THUMBNAIL_NUMBER}'.\n                        Yet another example: '{H}:{M}:{S}.{m} /\n                        {dH}:{dM}:{dS}.{dm}'. (default: {TIME})\n\n\n```\n\n## Metadata templates\n\n`vcsi` now supports metadata templates thanks to jinja2. In order to use custom templates one should use the `--template` argument to specifiy the path to a template file.\n\nHere is a sample template file:\n\n```\n{{filename}}\nFile size: {{size}}\n{% if audio_sample_rate %}\nAudio sample rate: {{audio_sample_rate/1000}} KHz\n{% endif %}\n\n{% if audio_bit_rate %}\nAudio bitrate: {{audio_bit_rate/1000}} Kbps\n{% endif %}\n\n{{frame_rate}} fps\n\nResolution: {{sample_width}}x{{sample_height}}\n```\n\n## Exposed metadata template attributes\n\n| Attribute name | Description | Example |\n| --- | --- | --- |\n| size | File size (pretty format) | 128.3 MiB |\n| size_bytes | File size (bytes) | 4662788373 |\n| filename | File name | video.mkv |\n| duration | Duration (pretty format) | 03:07 |\n| sample_width | Width of samples (pixels) | 1920 |\n| sample_height | Height of samples (pixels) | 1080 |\n| display_width | Display width (pixels) | 1920 |\n| display_height | Display height (pixels) | 1080 |\n| video_codec | Video codec | h264 |\n| video_codec_long | Video codec (long name) | H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 |\n| video_bit_rate | Video bitrate | 371006 |\n| display_aspect_ratio | Display aspect ratio | 16:9 |\n| sample_aspect_ratio | Sample aspect ratio | 1:1 |\n| audio_codec | Audio codec | aac |\n| audio_codec_long | Audio codec (long name) | AAC (Advanced Audio Coding) |\n| audio_sample_rate | Audio sample rate (Hz) | 44100 |\n| audio_bit_rate | Audio bit rate | 192000 |\n| frame_rate | Frame rate (fps) | 23.974 |\n\n\n## Testing\n\nTo run the test suite, run:\n\n```\nuv run pytest\n```\n\nTo measure code coverage:\n\n```\nuv run pytest --cov=vcsi.vcsi\n```\n\nTo test Github Actions locally using [act](https://github.com/nektos/act):\n\n```\nact push\n```\n","funding_links":[],"categories":["Python"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famietn%2Fvcsi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Famietn%2Fvcsi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famietn%2Fvcsi/lists"}