Batch image, video and audio conversion on your own server.
English · Русский
Next.js 16 · React 19 · TypeScript · Sharp · FFmpeg · Redis / BullMQ
Upload files, choose output formats, apply individual or batch settings, and download the results individually or as a ZIP. Conversion runs on the server with live progress in the browser. The application interface is currently in Russian.
The internal package and deployment name is Forma (forma-converter, Compose project forma).
- Drag and drop, folders, presets, individual settings, search, filters and a virtualized queue.
- Resumable uploads in 8 MiB chunks, up to four simultaneous uploads.
- Separate image, audio, video and archive queues, retries and cancellation.
- Individual downloads with Range support, background ZIP creation and Web Share where supported.
- Session recovery through HttpOnly cookies and live updates through Server-Sent Events.
- Responsive interface, light/dark/system themes, PWA manifest and an offline fallback.
- Configurable quotas, expiration and a separate cleanup process.
| Media | Input | Output |
|---|---|---|
| Images | JPG / JPEG, PNG, WEBP, AVIF, GIF, TIFF / TIF, BMP, HEIC / HEIF, ICO | JPG, PNG, WEBP, AVIF, GIF, TIFF, BMP, ICO |
| Video | MP4, MOV, WEBM, MKV, AVI, MPEG / MPG, M4V, FLV | The same video formats, or audio extraction |
| Audio | MP3, WAV, FLAC, AAC, OGG, M4A, OPUS | The same audio formats |
HEIC is input only and requires heif-convert with compatible system codecs. Audio extraction requires an audio track. GIF/WEBP outputs can preserve animation; other image outputs use the first frame. JPG flattens transparency onto white. See format definitions.
Install Docker with Compose, clone or download this repository, and open a terminal in its root. Docker builds include Node.js, FFmpeg and HEIF tools.
docker compose up -d --buildWithout a .env file, open http://localhost:8080. If .env already exists, set APP_ORIGIN=http://localhost:8080 and use Linux executable names (ffmpeg, ffprobe, heif-convert). The origin must exactly match the browser address, including scheme and port.
docker compose ps
docker compose logs -f web worker video-worker cleanup
docker compose downThe last command stops the stack while retaining named data volumes. The default proxy binds to 127.0.0.1:8080; use the deployment guides for public access. Container memory limits total roughly 8 GiB. A dedicated guide covers a 1 GiB VPS.
Use Node.js 22, npm, a running Redis 7+, ffmpeg, ffprobe, and heif-convert for HEIC. Install system tools separately and add them to PATH or set executable paths in .env.
npm ci
cp .env.example .envIn PowerShell, use Copy-Item .env.example .env. Configure REDIS_URL and tool paths if needed. Start each process in a separate terminal:
| Process | Command |
|---|---|
| Web UI and API | npm run dev |
| Conversion queues | npm run worker |
| File expiration and cleanup | npm run cleanup |
Open http://localhost:3000. All processes must share the same Redis and storage configuration. Closing the browser does not stop conversion. After restarting the browser, unfinished uploads require selecting the original file again; retain the session cookie.
Copy .env.example to .env for overrides. See server/config.ts for defaults; Compose explicitly overrides some values.
| Setting | Local default / purpose |
|---|---|
APP_ORIGIN |
http://localhost:3000; exact browser origin |
REDIS_URL |
redis://127.0.0.1:6379 |
STORAGE_ROOT |
.data; shared by web, workers and cleanup |
FFMPEG_PATH, FFPROBE_PATH, HEIF_CONVERT_PATH |
Executable names or paths |
MAX_FILE_SIZE_IMAGE/AUDIO/VIDEO |
1 / 5 / 20 GiB, configured in bytes |
MAX_FILES_PER_SESSION |
500 |
MAX_TOTAL_SESSION_SIZE |
50 GiB, configured in bytes |
FILE_TTL / SESSION_TTL |
3,600 / 86,400 seconds |
SITE_OWNER_NAME, SITE_CONTACT_EMAIL, SITE_CONTACT_ADDRESS, SITE_HOSTING_LOCATION |
Operator details for /privacy; fill before public launch |
Limits are configurable ceilings, not performance guarantees. Adjust concurrency and memory limits to the host. Keep UPLOAD_CHUNK_SIZE aligned with Nginx client_max_body_size.
npm run typecheck
npm test
npm run buildGitHub Actions runs these checks on Node.js 22 for pushes and pull requests. Integration and browser tests require running services and isolated test data; see operations. Playwright currently uses Microsoft Edge. Previous results and untested scenarios are listed in validation notes.
| Guide | Contents | Language |
|---|---|---|
| Operations | Runtime, queues, TLS, limits and integration commands | Russian |
| VPS deployment | Installation, HTTPS, backups and troubleshooting | Russian |
| 1 GiB VPS | Ubuntu 22.04, access by IP, Termius | Russian |
| Architecture | API, jobs and storage | Russian |
| Interface design | UX and interface decisions | Russian |
| GitHub publication | Repository setup and release checklist | Russian |
| Contributing · Security | Contributions and vulnerability reporting | English / Russian |
app/ Pages, layout and API route
features/ Upload and conversion workflows
components/ Shared interface components
domain/ Formats, settings, jobs and presets
server/ API, Redis, queues, workers, storage and cleanup
tests/ Unit, integration and browser checks
infra/ Nginx and TLS configuration
scripts/ Local development and VPS utilities
Conversion requires a backend, Redis, workers and shared storage. GitHub Pages cannot host the complete application. The PWA offline page does not provide offline conversion; user files and API responses are not cached by the service worker.
Local validation is documented, but Docker/TLS deployment, Linux HEIC, real mobile devices, 10–20 GiB files and multi-server load still require verification on the target infrastructure. Accounts, billing, an S3 adapter and hardware acceleration are not implemented.
Released under the MIT License. You may use, modify and distribute the code, including commercially, provided you retain the copyright and permission notices. The software is provided without warranty. Third-party dependencies retain their own licenses.