A private, opinionated, self-hosted video library.
Warning
This project is unfinished and under active development.
The filesystem is the source of truth:
/videos/
├── Standalone video.mp4
├── Standalone video.mp4.json
└── Saved playlist/
├── playlist.json
├── cover.jpg
├── 01 - First video.mp4
└── Section name/
└── 01 - Next video.mkv
- A video directly under
/videosis standalone. - A top-level folder is a playlist.
- One nested folder inside a playlist is a playlist section.
- Deeper folders are ignored and reported during scans.
- Number prefixes set natural order and are removed from display titles.
Supported video files include MP4, M4V, MKV, WebM, MOV, AVI, MPEG, and MPG. The app watches the folder and also supports manual and scheduled scans.
playlist.json is optional:
{
"version": 1,
"title": "Saved playlist",
"description": "Archived talks",
"cover": "cover.jpg",
"authors": ["Jane Smith"],
"tags": ["Talks", "Technology"],
"source": {
"provider": "Example",
"url": "https://example.com/playlist"
}
}A video sidecar uses the complete filename plus .json, such as First video.mp4.json:
{
"version": 1,
"title": "First video",
"authors": ["Jane Smith"],
"tags": ["Archive"],
"chapters": [
{ "title": "Introduction", "startSeconds": 0 },
{ "title": "Main topic", "startSeconds": 416 }
]
}Playlist authors and tags are inherited by its videos for display, search, and filtering. There are no categories.
docker run --rm \
--publish 80:80 \
--env SESSION_SECRET="$(openssl rand -hex 32)" \
--env AUTH_SETUP_TOKEN="choose-a-one-time-setup-token" \
--read-only \
--tmpfs /tmp \
--cap-drop ALL \
--cap-add DAC_OVERRIDE \
--cap-add NET_BIND_SERVICE \
--security-opt no-new-privileges \
--device /dev/dri:/dev/dri \
--volume videos-data:/data \
--volume /path/to/videos:/videos:ro \
ghcr.io/wajeht/videos:latestOpen localhost, enter AUTH_SETUP_TOKEN, and create the library password. /dev/dri enables Intel Quick Sync for incompatible videos; CPU re-encoding is intentionally disabled.
Distributed under the MIT License © wajeht.