Skip to main content

Python library for FFmpeg-based video processing

Project description

🎬 PyVideoKit-Libs

Python License

Python library for FFmpeg-based video and audio processing. Provides the core functions behind PyVideoKit-CLI, and can be used directly in your own Python projects.


✨ Features

  • 📼 VHS effect — retro visual noise, color bleed, and audio degradation
  • ✂️ Trim — cut a segment by start/end time with stream copy (no re-encoding)
  • 🔗 Concatenate — join multiple videos with stream compatibility validation
  • 🎬 Fade — fade-in and/or fade-out on an FFV1 master
  • 🔊 Extract audio — dump the audio track to uncompressed WAV (PCM 16-bit)
  • 🎞️ Convert to FFV1 — create a lossless MKV master for editing
  • 📺 Prepare for YouTube — encode to ProRes 422 HQ MOV, upscaled to 4K

📦 Requirements

  • Python ≥ 3.10
  • FFmpeg and FFprobe available in PATH
  • SoX available in PATH (required by apply_vhs_effect)

No Python package dependencies — the library delegates all heavy lifting to external tools via subprocess.


🔧 Installation

🏗️ Arch Linux (AUR)

yay -S python-pyvideokit-libs

FFmpeg, FFprobe, and SoX are installed automatically as pacman dependencies.

🐍 Other systems (pip)

pip install PyVideoKit-Libs

Make sure FFmpeg, FFprobe, and SoX are available in your PATH.


🖥️ Desktop Integration

If you also have PyVideoKit-GUI installed, you can add it to your application launcher. Arch Linux users get this automatically via the AUR package. For all other systems:

1. Save the icon:

mkdir -p ~/.local/share/icons/hicolor/scalable/apps
cat > ~/.local/share/icons/hicolor/scalable/apps/pvk-gui.svg << 'EOF'
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
  <rect x="4" y="14" width="40" height="30" rx="3" fill="#2d3561"/>
  <rect x="10" y="19" width="28" height="20" rx="2" fill="#1a2038"/>
  <polygon points="18,21 18,37 33,29" fill="#ff6b6b"/>
  <rect x="4" y="6" width="40" height="8" rx="2" fill="#ff6b6b"/>
  <rect x="11" y="6" width="6" height="8" fill="#ffffff"/>
  <rect x="23" y="6" width="6" height="8" fill="#ffffff"/>
  <rect x="35" y="6" width="5" height="8" fill="#ffffff"/>
</svg>
EOF

2. Create the .desktop entry:

mkdir -p ~/.local/share/applications
cat > ~/.local/share/applications/pvk-gui.desktop << 'EOF'
[Desktop Entry]
Version=1.0
Type=Application
Name=PyVideoKit
GenericName=Video Processing Tool
Comment=FFmpeg-based video processing GUI
Exec=pvk-gui
Icon=pvk-gui
Categories=AudioVideo;Video;AudioVideoEditing;
Terminal=false
Keywords=video;ffmpeg;trim;fade;vhs;youtube;convert;
EOF

3. Refresh the icon cache (may be required on some desktop environments):

gtk-update-icon-cache ~/.local/share/icons/hicolor/

PyVideoKit will now appear in your application launcher.


🚀 Quick Start

from pathlib import Path
from pyvideokit_libs import convert_to_ffv1, fade_video, prepare_youtube

# 1. Create a lossless master
master = convert_to_ffv1(Path("recording.mp4"))

# 2. Add a 1-second fade in and out
faded = fade_video(master, fade_in=1.0, fade_out=1.0)

# 3. Export for YouTube
result = prepare_youtube(faded)
print(result)

All functions accept an optional on_progress callback (pct: float) -> None for tracking progress.


📖 API Reference

🎞️ Video processing functions

apply_vhs_effect(input_path, output=None, on_progress=None) -> Path

Apply a retro VHS visual and audio effect. The input must have an audio stream. Produces a .mkv file.

out = apply_vhs_effect(Path("video.mp4"))

trim_video(input_path, start, end, output=None, on_progress=None) -> Path

