Ffmpeg4discord
ffmpeg4discord is a Python package tailored for Two-Pass encoding, enabling efficient video compression to meet desired file sizes. Ideal for users seeking to compress videos for Discord sharing within file size limitations.
Install / Use
/learn @zfleeman/Ffmpeg4discordREADME
ffmpeg4discord (ff4d) -- Target File Size Video Compression for Discord with FFmpeg
ff4d is a command-line tool that compresses video files to fit under a specified file size, making them easy to share on Discord and other platforms with file size limits. It is especially useful for quickly preparing large video clips (such as NVIDIA ShadowPlay recordings) for upload, without needing a visual editor.
The package provides a convenient interface for FFmpeg, including a 2-pass encoding workflow (via the TwoPass() class) and support for advanced video filters like cropping and resolution scaling. This makes it adaptable to a wide range of audio/video processing needs.
Installation
This package requires Python >= 3.9. For Windows users, ensure that Python is added to your system's PATH. I highly recommend that you use the python.org Python installation.
Install this package with the following command.
pip install ffmpeg4discord
You must first have FFmpeg installed on your system. ffmpeg needs to be registered in your PATH. macOS or Linux users can use their favorite package manager to do this, but this process is a little more tricky for Windows users.
NOTE: This package relies on the external FFmpeg binary, and updates to FFmpeg may cause unexpected errors; please raise an issue if you encounter any problems.
Help for Windows users
After installing this package, Windows users can run this command in a terminal to download the necessary ffmpeg binaries:
install-ffmpeg-windows
This will place ffmpeg.exe, ffprobe.exe, and ffplay.exe into the same location as your Python executable.
Usage
Use ff4d in your favorite terminal like this:
ff4d path-to-file.mp4 [optional-flags]
This command tries to compress the whole video file down to the an output file size of 10MB:
ff4d cool_clip.mp4 -s 10
This will trim a 20 second section out of cool_clip.mp4 starting at 10 seconds in and ending at 30 seconds. The output will be less than 10MB. More on the optional flags.
ff4d cool_clip.mp4 --from 00:00:10 --to 00:00:30 -s 10
I've had a good time using this command with a Batch file on Windows. Refer to the Sample Batch File section for more information.
Optional Flags
Boolean flags support both
--flagand--no-flagforms (e.g.--web/--no-web).
| Flag | Default | Example | Description |
|---|---|---|---|
| -o<br>--output | current working directory | -o "C:/Users/zflee/A Folder"<br>-o "C:/Users/zflee/Desktop/A Folder/filename.mp4" | Output directory or full output filename. If you provide a directory, ff4d will generate a timestamped filename. If you provide a filename, ff4d will use it (and will correct the extension if it doesn’t match the selected codec). |
| -s<br>--target-filesize | 10 | -s 50 | Target output file size in MiB. The encoder will iterate until it gets under this size (unless --approx is used). |
| -a<br>--audio-br | 96 | -a 128 | Audio bitrate in kbps. Lowering this allows a slightly higher video bitrate for the same target file size. |
| -c<br>--codec | x264 | -c hevc_nvenc | Video "codec profile". These aren't 1:1 titles with the FFmpeg codec choices, because modern codecs require more tweaking for encoding performance, so I've setup a profile for vp9 and av1 speed. Options are ordered from "most compatible" to "least compatible": x264, h264_nvenc, x265, hevc_nvenc, vp9, av1. See Notes on Codec Selection for more information. |
| -r<br>--resolution | off | -r 1280x720 | Scale the output video to a specific resolution (format: WIDTHxHEIGHT). |
| -x<br>--crop | No default | -x 255x0x1410x1080 | Crop the input before encoding (format: x_offsetx y_offsetx widthx height). See FFmpeg crop documentation. |
| -f<br>--framerate | off | -f 30 | Output frame rate (FPS). If you specify a value higher than the input video’s FPS, the original FPS will be kept. |
| --from | No default | --from 00:01:00 | Start time for trimming the input (timestamp format HH:MM:SS). |
| --to | No default | --to 00:01:20 | End time for trimming the input (timestamp format HH:MM:SS). |
| --filename-times | false | --filename-times | Parse From/To timestamps from the input filename. See File Name Formatting. |
| --approx | false | --approx | Approximate the target size: do a single 2-pass encode and do not loop to get under the target. |
| -an<br>--no-audio | false | -an | Do not include any audio stream in the output. (Overrides --amix / --astreams.) To explicitly re-enable audio after setting this in a config, use --no-no-audio. |
| --amix | false | --amix | Mix all (selected) audio streams into one output track. When off, only the default/first audio track is used. |
| --amix-normalize | false | --amix-normalize | When mixing audio, normalize volume levels. Specifying this implies --amix. |
| --astreams | all | --astreams "0,1" | Comma-separated list of 0-based audio stream positions to include. When used with --amix, those streams will be mixed; otherwise, only the first selected stream is kept. |
| -v<br>--verbose | false | --verbose | Enable verbose FFmpeg logging (useful for debugging). |
| --config | off | --config config.json | Path to a JSON file containing a saved configuration. When a setting is provided by both JSON and CLI flags, the CLI flag wins. See JSON Configuration. |
| --no-config | off | no---config | Disable loading any default configuration files. See JSON Configuration. |
| --web | false | --web | Launch the Web UI for this job. See Web UI. |
| -p<br>--port | random (when --web) | -p 5333 | Run the Web UI on a specific port. If omitted, a random free port between 5000–6000 is chosen. |
File Name Formatting
Enable this feature with --filename-times. You can edit the name of your video file if you need to trim it to a specific section. Here are a few examples.
000020.mp4- This trims and compresses the video from 00:00:20 to the end of the clip.
000020-000145.mp4- This trims and compresses the video from 00:00:20 to 00:01:45.
SomethingElse.mp4- Compresses the entire video if the first six characters of the file's name aren't numeric.
JSON Configuration
If your encoding job uses the same settings consistently, you can simplify your workflow by referencing a JSON configuration file instead of specifying multiple command-line arguments. This feature was designed for advanced users or "workflow people."
When using both a JSON configuration file and command-line flags, the command-line flag values take precedence over the values defined in the JSON. For example, if "target_filesize" is specified in the JSON file and you include the --target-filesize (or -s) flag in your command, the command-line value will be used.
If you supply a configuration JSON file, include only the settings that differ from the default values. Any omitted values will automatically use their defaults.
By default, ff4d will try to read a default configuration file if it is present. This file is located wherever your platform stores user-specific configuration data.
Typically, this would be:
| Windows | Linux | MacOS |
|---|---|---|
| %LOCALAPPDATA%\zfleeman\ffmpeg4discord | $XDG_CONFIG_HOME/ffmpeg4discord.json OR $XDG_CONFIG_HOME/ff4d/ffmpeg4discord.json | ~/Library/Application Support/ffmpeg4discord/ffmpeg4discord.json |
If you are unsure of where these paths would resolve to, ff4d logs any searched paths to the console when run.
This feature can be turned off with the --no-config flag.
Example JSON File Configuration
Create a new plain text JSON file (my-config.json) structured like this:
{
"target_filesize": 10.0,
"resolution": "1280x720",
"codec": "libvpx-vp9",
"to": "00:00:40"
}
And then you would call ff4d like this:
ff4d my-video.mp4 --config my-config.json
Detailed Example
ff4d 000050-000145.mp4 \
-x 1280x0x2560x1440 \
-r 1920x1080 \
-s 50 \
-a 48 \
-o D:/shadowplay/ \
--filename-times
The example above takes a 5120x1440 resolution video as its input. The script trims the video from 00:00:50 to 00:01:45 (specified in the file name, and enabled with --filename-times). It crops a 2560x1440 section starting at 1280 pixels from the top-left and 0 pixels down (-x). The output file will be located in D:/shadowplay/ (-o) with a new resolution of 1920x1080 (-r), and it will be 50MB (-s). The audio bitrate will be reduced to 48k (-a) as well, but that's probably going to sound terrible.
Web UI
The web UI can be activated by adding --web to your ff4d call.
ff4d cool_clip.mp4 -r 1280x720 -s 20 --web
That command will spin up a Flask server on your local machine and launch a rendered webpage with the video as the centerpiece. The flags you provide to ff4d will fill in the defaults for the form. You can override/replace the values with the web form.
You can drag the video playhead to different portions of the video and click the "Set Start/End Time" buttons to specify the section of the video you want to be clipped out. You can also use the range sliders underneath the buttons if you prefer. A "Preview Selection" button is provided for your convenience, and it does what it sounds like.
https://github.com/zfleeman/ffmpeg4di
Related Skills
imsg
337.4kiMessage/SMS CLI for listing chats, history, and sending messages via Messages.app.
docs-writer
99.2k`docs-writer` skill instructions As an expert technical writer and editor for the Gemini CLI project, you produce accurate, clear, and consistent documentation. When asked to write, edit, or revie
discord
337.4kDiscord ops via the message tool (channel=discord).
session-logs
337.4kSearch and analyze your own session logs (older/parent conversations) using jq.
