Skip to main content

A Python CLI tool for batch-processing MP4 videos with FFmpeg and FFprobe.

Project description

Video Normalization and Processing with FFmpeg

A small Python CLI tool to batch-process .mp4 files with FFmpeg/FFprobe.

It supports:

  • Loudness analysis (LUFS)
  • Loudness normalization
  • Text overlay
  • Video cutting into fixed-length segments
  • Optional re-encode for cuts
  • Dry-run mode to preview commands

Note: This is a naive wrapper script intended for simple batch workflows.
For advanced or production-grade video/audio processing, consider established packages such as ffmpeg-python, moviepy, or PyAV.

Requirements

  • Linux machine
  • Python >=3.14 (as defined in pyproject.toml)
  • uv
  • ffmpeg + ffprobe available in PATH

Install / setup (uv)

From project root:

uv sync

This installs runtime + project dependencies from pyproject.toml.

Configuration

Create a .env file in the project root:

SOURCE=/absolute/path/to/source
TARGET=/absolute/path/to/target
  • SOURCE: input folder with .mp4 files
  • TARGET: output folder (created if missing)

Usage

If your environment is activated and pyffmpeg_wrapper is installed as a CLI script, you can run:

pyffmpeg_wrapper [options]

CLI options

  • -l, --lufs (float, default: -16) Target integrated loudness.
  • -p, --pattern (string) Filename substring filter (*{pattern}*.mp4).
  • -cl, --check-loudness Analyze loudness only.
  • -n, --normalize Normalize audio loudness.
  • -sl, --segment-length (int) Split each video into N-second segments.
  • -re, --re-encode Re-encode cuts with default options.
  • -t, --text (string) Draw centered text overlay.
  • -cf, --clear-first Clear matching files in target first.
  • -dr, --dry-run Print FFmpeg commands without executing them (FFprobe still executes).

Examples

Check loudness:

uv run pyffmpeg_wrapper -cl

Normalize to -16 LUFS:

uv run pyffmpeg_wrapper -n -l -16

Normalize only files matching pattern:

uv run pyffmpeg_wrapper -n -p session1

Add overlay text:

uv run pyffmpeg_wrapper -t "DRAFT"

Cut into 60-second segments:

uv run pyffmpeg_wrapper -sl 60

Cut into 60-second segments with re-encode:

uv run pyffmpeg_wrapper -sl 60 -re

Dry run:

uv run pyffmpeg_wrapper -n -sl 60 -dr

FFmpeg Command Reference

See below for manual ffmpeg commands similar to what this script automates.

Quick Audio Normalization Example

ffmpeg -i input.mp4 -c:v copy -filter:a "loudnorm=I=-16:TP=-1.5:LRA=7:linear=true" output.mp4

Parameter explanations:

  • I=-16: Target integrated loudness, -16 LUFS (good for speech, matches YouTube and streaming standards).
  • TP=-1.5: True peak limit, -1.5 dBTP (prevents digital clipping).
  • LRA=7: Loudness range, 7 LU (keeps dynamics natural but not too wide for speech).
  • linear=true: Use linear normalization (better for speech).

Normalizing Videos for Concatenation

To normalize all your videos for concatenation, you should:

  • Re-encode both video and audio to a common format, resolution, frame rate, and audio settings.
  • Apply the loudnorm filter to the audio.

Recommended ffmpeg command:

ffmpeg -i input.mp4 \
  -vf "scale=1280:720,fps=30" \
  -c:v libx264 -preset fast -crf 23 \
  -c:a aac -b:a 192k -ar 48000 -ac 2 \
  -af "loudnorm=I=-16:TP=-1.5:LRA=11" \
  output.mp4

Cutting and Normalizing a Video Segment

ffmpeg -ss 00:01:23 -i input.mp4 \
  -vf "scale=1280:720,fps=30" \
  -c:v libx264 -preset fast -crf 23 \
  -c:a aac -b:a 192k -ar 48000 -ac 2 \
  -af "loudnorm=I=-16:TP=-1.5:LRA=11" \
  -t 30 \
  output.mp4

Project details


Download files

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

Source Distribution

pyffmpeg_wrapper-0.2.0.tar.gz (7.0 kB view details)

Uploaded Source

Built Distribution

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

pyffmpeg_wrapper-0.2.0-py3-none-any.whl (8.3 kB view details)

Uploaded Python 3

File details

Details for the file pyffmpeg_wrapper-0.2.0.tar.gz.

File metadata

  • Download URL: pyffmpeg_wrapper-0.2.0.tar.gz
  • Upload date:
  • Size: 7.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Garuda Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for pyffmpeg_wrapper-0.2.0.tar.gz
Algorithm Hash digest
SHA256 38ed147e8c63a1626ebe0d9c498ad02197fd93ec4034247587c22148d839178c
MD5 55703b56124fc41b7a8547c0e14e8972
BLAKE2b-256 1fc74b4db087c0b8034b395d457417e06953ce02d271218de1cb75ae2093b48c

See more details on using hashes here.

File details

Details for the file pyffmpeg_wrapper-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: pyffmpeg_wrapper-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 8.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Garuda Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for pyffmpeg_wrapper-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b93392bfc6bb8c826becb18fd68d0dae791449224b745bf0a7cdabaf53318719
MD5 2f468e58f7efdac82c711269e63381a3
BLAKE2b-256 5e038f14ef6cee0a2af1b1c881bb01fb06cdf36d0c68b4169176fd80f4c82fad

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