A local video compressor for making files fit Discord upload limits.
8disc compresses videos directly in the browser using FFmpeg WASM. It is designed for quick, local MP4 compression without uploading your files to a server.
- Compress videos locally in the browser
- Desktop compression with native FFmpeg through Tauri
- Target common Discord-friendly sizes: 8 MB, 16 MB, 25 MB, 50 MB, and 100 MB
- Drag-and-drop video upload
- English and Portuguese interface
- Download the compressed MP4 immediately after processing
- SvelteKit
- TypeScript
- Tailwind CSS
- FFmpeg WASM
- Tauri
- Native FFmpeg sidecar
- Vite
Install dependencies:
pnpm installStart the development server:
pnpm devRun project checks:
pnpm checkRun all frontend and Tauri checks:
pnpm check:allBuild for production:
PUBLIC_SITE_URL=https://your-domain.example pnpm buildRun the production static server locally on port 2000:
pnpm build
pnpm serve:prodThe workflow in .github/workflows/deploy-vps.yml builds a Docker image, sends it to a VPS, and runs it with Docker Compose on port 2000.
Prepare the VPS with Docker as an administrator:
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker <deploy-user>
sudo systemctl enable --now docker
sudo ufw allow 2000/tcpAfter logging in again as <deploy-user>, verify direct Docker access:
docker compose version
docker infoThe workflow does not use sudo. The deploy user must have direct Docker daemon access and write access to VPS_APP_DIR.
Add these GitHub environment secrets (production):
VPS_HOST: server IP or hostnameVPS_USER: SSH userVPS_SSH_KEY: private SSH key allowed to connect to the VPSPUBLIC_SITE_URL: required final public origin, for examplehttps://8disc.example.com
Optional:
VPS_PORT: SSH port, defaults to22VPS_APP_DIR: deployment directory, defaults to$HOME/8discon the VPS
The workflow creates/updates:
${VPS_APP_DIR}/docker-compose.yml${VPS_APP_DIR}/.env${VPS_APP_DIR}/8disc-image.tar
The container joins the external Docker network web, which must already exist on the VPS.
Verify a deployment:
docker ps --filter name=8disc
curl -I http://127.0.0.1:2000/robots.txtSet PUBLIC_SITE_URL to the final production origin before building so canonical URLs, Open Graph URLs, robots.txt, and sitemap.xml point to the correct domain.
The production server already sends the COOP and COEP headers required by FFmpeg WASM multithreading. If you want a domain with HTTPS in front of port 2000, use Caddy as a reverse proxy:
example.com {
encode zstd gzip
header {
Cross-Origin-Opener-Policy "same-origin"
Cross-Origin-Embedder-Policy "require-corp"
}
reverse_proxy 127.0.0.1:2000
}After deploying, verify this in the browser console:
globalThis.crossOriginIsolated === true
typeof SharedArrayBuffer !== 'undefined'The Tauri desktop app uses native FFmpeg and can use hardware H.264 encoders when available on Windows: NVIDIA NVENC, Intel Quick Sync, or AMD AMF. If no GPU encoder works, it falls back to libx264.
Prepare the FFmpeg sidecars before building the desktop app:
FFMPEG_BINARY=/path/to/ffmpeg.exe FFPROBE_BINARY=/path/to/ffprobe.exe pnpm prepare-ffmpeg-sidecarFor Linux builds, point the sidecar preparation to Linux executables:
FFMPEG_BINARY=/usr/bin/ffmpeg FFPROBE_BINARY=/usr/bin/ffprobe pnpm prepare-ffmpeg-sidecarWhen preparing Windows sidecars from another OS, set TAURI_TARGET_TRIPLE explicitly, for example x86_64-pc-windows-msvc.
Optional checksum validation:
FFMPEG_BINARY=/path/to/ffmpeg.exe \
FFPROBE_BINARY=/path/to/ffprobe.exe \
FFMPEG_SHA256=<sha256> \
FFPROBE_SHA256=<sha256> \
pnpm prepare-ffmpeg-sidecarRelease builds should require checksums:
FFMPEG_BINARY=/path/to/ffmpeg.exe \
FFPROBE_BINARY=/path/to/ffprobe.exe \
FFMPEG_SHA256=<sha256> \
FFPROBE_SHA256=<sha256> \
pnpm prepare-ffmpeg-sidecar:releaseRun the desktop app in development:
pnpm tauri devBuild the desktop app:
pnpm build:tauriBuild Linux packages:
pnpm build:linuxVideos are processed locally in your browser. The app does not need to upload your media to a backend service for compression.
