pyhecate is a Python command-line tool and library for macOS that automates the creation of insightful visual summaries from your video files. It generates still image thumbnails (JPGs), animated GIFs, and concise summary videos (MP4s), making it easy to preview, catalog, or share your video content.
It acts as a powerful and user-friendly wrapper for the underlying hecate command-line application, simplifying its usage and adding features like batch processing and custom video outros.
pyhecate is designed for anyone who works with video content on a Mac and needs a quick way to generate visual summaries:
- Content Creators: Quickly create thumbnails or teaser GIFs for social media or websites.
- Video Editors: Generate previews or contact sheets of video footage.
- Archivists & Librarians: Efficiently catalog large video collections with visual metadata.
- Researchers: Extract keyframes or summarized clips for analysis.
- Anyone with video files: Get a quick overview of video content without scrubbing through entire files.
- Saves Time: Automates the otherwise tedious manual process of extracting frames and creating summaries.
- Multiple Output Formats: Generates JPG snapshots, animated GIFs, and summary MP4 videos from a single command.
- Highly Customizable:
- Control snapshot frequency for JPGs.
- Define the width of animated GIFs.
- Set the desired length for video summaries.
- Optionally skip image or video summary generation.
- Batch Processing: Process a single video file or an entire folder of videos at once.
- Add Outros: Automatically append a custom outro/ending video clip to your generated summaries.
- Organized Output: Creates well-structured folders for each processed video, keeping generated files neatly organized.
-
hecate:pyhecaterelies on thehecatecommand-line tool. You must install it first.- Follow the installation instructions on the official
hecateGitHub page.
- Follow the installation instructions on the official
-
ffmpeg: You also needffmpegandffprobeinstalled and available in your system's PATH.pyhecateuses these for video metadata analysis and processing.- The easiest way to install
ffmpegon macOS is typically via Homebrew:brew install ffmpeg
- Alternatively, download binaries from the official FFmpeg website.
- The easiest way to install
Once the prerequisites are met, you can install pyhecate:
-
Recommended (from PyPI):
pip install pyhecate
-
Alternative (directly from GitHub for the latest version):
python3 -m pip install --user --upgrade git+https://github.com/twardoch/pyhecate/
Open your Terminal application and use the pyhecate command.
Basic Structure:
pyhecate [OPTIONS] <path_to_video_file_or_folder>Common Options:
path: (Required) Path to the video file or a folder containing video files.-d,--dir: Treat thepathargument as a folder and process all*.mp4files within it.-o <output_folder>,--outdir <output_folder>: Specify a parent folder where output subfolders (one for each video) will be created. Defaults to the input video's directory.-i <secs>,--image-every <secs>: Set JPG snapshot frequency in seconds (default: 30).-g <px>,--gif-width <px>: Set the width for animated GIFs in pixels (default: 360).-I,--skip-images: Skip generating JPG and GIF images.-s <secs>,--video-length <secs>: Set the video summary length in seconds (default: 16).-a <path_to_outro_video>,--outro <path_to_outro_video>: Path to an MP4 video file to append as an outro to the summary video.-S,--skip-video-summary: Skip making the video summary MP4 file.-v: Verbose output (use-vvfor debug-level verbosity).-h,--help: Show the full help message with all options.
Examples:
-
Process a single video with default settings: (Output will be in a folder named
myvideo_outinside the same directory asmyvideo.mp4)pyhecate /path/to/myvideo.mp4
-
Process all MP4 videos in a directory, saving results to a specific output location:
pyhecate -d /path/to/my_videos_folder -o /path/to/desired_output_location
-
Process a single video, create a 60-second summary, use 200px wide GIFs, and add an outro:
pyhecate /path/to/another_video.mp4 -s 60 -g 200 -a /path/to/my_outro.mp4
-
Process a video, but only generate the video summary (no JPGs or GIFs):
pyhecate /path/to/presentation.mp4 -I
You can also use pyhecate within your Python scripts for more complex workflows.
Core Classes:
pyhecate.PyHecate: Useful for processing based on file/folder paths, similar to CLI usage.pyhecate.PyHecateVideo: Provides fine-grained control over the processing of a single video file.
Examples:
-
Process all videos in a directory using
PyHecate:from pyhecate import PyHecate import logging # Configure logging to see progress (optional) logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s") processor = PyHecate( path="/path/to/your_video_collection", # Path to the directory dir=True, # Indicate it's a directory outdir="/path/to/programmatic_output", # Specify output base directory isumfreq=60, # Snapshot every 60 seconds vsumlength=30, # 30-second video summaries gifwidth=400 # 400px wide GIFs ) # Processing is triggered during instantiation when 'dir=True' or for single files. print("Processing complete. Check the output directory.")
-
Process a single video with detailed control using
PyHecateVideo:from pyhecate import PyHecateVideo import logging import os # Configure logging (optional) logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s") video_file = "/path/to/source_video.mp4" base_output_dir = "/path/to/single_video_output" # PyHecateVideo expects the final output directory for *this specific video* video_name_without_ext = os.path.splitext(os.path.basename(video_file))[0] specific_video_outdir = os.path.join(base_output_dir, video_name_without_ext) if not os.path.exists(specific_video_outdir): os.makedirs(specific_video_outdir) video_processor = PyHecateVideo( path=video_file, outdir=specific_video_outdir, # Directory where this video's outputs (jpg, gif, mp4 subfolders) will be created isumfreq=10, # Snapshots every 10 seconds vsumlength=20, # 20-second summary gifwidth=320, # 320px wide GIFs outro="/path/to/your_outro.mp4", # Optional: path to an outro video isum=True, # Generate images (JPGs, GIFs) vsum=True # Generate video summary ) success = video_processor.summarize() if success: print(f"Successfully processed {video_file}") print(f"Outputs are in: {specific_video_outdir}") else: print(f"Failed to process {video_file}")
pyhecate is structured around two main classes and leverages external command-line tools for its core functionality:
-
pyhecate.PyHecateClass:- This class serves as the main entry point when using
pyhecateas a library for processing multiple files or for simpler single-file processing. - It handles the initial path inputs, determining if it's a single video file or a directory of videos.
- If a directory is provided, it scans for
*.mp4files. - For each video file identified, it constructs an appropriate output subdirectory path (e.g.,
main_output_dir/video_filename_without_ext/) and then instantiatesPyHecateVideoto handle the actual processing for that video. - It passes along configuration options (like image frequency, summary length, etc.) to each
PyHecateVideoinstance.
- This class serves as the main entry point when using
-
pyhecate.PyHecateVideoClass:- This class is responsible for all processing operations for a single video file.
- 1. Metadata Extraction:
- It begins by calling
ffprobe(a tool distributed withffmpeg) usingsubprocess.run(). - This fetches crucial metadata from the video file, such as its duration, width, height, and whether it contains an audio stream. This information is used to configure subsequent processing steps (e.g., number of snapshots, video summary dimensions).
- It begins by calling
- 2. Output Preparation (
prep_outfoldersmethod):- Based on the video's metadata and user settings, it creates a structured set of subdirectories within the video's specific output folder (e.g.,
.../video_name_out/). These include:jpg-<width>: For still image snapshots.gif-<width>: For individual frame animated GIFs.gifsum-<width>: For summary animated GIFs.mp4-<length>: For the summary MP4 video.
- It also defines paths for temporary and final summary files.
- Based on the video's metadata and user settings, it creates a structured set of subdirectories within the video's specific output folder (e.g.,
- 3.
hecateExecution (run_hecatemethod):- This is the core processing step. The method constructs a command-line call to the external
hecateapplication. - Arguments for
hecateare dynamically built based on thePyHecateVideoinstance's attributes (e.g.,self.vsumto generate video summary,self.isumfor images,self.vsumlength,self.numsnaps,self.gifwidth). subprocess.run()is used to execute thehecatecommand.hecatethen performs the heavy lifting of analyzing the video and generating the raw output files (images, summary video) into the video's specific output folder (which acts as a temporary staging area forhecate).
- This is the core processing step. The method constructs a command-line call to the external
- 4. File Organization & Cleanup (
cleanup_foldersmethod):- After
hecatecompletes, its output files (JPGs, GIFs, temporary summary MP4) are located directly in the video's output folder. - This method moves these files into their respective, neatly organized subdirectories (e.g.,
jpg-1280/,gifsum-360/) that were created in theprep_outfoldersstep.
- After
- 5. Outro Addition (
add_outromethod):- If an outro video path (
self.outro) is provided and a summary video was generated, this method uses theffmpeg-pythonlibrary. - It takes the generated summary video and the specified outro video as inputs.
- It then uses
ffmpeg-python's capabilities to concatenate these two video streams (and their audio streams, if present and compatible) into a new MP4 file, which becomes the final summary video with the outro.
- If an outro video path (
- Orchestration (
summarizemethod):- This public method in
PyHecateVideocalls the above steps in sequence to fully process a single video.
- This public method in
Key External Tools & Libraries:
hecate: The core engine for analyzing video content and generating initial thumbnails, GIFs, and summary videos.pyhecatewrapshecatecalls usingsubprocess.ffmpeg(andffprobe): Used for:ffprobe: Extracting video metadata (duration, dimensions, audio information) viasubprocess.ffmpeg(viaffmpeg-pythonlibrary): Concatenating the generated video summary with a custom outro video.
Send2Trash: Used for moving files to the system's trash/recycle bin instead of permanently deleting them, which is a safer default.
We welcome contributions to pyhecate! To ensure code quality and consistency, please follow these guidelines:
Development Environment Setup:
- Prerequisites:
- Python 3.8+
- Git
- The
hecatecommand-line tool installed and in your PATH. ffmpegandffprobeinstalled and in your PATH.
- Clone the Repository:
git clone https://github.com/twardoch/pyhecate.git cd pyhecate - Install in Editable Mode with Development Dependencies:
This will install
pyhecatesuch that changes you make to the source code are immediately effective. The[dev]extra includes tools for linting, formatting, type checking, and testing.pip install -e .[dev]
Code Style & Quality:
- Formatting: Code is formatted using Ruff. Before committing, please format your changes:
ruff format . - Linting: Code is linted using Ruff to catch common issues and enforce style. Check your code with:
Configuration for Ruff can be found in
ruff check .pyproject.toml. We generally follow PEP 8 guidelines. - Type Checking: Static type checking is performed using MyPy. Ensure your code passes type checks:
All new code should include type hints. MyPy configuration is also in
mypy .pyproject.toml.
Testing:
- Tests are written using the pytest framework and are located in the
tests/directory. - Run all tests with:
pytest
- New features or bug fixes should ideally be accompanied by new tests to cover the changes.
- Ensure all tests pass before submitting a pull request.
Dependencies:
- Project dependencies are managed in
pyproject.toml(using Hatch for the build system) and also listed insetup.pyfor broader compatibility. - Development dependencies are specified under
[project.optional-dependencies]inpyproject.toml.
Commit Messages:
- Please write clear and descriptive commit messages. While not strictly enforced, following a convention like Conventional Commits is encouraged.
- Example:
feat: Add support for custom GIF frame rates - Example:
fix: Correctly handle videos with no audio stream during outro - Example:
docs: Update README with new installation instructions
- Example:
Pull Requests:
- Fork the repository on GitHub.
- Create a new branch for your feature or bug fix.
- Make your changes, adhering to the coding standards above (format, lint, type check, test).
- Push your changes to your fork.
- Open a pull request against the
main(or relevant development) branch of thetwardoch/pyhecaterepository. - Clearly describe the changes you've made and why.
Project-Specific Guidelines:
- Be mindful of any instructions or conventions documented in files like
AGENTS.mdor similar notes within the project if you encounter them, as these may contain specific guidance for working with certain parts of the codebase.
Thank you for contributing!