Cut a segment from a video using stream copy (no re-encoding). start and end are in seconds.

out = trim_video(Path("video.mkv"), start=10.0, end=90.5)

Use parse_time_to_seconds("00:01:30") to convert a timestamp string to seconds.


join_videos(video_paths, output=None, on_progress=None) -> Path

Concatenate two or more videos using stream copy. Validates stream compatibility (codec, resolution, fps, audio format) before proceeding.

out = join_videos([Path("clip1.mkv"), Path("clip2.mkv"), Path("clip3.mkv")])

fade_video(input_path, fade_in=None, fade_out=None, output=None, on_progress=None) -> Path

Add fade-in and/or fade-out to an FFV1 video. Output is re-encoded as FFV1 with PCM audio.

out = fade_video(Path("master.mkv"), fade_in=1.5, fade_out=2.0)

extract_audio(input_path, output=None, on_progress=None) -> Path

Extract the audio track to an uncompressed WAV file (PCM 16-bit, pcm_s16le).

out = extract_audio(Path("video.mkv"))

convert_to_ffv1(input_path, fps=None, output=None, on_progress=None) -> Path

Convert any video to a lossless FFV1/MKV master. Use this as the first step before applying effects. fps defaults to None (preserve source frame rate); pass an integer to force a specific rate.

master = convert_to_ffv1(Path("recording.mp4"))        # preserve source fps
master = convert_to_ffv1(Path("recording.mp4"), fps=60) # force 60 fps

prepare_youtube(input_path, output=None, on_progress=None) -> Path

Encode an FFV1 master to ProRes 422 HQ MOV for YouTube upload:

  • Upscaled to 4K (2160p height), aspect ratio preserved
  • ProRes 422 HQ (prores_ks, profile 3), 10-bit 4:2:2 (yuv422p10le)
  • Uncompressed 16-bit PCM audio
out = prepare_youtube(Path("master_ffv1.mkv"))

⚙️ Utility functions

Function Description
parse_time_to_seconds(ts) Parse SS, MM:SS, or HH:MM:SS to a float
seconds_to_hms(seconds) Convert seconds to HH:MM:SS.mmm string
probe_duration(path) Get media duration in seconds via FFprobe
probe_stream_props(path) Get codec, dimensions, fps, sample rate, channels
probe_video_codec(path) Get the video codec name
probe_has_audio(path) Check whether an audio stream is present
make_output_path(input_path, suffix, ext) Generate an output filename next to the input
resolve_output_path(default, output) Resolve a file or directory output argument
require_tools(*names) Raise if any external tool is not in PATH
require_video_codec(path, codec, hint) Raise if the video codec does not match
require_audio_stream(path) Raise if no audio stream is present
run_ffmpeg_with_progress(cmd, duration, on_progress) Run an FFmpeg command with progress tracking

🛡️ Error handling

All functions raise FFmpegError when an FFmpeg subprocess exits with a non-zero code.

from pyvideokit_libs import FFmpegError, convert_to_ffv1

try:
    out = convert_to_ffv1(Path("bad_file.mp4"))
except FFmpegError as e:
    print(f"FFmpeg failed (exit {e.returncode}):")
    for line in e.error_lines:
        print(line)

🔄 Typical Workflow

convert_to_ffv1  →  trim_video / fade_video / apply_vhs_effect  →  prepare_youtube

Functions that re-encode (fade_video, apply_vhs_effect, prepare_youtube) expect an FFV1 .mkv as input.


⚖️ License

This project is licensed under the GPLv3 License — see the LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyvideokit_libs-0.3.0-py3-none-any.whl (39.0 kB view details)

Uploaded Python 3

File details

Details for the file pyvideokit_libs-0.3.0-py3-none-any.whl.

File metadata

File hashes

Hashes for pyvideokit_libs-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 59273c2f8d7ab50a916b2bd937f8987967543ffe8650da3b33c805fe95eb5efa
MD5 823eb8488a67e57734f40cc75c8fcd94
BLAKE2b-256 ac777b275e576b4af06add76f32f5488a1454a2ddfa6161d823448266424fd04

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page