This small Flask app accepts MKV uploads and remuxes/converts them to MP4 using ffmpeg.
Configuration
Copy .env.example to .env and set any values you need (the .env file is ignored by git).
Run the app directly with values from .env loaded by python-dotenv.
Environment variables are namespaced with the _MKV2MP4 suffix to avoid collisions (for example USERNAME_MKV2MP4, PASSWORD_MKV2MP4, PORT_MKV2MP4).
Quick start with Docker Compose:
Build and run the service (uses the bundled docker-compose.yml):
docker-compose up --build -dThe service will be available on port 5000 by default and ffmpeg is already bundled into the Docker image.
Notes:
-
ffmpegis installed inside the image; no additional host setup is required. -
The app runs with Gunicorn. The default login is
admin/password123.- The default login values are set in
.env.exampleunderUSERNAME_MKV2MP4/PASSWORD_MKV2MP4. - Configurable Gunicorn runtime options are available via environment variables in
docker-compose.yml:GUNICORN_TIMEOUT_MKV2MP4- increase if uploads or conversions take a long time (default 3600s).GUNICORN_WORKER_CLASS_MKV2MP4- worker class (defaultgthread).GUNICORN_THREADS_MKV2MP4- threads per worker (default4).CONCURRENT_CONVERSIONS_MKV2MP4- how many simultaneousffmpegconversions to allow (default1).
Recommendation: for memory-constrained environments keep
CONCURRENT_CONVERSIONS_MKV2MP4at1and increaseGUNICORN_TIMEOUT_MKV2MP4to a value large enough for uploads + conversion. Also consider giving the container more RAM (Docker Desktop resource settings) to avoid OOM kills. - The default login values are set in
- Create and activate a virtual environment:
python -m venv .venv
.\.venv\Scripts\Activate.ps1 # PowerShell on Windows
# Or on macOS / Linux:
# source .venv/bin/activate- Install Python dependencies:
pip install -r requirements.txt- Install
ffmpeg/ffprobe(must be on your PATH). For example:
# Ubuntu/Debian
sudo apt install ffmpeg
# Windows: download from https://ffmpeg.org and add to PATH- Copy
.env.exampleto.envand adjust any settings (optional), then run:
python app.pyNote:
python app.pyruns the Flask development server which is simple and cross-platform for local testing. The project uses Gunicorn inside the Docker image for a more robust, production-ready server. Gunicorn is not supported on native Windows (it requires a Unix-like environment such as WSL), so usingpython app.pyis the easiest local option on Windows.
If you prefer to run a Gunicorn server locally on macOS/Linux or inside WSL, you can use the same command the Docker image uses:
gunicorn -w 1 -b 0.0.0.0:5000 --timeout 3600 --worker-class gthread --threads 4 app:app- Open
http://localhost:5000in your browser. After uploading an MKV you'll be redirected to a progress page. You can also poll the status programmatically at/progress/<uid>(JSON) and download when finished at/download/<uid>.
The web UI now offers four processing modes when you upload an MKV:
- Auto (default): Attempts a fast remux (copying streams) and falls back to a full re-encode if that fails.
- Remux only: Only attempts a fast remux (very quick if it works). If remuxing fails the conversion stops with an error.
- Remux video + re-encode audio: Copies the video stream but re-encodes audio to
AAC(recommended if you see audio stuttering after remuxing). - Convert: Forces a full re-encode (video + audio), which is slower but most compatible.
If you're seeing audio stuttering after remuxing, try Remux video + re-encode audio - it fixes most audio compatibility problems while keeping the conversion fast.


