Self-hosted service
mtvpls/MoonTVPlus avatar
mtvpls/MoonTVPlus

MoonTVPlus: A Self-Hosted Video Aggregator That Ships with No Sources

MoonTVPlus 是基于 MoonTV v100 二次开发的增强版影视聚合播放器。它在原版基础上新增了外部播放器支持、视频超分、弹幕系统、评论抓取等实用功能,提供更强大的观影体验。

3,306 stars3,080 forksTypeScriptNOASSERTION

At a glance

What is it?
MoonTVPlus is a Next.js web application forked from MoonTV v100 that aggregates online video sources into a single browsable interface. It adds Anime4K super-resolution, a danmu bullet comment system, group watch rooms, and multi-platform deployment support, but it deploys as an empty shell with no built-in streams and an unresolved license identifier.
Who is it for?
MoonTVPlus suits developers who want a self-hosted video aggregation front end and are willing to curate their own video sources. It is not a fit for anyone expecting built-in streams or a plug-and-play setup; the README explicitly states the project deploys as an empty shell with no built-in video or live sources.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

An Aggregator Shell: What MoonTVPlus Does and Requires from Operators

MoonTVPlus is a web application for aggregating and playing online video from third-party sources. It is a fork of MoonTV v100, originally from MoonTechLab/LunaTV, and extends the base with a collection of additional features. The interface provides multi-source search, episode lists, actor metadata, favorites, and watch progress synchronization.

The most important operational fact about MoonTVPlus is that the README states clearly: after deployment, the project is an empty shell with no built-in video sources or live streams. Operators must collect their own sources and configure them separately. This is not a media server that indexes local files; it is a front end that relies on externally defined source scripts and configurations that the operator provides. A developer who deploys the application and opens it in a browser will find no content until sources are configured.

The README also includes an explicit request not to publish promotional content about the project on Chinese social media platforms including Bilibili, Xiaohongshu, WeChat public accounts, Douyin, or Toutiao, and states that no tech newsletter or aggregation sites are authorized to feature it.

Capabilities Added Beyond the MoonTV Base

The README lists the additions relative to the original MoonTV. External player redirection lets the browser hand off playback to PotPlayer, VLC, MPV, MX Player, nPlayer, or IINA. Video super-resolution uses Anime4K via WebGPU at scale factors of 1.5x, 2x, 3x, and 4x. A full danmu (bullet comment) system adds search, matching, loading, persistent settings, and blocking. Douban movie review scraping fetches short reviews with paginated loading.

Beyond those four headline additions, the README lists torrent and magnet search aggregating Mikan, Nyaa, ACG.RIP, and Dongman Huayuan with seedling health checking and push to OpenList for offline download. A WebTV mode provides a television-optimized interface with QR code login and a phone-as-remote-control feature. Anime subscription tracking identifies fansub groups and episode numbers, triggers automatic library entry or download, and sends update notifications. External subtitle loading supports ASS/SSA special effects subtitles and PGS image subtitles. An AI movie assistant responds to natural-language queries. Group watch rooms support synchronized playback, screen sharing, real-time chat, and voice calls. M3U8 download merges segments in the browser. Server-side offline download supports resumable transfers. The private media library connects to OpenList, Emby, or Xiaoya.

Deployment Platforms and Docker Environment

The README lists five deployment targets: Docker, Vercel, Netlify, Cloudflare Workers, and EdgeOne Pages. One-click deploy buttons for Vercel, Netlify, Zeabur, and Render are provided in the README. For Cloudflare Workers, the project uses GitHub Actions with a workflow file already included in the repository at .github/workflows/cloudflare-deploy.yml. Automatic deployment on push can be configured with this trigger block:

yaml
on:
  push:
    branches:
      - main  # 或你的主分支名称
  workflow_dispatch:

For Docker, the Dockerfile uses a three-stage build on node:24-alpine. The runtime image sets these default environment variables:

dockerfile
ENV PORT=3000
ENV SQLITE_DB_PATH=/app/.data/moontv.db
ENV OFFLINE_DOWNLOAD_DIR=/data

The application listens on port 3000. SQLite database files are written to /app/.data/moontv.db by default, which means a Docker volume mount is required for persistence across container restarts. The package.json start script is NODE_ENV=production node server.js, using a custom server that includes Socket.IO support rather than the default Next.js server, which is how the group watch and real-time features are implemented.

