启动前必须先把 .env.example 复制为 .env 并设置 POSTGRES_PASSWORD,否则数据库起不来;默认访问端口是 7080,不是 80;iOS 和 Mac 构建存在但维护者没有 Apple 硬件、未做测试。
cp .env.example .env # set POSTGRES_PASSWORD
docker compose up -d # pulls ghcr.io/kaybi-gh/k7:latestREADME 未说明 CPU、内存或显存要求,也未列出支持的 GPU 厂商与型号;仅说明转码依赖 ffmpeg,Windows 端 Direct Play 视频解码依赖 LibVLC。
自托管媒体服务器,给家人朋友小圈子放本地电影剧集和音乐
自托管的媒体服务器,面向家庭和小圈子朋友共享电影、音乐,支持 Docker 部署,可作为 Jellyfin 的替代方案。
核心能力
- 用 ffmpeg 转 HLS 流,客户端或网络扛不住原片也能播
- 两台 K7 实例可联邦互联,共享并串流远端媒体与元数据
- 支持 Web、Android 手机与 TV、Windows、iOS、Mac、Linux 多端
- Sync Play 远程同步播放,多设备一起看或听
- 可接 OpenSubsonic 客户端,如 Symfonium、Feishin
容易踩的坑
- v1.17.3K7 v1.17.3最新正式版2026-11-06 · 2026-11-06 21:30 UTC
Highlights
-
Performance improvements (both clients and server): less UI re-rendering (cards, nav, mini player, TV spatial nav, home feed), cheaper detail heroes and theme songs, faster home / HLS / token / MediatR paths on the server, and deferred web player scripts. Android keeps improving cold start with an unattended in-app AOT tour profile and splash removal deferred until after the first layout.
-
Content ratings: numeric age labels (
13,13+, ...) are parsed for restrictions and the rating is shown on movie pages. It allows administators to define a real age on medias instead of a public content rating (also allows to unofficially use common sense ratings for instance). -
Playlists & collections: full playlists and collections paginate for browse and play, and dynamic playlist detail restores title / artist / album columns.
-
Access & scan: excluded libraries stay hidden from radio, top tracks and media detail. Indexed files are kept when the library root is temporarily unreachable.
Changes
Features
- feat(restrictions): parse numeric content rating ages
- feat(maui): report blazor errors in release builds
- feat(clients): add opt-in page performance measurements
Performance
- perf(android): generate automated tour.aprof
- perf(ui): skip review spoiler lookups when there is nothing to blur
- perf(ui): stream theme songs with authenticated maui playback
- perf(ui): render the app nav only when its badge counts change
- perf(ui): skip media card renders when nothing displayed changed
- perf(ui): stop rendering the hidden mini music player copy
- perf(ui): apply season episode focus without rendering the page
- perf(ui): cheapen tv spatial navigation and drop permanent card layers
- perf(ui): paint detail page heroes before the library group and theme song
- perf(ui): skip the keep watching refetch when the playing media already leads the row
- perf(series): resolve the episode to play on the server
- perf(web): load player scripts after first paint and the cast sender asynchronously
- perf(server): log streaming, image and hub requests at debug
- perf(server): drop the discarded ffmpeg pass in dominant color extraction
- perf(server): save rescanned indexed files in batches
- perf(server): split the top-level home feed query
- perf(server): read each hls segment once and load timelines without tracking
- perf(server): compress api json reads and decode them in socket-based maui heads
- perf(server): issue signed instead of encrypted access tokens
- perf(server): authorize mediatr requests on role claims before the identity store
- perf(server): bump only the reporting user's cache version on progress ticks
- perf(metadata): build movie cast from tmdb credits and enrich new persons in background
- build(maui): record aot profiles with an unattended in-app tour
Bug Fixes
- fix(android): defer splash removal until after the first layout
- fix(playlists): restore title artist album columns on dynamic playlist detail
- fix(playlists): paginate full playlist and collection items for browse and play
- fix(access): hide excluded libraries from radio, top tracks and media detail
- fix(scan): keep indexed files when the library root is unreachable
- fix(server): register noop device storage for shared layouts
- fix(server): scope media etags and query cache to the user, shared profile and server run
- fix(ui): show content rating on movie pages
- fix(ui): keep tv ok on the focused control when no player is visible
- fix(ui): coalesce home feed refreshes around playback
- fix(ui): keep the movie page state per instance
- fix(ui): release closed dialog entries
- fix(ui): release the fullscreen listener with the player and stop reallocating visualizer canvases
Docs / Dependencies
- docs: add privacy policy
- chore(deps): bump blazor-apexcharts to 7.1.0
- chore(deps): bump xamarin.androidx.fragment.ktx to 1.9.1
- chore
-
- v1.17.2K7 v1.17.22026-10-29 · 2026-10-29 21:08 UTC
查看更新说明
Highlights
-
Huge improvement on Android clients cold start
Device Metric Before After Nokia Streaming Box 8000 (32-bit, Android TV) Home screen ~33 s ~9 s Nokia Streaming Box 8000 (32-bit, Android TV) User picker ~33 s ~7 s Pixel phone Home screen ~5 s 1.7 s Pixel phone User picker ~5 s 1.1 s The release APK grows from 69 MB to 77 MB because of the recorded ahead-of-time compilation profile. As a side effect, my super lottie animation won't be displayed for long anymore. 😢
-
Android sign-in / MFA: Custom Tabs antiforgery failures after 2FA are recovered, empty auth-form 400s are handled, 2FA cookies are hardened, and native login lands on
auth-completeso thek7://handoff completes reliably. -
Music sessions: a restored queue comes back paused (not stuck buffering). Queues are no longer mixed across users on the same device, each identity keeps its own saved session (as intended).
-
UI polish: QR page back button now sits in the corner, focus returns to the page after stopping the mini player, and the media page backdrop no longer races a disposed JS module.
Changes
Performance
- perf(maui): add custom aot profile
- perf(maui): speed up android cold start
Bug Fixes
- fix(auth): recover android custom tabs mfa antiforgery failures
- fix(auth): recover empty auth form 400 and harden 2fa cookies
- fix(auth): land android native login on auth-complete
- fix(maui): keep a restored music session paused instead of buffering
- fix(maui): report the inner exception of unobserved task failures
- fix(clients): reset the music queue when another user signs in
- fix(ui): give focus back to the page after stopping the mini player
- fix(ui): position the qr page back button in the corner
- fix(ui): avoid the disposed module race in the media page backdrop
- fix(web): never cache the link preview document
Docs / Dependencies
- docs(dev): document native login landing on auth-complete
- chore(deps): bump docker
- chore(deps): bump postgres:18-alpine docker digest
Artifacts
- Docker (server):
ghcr.io/kaybi-gh/k7:1.17.2 - Docker (import):
ghcr.io/kaybi-gh/k7-import:1.17.2 - Android:
K7-1.17.2-android.apk - Windows:
K7-1.17.2-win-x64.zip - Linux:
K7-1.17.2-linux-x64.flatpak(Flatpak bundle) - iOS:
K7-1.17.2-ios-sideload.ipa(AltStore source:apps.json)
-
- v1.17.1K7 v1.17.12026-10-25 · 2026-10-25 22:20 UTC
查看更新说明
Highlights
-
.NET October 2026 security updates: server, Docker images, and self-contained clients are rebuilt on .NET 10.0.14 / SDK 10.0.403 (OOB).
-
Intro / outro detection: neighbouring episodes, bridging noisy chromaprint runs, and named chapter fallback improve markers. Diagnostics list Intro vs Outro separately and retry incomplete segments.
-
Music merges: Fix all refreshes MusicBrainz stamps before merging (title-aware recording / ISRC). A shared ISRC is ignored when tracks already have distinct MusicBrainz recording ids.
-
Phone / TV UX: reactive seek thumbs, gesture catchers inset from system edges, season scroll restored after playback, TV device-link QR refreshes when its timer ends.
Changes
Security / Dependencies
- chore(deps): bump dotnet monorepo (SDK 10.0.403, ASP.NET / runtime packages 10.0.14)
- chore(deps): bump microsoft runtime
- chore(deps): bump docker
- chore(deps): bump scalar.aspnetcore.microsoft to 2.18.3
- chore(deps): bump bunit to 2.13.3
Bug Fixes
- fix(media): improve intro detection with bridging, neighbors, and chapter fallback
- fix(media): title-aware recording stamps and refresh before merge
- fix(diagnostics): show intro vs outro detail and retry incomplete segments
- fix(diagnostics): keep intro/outro pages populated across virtualize slices
- fix(diagnostics): exclude tracks from missing metadata and raise intro detect timeout
- fix(diagnostics): ignore shared isrc when musicbrainz recordings differ
- fix(ui): use real links for diagnostics detail navigation
- fix(ui): restore season episode scroll after playback on phone
- fix(maui): make phone seek thumbs reactive
- fix(maui): inset video gesture catchers from system edges
- fix(clients): refresh tv device-link qr and keep expired profiles on picker
- fix(radio): exclude rated tracks from discovery mixes
Artifacts
- Docker (server):
ghcr.io/kaybi-gh/k7:1.17.1 - Docker (import):
ghcr.io/kaybi-gh/k7-import:1.17.1 - Android:
K7-1.17.1-android.apk - Windows:
K7-1.17.1-win-x64.zip - Linux:
K7-1.17.1-linux-x64.flatpak(Flatpak bundle) - iOS:
K7-1.17.1-ios-sideload.ipa(AltStore source:apps.json)
-
- v1.17.0K7 v1.17.02026-10-23 · 2026-10-23 16:34 UTC
查看更新说明
Breaking changes
- Linux packages: the
.deband.tar.gzclients are dropped. Linux ships as a Flatpak only (K7-1.17.0-linux-x64.flatpak). Install with Flatpak, thenflatpak run com.k7.maui.
Highlights
-
Linux Flatpak: the desktop client is packaged as a Flatpak (GNOME Platform runtime, player and
k7://handler included), so it no longer depends on the host GTK / WebKit / GStreamer versions. -
Multi-disc music import: disc and track numbers are parsed from filenames and folders, so multi-disc albums match on disc+track instead of title alone, and MusicBrainz picks the release from layout / tagged release id more reliably.
-
Diagnostics merges:
Fix allcan merge duplicate persons and music artists in the background (richest metadata wins, roles reattach). Album merges are harder to get wrong (same-album shells, format pairs, import shells listed and file-less rows hidden). -
Import shells: a later import reuses the matching playable album instead of leaving another imported shell when artist and album already match.
Changes
Features
- feat(linux): add flatpak packaging
- feat(music): parse disc and track from filename and folders
- feat(diagnostics): merge person and artist duplicates in background
- feat(metadata): backfill avatar picture variants on request
Bug Fixes
- fix(music): preserve dotted titles when stripping audio extensions
- fix(music): stamp distinct recording ids for same-title tracks
- fix(music): pick musicbrainz release from layout and tagged release id
- fix(music): match album tracks by disc not title alone
- fix(music): match albums by folder not title alone
- fix(music): fall back solo artist formation date to birth date
- fix(music): hide file-less albums and tracks from artist views
- fix(music): play artist radio from linked and similar tracks
- fix(import): reuse matching playable album instead of imported shell
- fix(diagnostics): list import shells and hide file-less album rows
- fix(diagnostics): harden album merge and repair same-album duplicates
- fix(diagnostics): ignore spotify-only ids for missing metadata
- fix(metadata): soft-cancel missing pictures and keep local files
- fix(metadata): sync episode cast and guest stars on refresh
- fix(player): wait and retry while subtitle vtt extracts
- fix(playback): force stereo aac on windows and linux quality promote
- fix(linux): range http media input and player fixes
- fix(linux): harden quality teardown and rating stars
- fix(windows): clear d3d11 letterbox after aspect change
- fix(windows): soft-release d3d on quality swap
- fix(maui): show select-user carousel when solo session expired
- fix(ui): debounce serie season cast and restore tv scroll
- fix(ui): route similar media by card kind on serie page
- fix(ui): convert nullable numbers in k7 text field
- fix(ui): outline stats ranked table cards
- fix(medias): include user ratings on nested detail payloads
- fix(deps): pin cryptography packages for nuget audit
- fix(linux): skip flatpak debuginfo strip without elfutils
- fix(linux): disable flatpak strip via manifest build-options
Performance
- perf(metadata): batch person resolve and raise serie refresh timeout
CI / Docs
- ci(linux): publish flatpak only
- docs(import): note playable album merge instead of shell
Artifacts
- Docker (server):
ghcr.io/kaybi-gh/k7:1.17.0 - Docker (import):
ghcr.io/kaybi-gh/k7-import:1.17.0 - Android:
K7-1.17.0-android.apk - Windows:
K7-1.17.0-win-x64.zip - Linux:
K7-1.17.0-linux-x64.flatpak(Flatpak bundle) - iOS:
K7-1.17.0-ios-sideload.ipa(AltStore source:apps.json)
- Linux packages: the
- v1.16.0K7 v1.16.02026-10-11 · 2026-10-11 20:47 UTC
查看更新说明
Highlights
-
Playback history search: My Space history and the admin history panel can filter by media title.
-
Diagnostics: medias duplicates (medias that share the same provider id) can be merged from
Fix allon the admin diagnostics page (the richer entry is kept, user state moves over). The dashboard also shows an all-clear state when there is nothing left to fix. -
Disk free space: the admin dashboard lists free space for each mounted library disk (and the usual path mounts), with a simple color cue when space runs low.
-
Settings about page: new links for quick access to GitHub repository, documentation and release notes.
Changes
Features
- feat(diagnostics): merge shared external ids and keep cross-album tracks
- feat(music): import the artist formation date from musicbrainz
- feat(ui): show country and formation date on the artist page
- feat(ui): show an all-clear state when diagnostic totals are zero
- feat(admin): show free space for each mounted library disk
- feat(history): search playback history by media title
- feat(ui): link the about page to github docs and release notes
Bug Fixes
- fix(diagnostics): flag artists that have no formation date
- fix(diagnostics): ignore missing genres on episodes and seasons
- fix(medias): prefer the populated serie when an external id is shared
- fix(ui): show k7 menus as bottom sheets in a narrow desktop window
- fix(ui): surface library scan on the admin card
- fix(social): show federation-scoped reviews to local users
- fix(ui): keep the mini player from covering mobile settings
- fix(ui): load watch state and show series seasons albums and artists
Artifacts
- Docker (server):
ghcr.io/kaybi-gh/k7:1.16.0 - Docker (import):
ghcr.io/kaybi-gh/k7-import:1.16.0 - Android:
K7-1.16.0-android.apk - Windows:
K7-1.16.0-win-x64.zip - Linux:
K7-1.16.0-linux-x64.deb(Debian / Ubuntu),K7-1.16.0-linux-x64.tar.gz - iOS:
K7-1.16.0-ios-sideload.ipa(AltStore source:apps.json)
-
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
K7 is a self-hosted media server for a small circle of family and friends.
The name comes from the French pronunciation /ka.sɛt/ (cassette). The idea is to bring back that feeling of a shelf at home: audio tapes, VHS, everything yours and local.
More screenshots: screenshots/README.md.
Demo
Access the live demo here. Only guest login is available, so features that require a full account are not accessible.
Quick start (Docker)
cp .env.example .env # set POSTGRES_PASSWORD
docker compose up -d # pulls ghcr.io/kaybi-gh/k7:latest
Open http://localhost:7080 and complete first-run setup. Install details: docs/admin/install.md.
Features
Core
- Open source (AGPL-3.0) - your server, your rules, no vendor lock-in
- Simple to deploy - no complex stack required
- Movies, TV series, and music - one shelf for everything you already own locally (more types may come)
- Local auth + optional 2FA + optional OIDC - works offline at home, plug in your identity provider when you need SSO
- Guest mode - optional limited access without a personal account (admin-controlled)
- Transcoding (ffmpeg, HLS) - play anywhere, even when the client or network cannot handle the original file
- Federation - link two K7 instances (yours and a friend's) to share and stream remote media and metadata without duplicating files
Clients
- Web, Android (phone + TV), Windows, iOS, Mac, Linux (experimental GTK4) - same UI everywhere (Blazor WASM or MAUI + Blazor)
- Fully keyboard-navigable - spatial navigation across the whole app
- Remote control - drive playback on one device (TV, phone, browser) from another logged-in client on the same server
- Chromecast (Web and Android only) - cast video and music to any supported device
- OpenSubsonic - connect apps like Symfonium or Feishin with an app password (Settings -> External clients)
- iOS and Mac builds exist but are not tested by the maintainer (no Apple hardware)
Personalization
- Server-wide defaults - the admin can set default values for almost all customization (home layout, video player, playback, track selection, and more); each user can override them in their own settings
- Custom home page - pin what matters to you instead of a one-size-fits-all dashboard
- Custom navigation - optional shortcuts (library groups, collections, playlists, app pages) as a Home row or a desktop bar under the top menu
- Global media filters - hide content you never want to see, across the whole app
- Playback preferences - quality, subtitles, intro skip, seekbar thumbnails, and more, so each viewing session feels right
- Library and profile restrictions - fine-tune who can access what beyond simple sharing rules
- Editable metadata with field locks - fix or override titles, descriptions and more, lock individual fields so metadata refreshes do not overwrite your changes
Your space
- Playlists, collections, history, stats, reviews - one place for "your" corner of the shelf, not buried in admin screens
- Dynamic playlists - rule-based lists (genre, year, play count, artist, and more) that re-evaluate as your library grows, like a mixtape that updates itself
- Offline downloads - take media on native clients and sync progress when you are back online
Music discovery (AudioMuse AI)
- Optional integration with self-hosted AudioMuse AI - mood radios, similar tracks, sonic paths, and playlists built from a text prompt, plus natural-language search in the library
- Keeps AI-assisted discovery on infrastructure you control; disabled by default until you connect your AudioMuse server
Social
- Sync Play - watch or listen together remotely, as if you were on the same couch
- Shared profiles - follow a series as a couple (or any group) with merged stats and history on each account
- Visibility controls - separate what you share and what you accept to see, per content type (playback history, reviews, collections, playlists, dynamic playlists) from and to whoever you want: nobody, your local server, federated servers, specific people
Administration
- Dashboard, diagnostics, background tasks - see what the server is doing without SSH
- Outgoing notifications - customizable webhook rules (event filters, payload templates) to plug K7 into your own tools
- Import tool - migrate from Plex, Jellyfin, Spotify, and more (tools/K7.Import)
Documentation
All guides (users, admins, developers): docs/README.md.
Community
This project was built for my own specific needs. While I think it could benefit some people, making it free and open source does not mean I will work on every feature request.
Contributions are welcome:
- Issues - bugs (not security reports; see SECURITY.md)
- Discussions - ideas, feature requests, and questions
- Pull requests - opening a PR does not guarantee a merge
Please read CONTRIBUTING.md for guidelines and to start contributing.
Code of conduct
Be respectful and constructive. Harassment and bad-faith behavior are not tolerated. Maintainers may close or remove contributions that violate this.
Support
While a simple thank you is more than enough, I do accept donations. If K7 is useful to you and you feel like chipping in, the Sponsor button on this repository is the simplest way to do that.
K7 also relies on many other open source projects and communities listed below, many of them welcome donations too.
Special thanks
K7 would not exist without the work of many projects and communities, including:
- FFmpeg - transcoding and media processing
- LibVLC - Windows Direct Play video decoding
- OpenIddict - authentication and OIDC
- AudioMuse AI - optional music intelligence
- MusicBrainz - music metadata
- TMDb - movie metadata
- TheTVDB - TV series metadata
- Wikimedia Commons, Wikidata, and Wikipedia - artist images and person metadata
- Chromaprint / AcoustID - audio fingerprinting
- TagLibSharp - reading and writing media tags
- Phosphor Icons - UI icons
See the in-app About page for a fuller list of credits.
License
K7 is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). If you modify K7 and provide it over a network, you must share your changes under the same license.