Skip to main content

pressurecooker

Never have to pay for video upload limits again, pressurecook videos to your preferred size, using FFmpeg.

Uses Vulkan for GPU Detection, supports NVIDIA NVENC, AMD VCE, Intel QuickSync. Through a simple command-line interface, pressurecooker calculates a video and audio bitrate budget from the source duration. It reports the finished size and warns when the output exceeds the target. Encoder rate control and container overhead can cause the result to differ from the requested size.

hainan chicken

Quick start

Install Python 3.10+, Git, and FFmpeg with ffprobe. Keep FFmpeg and ffprobe on PATH, then clone the repository:

git clone https://github.com/maxie-maxie/pressurecooker.git
cd pressurecooker

Install and encode a video with a 25 MiB target.

Linux:

python3 -m venv .venv
.venv/bin/python -m pip install .
.venv/bin/pressurecooker video.mp4 output.mp4 -t 25

Windows PowerShell:

py -m venv .venv
.\.venv\Scripts\python.exe -m pip install .
.\.venv\Scripts\pressurecooker.exe video.mp4 output.mp4 -t 25

Replace video.mp4 with your file. Use --help to list flags.

Contents

Requirements

Dependency Required for
FFmpeg and ffprobe Every installation; installed separately.
Python 3.10 or newer Python package and portable executable. Native executables include Python.
GPU and driver with Vulkan Video encoding support GPU encoding. Software encoding remains available.

The CLI has no third-party Python runtime dependencies. The FFmpeg build must contain the selected encoder: libx264, libx265, or libsvtav1 for software; h264_vulkan, hevc_vulkan, or av1_vulkan for GPU encoding. Check ffmpeg -encoders for the available encoders. Vulkan Video uses the GPU's video hardware through its driver; support depends on the device, driver, and codec. General Vulkan graphics support alone is insufficient.

Software AV1 requires an FFmpeg build with SVT-AV1 two-pass integration; older builds may include the encoder without supporting two passes.

Install FFmpeg with your system package manager, for example:

# Debian or Ubuntu
sudo apt install ffmpeg
# Windows
winget install --id Gyan.FFmpeg --exact

Check that both commands resolve:

ffmpeg -version
ffprobe -version

Use --ffmpeg and --ffprobe to provide explicit executable paths.

Installation

The Python distribution is named pressurecooker-video and installs the pressurecooker command. With pipx installed, install the release from PyPI:

pipx install pressurecooker-video
pipx ensurepath

Open a new terminal after pipx ensurepath, then run pressurecooker --help. FFmpeg and ffprobe must be installed separately. Source installations and release files are described below.

Python package

To install a source checkout, clone the repository as shown in Quick start, then run these commands from its root.

Linux:

python3 -m venv .venv
source .venv/bin/activate
python -m pip install .
pressurecooker --help

Windows PowerShell:

py -m venv .venv
.\.venv\Scripts\python.exe -m pip install .
.\.venv\Scripts\pressurecooker.exe --help

For an installation managed by pipx:

pipx install .
pipx ensurepath

Open a new terminal after pipx ensurepath. A built wheel can also be installed with pipx install pressurecooker_video-0.1.0-py3-none-any.whl, or with python -m pip install inside a virtual environment.

Native executable

Choose a file for your operating system and architecture. Keep its accompanying .licenses directory when redistributing it.

Linux x64, after building or extracting the release files:

mkdir -p "$HOME/.local/bin" "$HOME/.local/share/pressurecooker/licenses"
install -m 755 dist/pressurecooker-0.1.0-linux64 "$HOME/.local/bin/pressurecooker"
cp -R dist/pressurecooker-0.1.0-linux64.licenses/. "$HOME/.local/share/pressurecooker/licenses/"
export PATH="$HOME/.local/bin:$PATH"
pressurecooker --version

Add the export PATH line to your shell's startup file to keep this setting.

Use the linux32 files for a 32-bit Linux installation, replacing linux64 in these commands.

Windows x64, from the repository root after building:

$installDir = Join-Path $env:LOCALAPPDATA 'Programs\pressurecooker'
New-Item -ItemType Directory -Path $installDir -Force | Out-Null
Copy-Item -LiteralPath '.\dist\pressurecooker-0.1.0-windows64.exe' -Destination (Join-Path $installDir 'pressurecooker.exe')
Copy-Item -LiteralPath '.\dist\pressurecooker-0.1.0-windows64.licenses' -Destination (Join-Path $installDir 'licenses') -Recurse -Force
$userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
if (($userPath -split ';') -notcontains $installDir) {
    $newUserPath = if ($userPath) { $userPath.TrimEnd(';') + ';' + $installDir } else { $installDir }
    [Environment]::SetEnvironmentVariable('Path', $newUserPath, 'User')
}
if (($env:Path -split ';') -notcontains $installDir) {
    $env:Path = $env:Path.TrimEnd(';') + ';' + $installDir
}
pressurecooker --version

Use the windows32 files for a 32-bit installation. The commands above rename the executable to pressurecooker.exe and update the user PATH without replacing existing entries.

Portable executable