Storage Backend Options for Watch Progress

MoonTVPlus supports several storage backends for watch progress and favorites synchronization. The README and configuration files reference Kvrocks, Redis, Upstash (a managed Redis service), Cloudflare D1 (a serverless SQLite database), Turso (a cloud SQLite service), and local SQLite.

The NEXT_PUBLIC_STORAGE_TYPE environment variable selects the backend, accepting values such as upstash, d1, and turso. For the default Docker deployment, SQLite is used and the database file lives at the path set by SQLITE_DB_PATH. For Cloudflare Workers deployments, the README recommends Upstash because Cloudflare's execution model does not support a persistent local file system; D1 is offered as an alternative. For EdgeOne Pages, the README recommends Turso and includes a pnpm init:turso initialization step for setting up the table schema. The package.json includes separate init scripts for each backend: init:sqlite, init:postgres, and init:turso.

This variety of backends reflects the range of deployment environments the project targets, but it also means configuration requirements differ significantly between platforms. An operator deploying to Docker has different storage setup steps than one deploying to Cloudflare Workers.

Legal Uncertainty and Operational Limits

The repository includes a LICENSE file, but the license identifier is NOASSERTION: GitHub's automated detection could not resolve it to a recognized SPDX expression. Developers intending to use, fork, or redistribute MoonTVPlus must read the LICENSE file directly before doing so.

The project has published no GitHub releases. The package.json shows version 0.1.0. There is a CHANGELOG file in the repository root, but release history is not tracked through GitHub's release mechanism, so there is no tag-based record of changes.

WebGPU availability limits where Anime4K super-resolution works. WebGPU is not available in all browsers or environments; Safari added it in a limited form later than Chromium-based browsers, and server-side rendering contexts do not expose it at all. The README does not document a fallback for browsers without WebGPU support. The danmu system, Douban review scraping, and torrent search all depend on third-party services that are outside MoonTVPlus's control and may break if those services change their APIs.

Comparing with Jellyfin and Maintenance State

Jellyfin is the most commonly referenced open-source self-hosted media server for home use. It indexes and streams media from a local file library: video files stored on disk are transcoded or direct-played through the Jellyfin server. It is Apache 2.0 licensed and runs on Linux, Windows, and macOS without needing a cloud deployment platform. The fundamental difference is that Jellyfin manages locally stored files, while MoonTVPlus aggregates links to third-party online streams. A team that owns a library of video files and wants to stream them across devices should evaluate Jellyfin. A developer who wants to build a front end for browsing and playing online stream sources should evaluate MoonTVPlus. The two tools do not overlap in architecture or data model, despite both presenting a video browsing interface.

MoonTVPlus's last recorded push to the main branch was on 2026-09-25. The repository is not archived.

Editorial conclusion

MoonTVPlus suits developers who want a self-hosted video aggregation front end and are willing to curate their own video sources. It is not a fit for anyone expecting built-in streams or a plug-and-play setup; the README explicitly states the project deploys as an empty shell with no built-in video or live sources. Before deploying, read the LICENSE file directly since the identifier is NOASSERTION, and confirm the storage backend, as SQLITE_DB_PATH defaults to /app/.data/moontv.db and must be mounted as a volume for persistence in Docker.

Frequently asked questions

Does MoonTVPlus include built-in video sources or live streams?

No. The README explicitly states that after deployment, the project is an empty shell with no built-in video sources or live streams. Operators must collect and configure their own sources using the video source script system.

What storage backends does MoonTVPlus support for watch progress?

MoonTVPlus supports Kvrocks, Redis, Upstash, Cloudflare D1, Turso, and local SQLite. The backend is selected via the NEXT_PUBLIC_STORAGE_TYPE environment variable. The default Docker deployment uses SQLite at /app/.data/moontv.db.

Which external players does MoonTVPlus support for playback redirection?

The README lists PotPlayer, VLC, MPV, MX Player, nPlayer, and IINA as supported external players. The external player redirect feature hands off playback from the browser to the selected application.

Official sources

  1. Issues
  2. mtvpls/MoonTVPlus on GitHub
  3. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/mtvpls-moontvplus.svg)](https://hysenlabs.com/projects/mtvpls-moontvplus)