A minimal private video streaming service built with Rust and Svelte.
Upload video files in any common format, get a shareable link, and stream immediately. Non-native formats get a fast 480p preview for quick playback while full quality transcodes in the background.
See demo.mp4 for a quick walkthrough of the upload → processing → playback flow.
git clone https://github.com/kirrarista/vidstream.git
cd vidstream
make build
make run
# Server starts at http://localhost:3000
make docker
# Or manually:
docker build -t vidstream .
docker run -p 3000:3000 vidstream
Run the backend and frontend separately for hot reload:
# Terminal 1: Backend
cd backend
cargo run
# Terminal 2: Frontend (with API proxy to backend)
cd frontend
npm run dev
The Vite dev server runs on port 5173 and proxies /api requests to the backend on port 3000.
vidstream/
├── ARCHITECTURE.md # Design document
├── Makefile # Build commands
├── Dockerfile # Multi-stage build
├── demo.mp4 # Demo video
├── backend/
│ ├── Cargo.toml
│ └── src/
│ ├── main.rs # Server setup and routing
│ ├── handlers.rs # Upload, stream, list, status endpoints
│ ├── transcode.rs # FFmpeg transcoding pipeline
│ ├── db.rs # SQLite initialization
│ └── error.rs # Error types
└── frontend/
├── package.json
└── src/
├── App.svelte # Router
├── Upload.svelte # Upload page
├── Watch.svelte # Video player page
└── main.js # Entry point
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/upload | Upload a video (multipart form, field name: video) |
| GET | /api/videos/{uuid} | Stream a video (supports range requests) |
| GET | /api/videos/{uuid}/status | Get processing status and quality |
| GET | /api/videos | List recent uploads |
MP4, WebM, MOV, AVI, MKV, FLV, WMV, 3GP, OGV, M4V, TS
All formats are transcoded to MP4 (H.264 + AAC) for universal browser playback. Files already containing H.264 are remuxed without re-encoding.
See ARCHITECTURE.md for detailed design decisions, transcoding pipeline, and scaling considerations.