The .pyz file runs on a system with Python 3.10 or newer:

python pressurecooker-0.1.0.pyz --help

On Linux, it can also be copied to a directory on PATH as pressurecooker and made executable with chmod +x. Its shebang uses python3.

Release files

File Description
pressurecooker_video-0.1.0-py3-none-any.whl Python package for either interpreter architecture.
pressurecooker_video-0.1.0.tar.gz Source distribution, including tests and build scripts.
pressurecooker-0.1.0.pyz Portable executable; requires Python.
pressurecooker-0.1.0-windows64.exe Native Windows x64 executable.
pressurecooker-0.1.0-windows32.exe Native Windows x86 executable.
pressurecooker-0.1.0-linux64 Native Linux x64 executable.
pressurecooker-0.1.0-linux32 Native Linux x86 executable.
*.licenses/ License texts accompanying each native executable.
pressurecooker-0.1.0-windows*.zip, pressurecooker-0.1.0-linux*.tar.gz Native executable with its license directory.
SHA256SUMS SHA256 hashes of the built release files.

FFmpeg and ffprobe are external dependencies for every release file. Native executables must be built on the target operating system with a matching interpreter architecture.

Usage

pressurecooker <source-video> <destination> --target-mb N [options]

Sizes use MiB; bitrates use kbps. The destination can be a directory or an output filename ending in .mp4, .mkv, or .webm. A directory receives <sourceName>.fit<N>.<container-ext>. A path without a recognized extension is treated as a directory.

Relative paths resolve against the current working directory. For example, from a Windows directory containing percent signs:

Set-Location -LiteralPath 'D:\Rar%44211323%'
pressurecooker video.mp4 . -t 150

Encode H.264/AAC in MP4 for broad playback compatibility, including Discord clients that support that format:

pressurecooker input.mov output.mp4 -t 25 -c h264 -s hd

Preview commands without creating output files or directories:

pressurecooker video.mp4 output/ -t 50 --dry-run

Options

Option Default Description
-t, --target-mb N Required Positive, finite target size in MiB.
-c, --codec C hevc h264, hevc, or av1.
-f, --container C Extension, then mp4 mp4, mkv, or webm; WebM requires AV1.
-p, --preset P fast Named encoder preset; AV1 also accepts 0-13.
-a, --audio-kbps N 128 Positive audio bitrate for re-encoding.
-r, --fps N Source Positive frame rate, up to 1000.
-s, --resolution R Source Resolution alias or WxH.
-q, --hw M auto auto or vulkan: detect Vulkan Video GPUs; off: software; qsv: legacy backend.
-d, --dry-run Off Print the plan and FFmpeg commands.
-v, --verbose Off Display FFmpeg progress.
-ff, --ffmpeg PATH PATH FFmpeg executable path.
-fp, --ffprobe PATH PATH ffprobe executable path.
--overwrite Off Replace an existing destination after successful encoding.
--version Print the version.
-h, --help, /? Show help.

An explicit container must agree with the destination's recognized extension. Use -- before positional paths whose names begin with a hyphen.

Encoding behavior

Presets and scaling

Named presets are ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow, and placebo. Software H.264 and HEVC use these names directly. For SVT-AV1 they map to 12, 11, 10, 9, 8, 7, 6, 5, 4, and 3 respectively.

Vulkan uses FFmpeg's -quality option. fast and faster presets map to level 0; medium, slow, slower, veryslow, and placebo request levels 1 through 5. AV1 numeric presets map to max(0, 8 - N). The requested level is capped at the GPU's highest supported level. Higher levels trade speed for quality, with the available levels defined by the driver. The encoding plan reports the selected level and GPU.

Resolution aliases are sd/360p (640x360), hd/720p (1280x720), fullhd/1080p (1920x1080), qhd/1440p (2560x1440), and uhd/2160p (3840x2160). Explicit dimensions round down to even numbers. Requests exceeding either source dimension keep the original resolution. Frame rate stays unchanged unless requested.

Audio and size budget

The first video and first audio streams are used. Compatible AAC audio in MP4/MKV, or Opus in WebM, is copied when its bitrate is known and at most 160 kbps. Other audio is re-encoded as AAC or Opus, with a minimum of 48 kbps and a cap based on 15% of the total budget. Video-only sources reserve no audio budget.

total_kbps = target_MiB * 8388.608 / duration
video_kbps = floor((total_kbps - audio_kbps) * 0.97)

A video budget below 50 kbps is rejected. Software encoding uses two passes. GPU encoding uses one pass with an additional 0.96 bitrate factor. MP4 output includes faststart.

The default auto mode probes the GPUs listed by FFmpeg and selects the first that can encode the chosen codec through Vulkan Video. If none succeeds, it selects the corresponding software encoder and prints the reason. --hw vulkan follows the same selection and fallback policy. --hw off skips GPU probes.

With Vulkan encoding, a short decode-and-encode probe checks the source on the selected GPU. Supported sources use Vulkan decoding and scaling. If that probe fails, encoding stays on the GPU while decoding and scaling use software. Both probe types discard their output. HEVC and AV1 playback depends on the receiving application and device.

