Development setup¶
The project uses uv. Python 3.11 to 3.14 is supported; .python-version pins 3.12 for local work and CI.
git clone https://github.com/jessielw/FFMPEG-Audio-Encoder.git
cd FFMPEG-Audio-Encoder
uv sync --group dev
uv run ffmpeg-audio-encoder
You need FFmpeg and ffprobe on PATH, or configured in application settings. The optional encoders are optional here too - see Required and optional tools.
Dependency groups¶
| Group | Contents | Sync with |
|---|---|---|
dev (default) |
ruff, basedpyright, pytest, pytest-qt, pytest-timeout | uv sync --group dev |
build |
PyInstaller, Pillow, setuptools | uv sync --group build |
docs |
Zensical | uv sync --group docs |
dev is uv's default group, so uv sync --group docs gives you dev and docs. Use --only-group docs when you want Zensical alone - that is what the docs workflow does, and it will uninstall your dev tools if you run it against a shared local environment.
Quality checks¶
The same four commands CI runs, in the same order:
ruff format (without --check) applies the formatting. Line length is 100.
basedpyright runs in standard mode overall, and strict for src/ffmpeg_audio_encoder/domain and src/ffmpeg_audio_encoder/encoders - the two layers that carry no Qt and no I/O.
The encoder reference page is generated by the docs build rather than committed, so there is nothing to keep in sync by hand - see working on the docs.
Tests¶
uv run pytest # everything
uv run pytest tests/test_queue.py # one file
uv run pytest -k deezy # by name
Tests time out after 60 seconds each, enforced on a thread. UI tests use pytest-qt; set QT_QPA_PLATFORM=offscreen if you are running headless, as CI does.
The integration tests (test_integration_ffmpeg.py, test_integration_external.py) invoke real encoders and skip when the tool is unavailable.
Running the application¶
uv run ffmpeg-audio-encoder
uv run ffmpeg-audio-encoder --version
uv run ffmpeg-audio-encoder --diagnostics
Unrecognised arguments are forwarded to QApplication, so Qt's own flags work:
A note on CI's FFmpeg matrix¶
The quality job runs twice: once against the distribution FFmpeg and once against a current static build. That is not redundancy. An ffmpeg 9 filter regression got past every green run when only the distribution build was tested, and was not caught until a release tag built on macOS and Windows, whose package managers ship the newer ffmpeg.
If you touch filter-graph construction, expect both to matter.
Next¶
- Architecture - how the layers fit together
- Adding an encoder
- Building bundles
- Working on the docs