A self-hosted, zero-build web media center for browsing, playing, and managing personal video collections β now with a natural-language AI assistant and a bento-style adaptive grid. Cyberpunk-themed, with a fullscreen workspace for multi-video layouts and a mobile-friendly layout.
Free. Private. No cloud. No accounts. No tracking. (The AI assistant is optional, bring-your-own-key, and stays off until you add a key β see Privacy.)
- Control the app by chatting β e.g. "loop the third clip from 1:20 to 1:45", "save this as chill mix", "download this link into my Nature folder", "play everything", "open the workspace", "how many videos are in X?"
- Powered by Google Gemini function-calling β the model can only invoke a fixed, allow-listed set of actions (loops, playlists, downloads, theater/playback, search, read-only questions). No destructive deletes via chat.
- Bring your own key (BYOK) β the API key stays server-side (a
GEMINI_API_KEYenv var, or a git-ignored config file); each user pastes their own in Settings β AI Assistant. The key is never returned by the API. - Context-aware β resolves "the third clip", clip names, "all", "this" (the clip you have open), and "save this playlist" (the one currently loaded); every reference is re-validated server-side.
- Floating glass chat orb β drag it anywhere on screen, resize the panel, double-click to reset. Reachable from every view.
- Folder-based navigation β browse your library organized by folders
- Bento grid β tiles honor each clip's true aspect ratio: portrait (9:16) clips render as tall tiles and landscape tiles tetris-fill the gaps around them (dense masonry) β no black bars, no wasted space
- Hover preview β tiles auto-play muted on hover. Cards render as lazy thumbnails and only spin up a live
<video>on hover, so a 100-video folder costs a few JPEG fetches instead of 100 open streams - Aspect-aware popup player β click a clip to watch in a draggable, resizable window that sizes itself to the video (portrait opens tall; resizing snaps to the video's shape, so it's never letterboxed)
- Download from a URL β paste a YouTube / TikTok / X / direct link and download it straight into a folder or the theater (via
yt-dlp, transcoded to browser-friendly H.264/AAC) - Import & organize β import local files into folders, create new collections, hide folders, and search instantly
- Multi-source β add multiple video directories from Settings
- Adaptive bento grid β the same aspect-honest, gap-filled layout as Browse
- Drag to reorder β grab a tile and drop it on another to swap places; tiles glide into position (snapped to the grid, never overlapping) so you can curate what sits at the top of your view
- Loop-aware hover previews β hover a clip to preview it muted; if it has a loop set, the preview plays the loop region
- Per-clip loop controls β custom loop start/end times (m:ss format)
- Play All / Pause All / Mute All β global controls
- Add clips from anywhere β browse view β add to theater
- Fullscreen multi-panel layout β drag and resize video panels freely
- 4-corner resize handles β precision layout control
- Save/restore layouts β panel positions persist across sessions
- Auto-tile β intelligent default layout if no saved positions
- Video prefetch cache β background-loads videos for instant workspace playback
- Save/load named playlists β organize different video collections
- Layout persistence β workspace layouts save with playlists
- Quick load β one click to swap your entire theater setup
- Phone layout β bottom tab bar, slide-up folder sheet, tap-to-expand search, and a toolbar overflow menu
- Tablet β starts with the collapsed sidebar rail
- Any screen β the grid reflows to fit; workspace mode is desktop-only
- Name your app β personalize the site name and theater name
- Multi-source management β add/remove video directories from the UI
- Exclude / hide folders β keep specific folders out of browsing
- Desktop mode β optional native window via pywebview
git clone https://github.com/rikachu225/video-collection.git
cd video-collection
install.bat
start.batgit clone https://github.com/rikachu225/video-collection.git
cd video-collection
chmod +x install.sh start.sh
./install.sh
./start.shThe install script will:
- Install Python if missing (via winget/brew/apt)
- Create a virtual environment
- Install dependencies
- Ask you to personalize your site name and theater name
- Generate your config
Then open http://localhost:7777 and add your video folders in Settings.
Optional β enable the AI assistant: grab a free Google Gemini API key, then either set a GEMINI_API_KEY environment variable before launching, or paste the key into Settings β AI Assistant. The assistant stays disabled until a key is present.
- Python 3.10+
- ffmpeg (optional, for thumbnail generation and codec remuxing)
- yt-dlp (optional, for URL downloads β installed by default)
- google-genai + a Google Gemini API key (optional, only for the AI assistant)
- No Node.js. No npm. No build step. No external JS libraries.
| Layer | Tech |
|---|---|
| Backend | Python 3 + Flask + Waitress (production WSGI) |
| Frontend | Vanilla HTML/CSS/JS (zero dependencies, no build) |
| AI | Google Gemini via the google-genai SDK (optional, BYOK) |
| Data | JSON files (config, playlists, theater state, layouts) |
| Streaming | HTTP Range Requests (1MB chunks, full seeking support) |
| Downloads | yt-dlp (optional) |
| Desktop | pywebview (optional native window mode) |
video-collection/
βββ server.py β Flask backend (API routes + video streaming)
βββ ai_agent.py β AI assistant: tool schema + Gemini function-calling loop
βββ static/
β βββ index.html β Single-page app shell
β βββ app.js β Core frontend logic (browse, theater, workspace, popup)
β βββ assistant.js β AI chat orb + panel
β βββ styles.css β Cyberpunk dark theme
β βββ assistant.css β AI orb + glass panel styles
β βββ favicon.svg β Cyan-purple gradient play icon
βββ data/
β βββ config.example.json β Example config (copy to config.json)
β βββ config.json β Your media paths + BYOK key (git-ignored, auto-generated)
β βββ theater.json β Current theater state (auto-generated)
β βββ playlists.json β Saved playlists (auto-generated)
β βββ folder_layouts.json β Popup player positions (auto-generated)
βββ tests/ β pytest suite (backend + AI agent)
βββ install.bat / .sh β One-click setup
βββ start.bat / .sh β Launch server
βββ desktop.py β Optional native window mode
βββ requirements.txt β Python dependencies
- Cyberpunk aesthetic β dark theme, cyan/purple accents, glass effects, subtle glow
- Apple-inspired UX β precision, minimalism, smooth interactions
- Bento layout β aspect-honest, gap-filled grids that adapt to portrait and landscape
- 4K optimized β designed for high-DPI displays, with a mobile-friendly responsive layout
| Key | Action |
|---|---|
Space |
Play/pause video (popup or all workspace videos) |
Esc |
Close popup / exit workspace / close settings |
- 100% local by default β nothing leaves your machine
- No analytics β zero tracking, zero telemetry
- No accounts β no login, no cloud sync
- Your data stays yours β config and playlists are plain JSON files on disk
AI assistant caveat (honest disclosure): the assistant is optional and disabled until you add your own Gemini key. When you do use it, your chat messages and library names (folder and clip titles) are sent to Google Gemini so it can interpret your request β that's the one thing that leaves your machine, and only while chatting. Video files themselves are never uploaded. Don't configure it (or leave it disabled) to keep the app fully offline.
This app is designed for local network use only.
The built-in LAN guard rejects any request originating from a non-private IP β only loopback and RFC-1918 ranges (10.x, 172.16-31.x, 192.168.x) can reach the API. That keeps casual misconfiguration safe.
For your own safety, please:
- Do NOT port-forward port
7777on your router - Do NOT expose it via a public domain, reverse proxy, or VPN passthrough to untrusted networks
- Do NOT run this on a machine with a public IP
The app assumes every device on your LAN is trusted. If you share Wi-Fi with people you wouldn't hand the keys to, treat the API as openly accessible to them. Your router and firewall are the real perimeter β keep them that way.
Health probe: GET /api/health returns source availability + a UTC timestamp for uptime monitoring.
AGPL-3.0 β Free to use, modify, and self-host. If you deploy a modified version as a service, you must open-source your changes. You may not sell this software or offer it as a paid service. See LICENSE.
Built with π€ by @rikachu225