Output handling and exit codes

Existing output is refused unless --overwrite is set. Source files and their symlink or hardlink aliases cannot be destinations. Encoding uses unique temporary output and statistics files; output is finalized after success, and failures or Ctrl-C remove temporary files. A dry run creates no files or directories; GPU probes write to the null device.

Exit code Meaning
0 Success.
2 Input or usage error.
3 Missing FFmpeg or ffprobe.
4 Target too small for the duration.
5 Encoding failure.
130 Interrupted.

Running without arguments prints usage and exits with code 2.

Compatibility

The Python package and portable executable require Python 3.10 or newer and a compatible FFmpeg installation. A universal wheel does not establish that every platform has been tested. Native Linux builds also depend on the target system's C library.

Windows x64, Windows x86, Linux x64, and Linux x86 build routes are tested in GitHub Actions. Linux x86 uses Debian Bookworm i386 in a chroot on an x64 runner; CI verifies 32-bit Python, runs the test suite, and starts the built executable. Local Linux x86 execution is unavailable on the WSL 1 environment used for release preparation.

Development

Install build tools and run checks from the repository root:

python -m pip install build ".[build]"
python -m unittest discover -s tests -v
python -m build
python scripts/build_portable.py
python scripts/build_binary.py
python scripts/package_release.py

Outputs are written to dist/. Native builds use the operating system and pointer width of the Python interpreter running the script. A 32-bit build requires a 32-bit interpreter. Build Linux executables on the oldest Linux distribution you intend to support.

The native builder discovers CPython and PyInstaller licenses from the installed runtime and distribution metadata. For a custom Python installation, pass --python-license PATH. Supplemental dependency notices are supplied for Windows CPython 3.12.10/3.14.4 and discovered from Debian/Ubuntu system packages. Other runtimes require --runtime-license-dir PATH. Missing license files stop the build. --clean removes the repository's build outputs before rebuilding.

Publishing to PyPI

Publishing a GitHub release runs publish-pypi.yml. It builds the wheel and source distribution, checks their metadata, tests the installed wheel, and uploads both packages through PyPI Trusted Publishing.

One-time setup

Create a PyPI account, verify its email address, and enable two-factor authentication. Under Publishing, add a pending GitHub publisher with these values:

Field Value
PyPI project name pressurecooker-video
Owner maxie-maxie
Repository pressurecooker
Workflow filename publish-pypi.yml
Environment pypi

The first upload creates the PyPI project. For an existing project, add the same publisher in its Publishing settings. GitHub creates the pypi environment when the publishing job runs. Authentication uses GitHub's identity token; an API token or repository secret is unnecessary.

Publish a version

For the first release, keep version 0.1.0. For subsequent releases, update both pyproject.toml and src/pressurecooker/__init__.py, then commit and push. The release tag must be v followed by that version.

From the repository root, publish the first GitHub release:

gh release create v0.1.0 --target main --title "v0.1.0" --generate-notes

You can also publish a release from GitHub's Releases page. Drafts do not upload to PyPI. After the workflow succeeds, users can install with pipx install pressurecooker-video; FFmpeg and ffprobe remain separate requirements.

To check the workflow without uploading, run it manually from the Actions page or use:

gh workflow run publish-pypi.yml --ref main

Manual runs build and test the packages, then skip publishing. PyPI versions cannot be replaced; use a new version for each later release.

License

pressurecooker is distributed under the MIT License. Native executables include CPython and the PyInstaller bootloader; their license texts accompany each build. FFmpeg and its encoders are installed and licensed separately. See Third-party notices.

Metadata

Release files for pressurecooker-video 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pressurecooker-video 0.1.0
File Size Uploaded Provenance Actions
pressurecooker_video-0.1.0.tar.gz 50.7 kB With provenance Details for pressurecooker_video-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for pressurecooker-video 0.1.0
File Interpreter ABI Platform Actions
pressurecooker_video-0.1.0-py3-none-any.whl Python 3 none any Details for pressurecooker_video-0.1.0-py3-none-any.whl

Total release size: 71.9 kB

Release files / pressurecooker_video-0.1.0.tar.gz

Download URL pressurecooker_video-0.1.0.tar.gz
Size 50.7 kB
Tags Source
SHA-256 checksum
How to use checksums
f2b87428ded3dd910cf099449d5dfd38e1cbb2c07f94f7dedf8fd9d4fe4eec16
BLAKE2b-256 checksum
How to use checksums
0b5444017ec0f6973a3ffcf6e6d82e175918aa495e7bde852ae480204472c590
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 10, 2026.

Transparency log

Release files / pressurecooker_video-0.1.0-py3-none-any.whl

Download URL pressurecooker_video-0.1.0-py3-none-any.whl
Size 21.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5b2262e20f8804d4af93d61695cab3e932a476039d38d35055ecfc25c12b0dc3
BLAKE2b-256 checksum
How to use checksums
a7ddaecc3c4442ec9c80e6572b7efbb9be1cb2581cd6949f7942a1660ebed057
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 10, 2026.

Transparency log

Security for pressurecooker-video 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for pressurecooker_video-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 10, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page