Repository navigation
Installation
This page covers installing Mi302: the one-line installer and its options, special cases, the mi302 management command, running it manually with Python, installing it as a MoviePilot plugin, updating and uninstalling.
The installer's messages and the web admin page are in Traditional Chinese. Where this page quotes them, the original text is given so you can match it on screen.
| Method | Good for | Start at boot |
|---|---|---|
| One-line installer (recommended) | Linux, macOS | Set up for you |
| Manual Python install | Controlling every step yourself, or Windows | Set it up yourself |
| MoviePilot plugin | Already running MoviePilot V3 | Starts with MoviePilot |
Mi302 needs Python 3.10 or newer; the installer installs it if it cannot find one. There is no Docker version of Mi302. If you used the old Docker version, see "Moving from the old Docker version" below.
On the Linux machine that will run Mi302 (on macOS, leave out sudo; see "macOS" below):
curl -fsSL https://raw.githubusercontent.com/MiCat-S/Mi302/main/install.sh | sudo bashThe script does the following, in order:
- Downloads Mi302 to the install folder (on Linux,
/opt/mi302by default). It uses git if present; if git is missing it tries to install it with the system package manager, and falls back to downloading a tarball. - Asks two questions:
-
Which user runs Mi302: defaults to the account that ran
sudo. This account must be able to read and write your media folders; the.strmfiles created by 115 sync are written as this user. - Port: defaults to 8096. Not asked if a config file already exists; the port from the config file is kept.
-
Which user runs Mi302: defaults to the account that ran
- Installs Python if no 3.10+ is found, creates a virtual environment in
.venv, installs the Python dependencies, and installs ffmpeg. ffmpeg is used for media info probing; if it cannot be installed you get a warning and everything else still works. - Sets up start at boot (the systemd service
mi302.service), starts Mi302, and waits up to 60 seconds for the web page to respond. - Prints the URLs and the management commands.
System packages are installed with whichever of apt-get, dnf, yum, apk, pacman or zypper the machine has. Once the questions are answered you can walk away; the only later prompt appears if the port is already taken by another program.
The final output looks like this (the IP is the first LAN address the script finds):
==> Mi302 已經在執行 版本 64a30e6(2026-09-27 10:00)
管理網頁: http://192.168.1.20:8096/web
播放器: 新增 Emby 伺服器,位址 http://192.168.1.20:8096
設定檔: /opt/mi302/config/config.yaml
資料和日誌:/opt/mi302/config/data/
管理指令: mi302 status | logs | restart | update | reset-password 帳號 密碼 | uninstall
The lines are: the web admin page, the address to add in players, the config file, the data and log folder, and the management commands. Open the web admin page URL and continue with First Setup. If a ufw or firewalld firewall is active, the script also prints the command that opens the port.
| Option | Meaning |
|---|---|
--user NAME |
User that runs Mi302 (Linux only). It needs read and write access to your media folders. Default: the account that ran sudo
|
--port PORT |
Port for the web page and players, 1–65535. Default 8096 |
--dir FOLDER |
Install folder. Default /opt/mi302 on Linux, ~/Mi302 on macOS. When you run install.sh from inside a Mi302 program folder, it installs into that folder |
--mirror |
Use the Tsinghua PyPI mirror for pip. Switched on automatically when PyPI cannot be reached |
--branch BRANCH |
Branch to install from. Default main
|
-y, --yes
|
Do not ask; use defaults for anything not given |
-h, --help
|
Show help |
To skip the questions, give all options at once:
# run as user cat on port 8097, defaults for everything else
curl -fsSL https://raw.githubusercontent.com/MiCat-S/Mi302/main/install.sh | sudo bash -s -- --user cat --port 8097 -yThe user, branch and pip mirror are stored in .env in the install folder; the port is stored as server.port in config.yaml. Later runs and updates reuse them, so you only pass the options you want to change.
/opt/mi302/ ~/Mi302 on macOS
config/ settings and data, kept on update
config.yaml config file (settings from the web page are written here too)
config.yaml.bak previous version of the config file
data/
library.db database: accounts, watch history, 115 login state, ...
backups/ daily automatic backups
images/ uploaded images (for example library covers)
logs/mi302.log log file
.env options chosen at install time
.venv/ Python virtual environment
install.sh, embyserver/… program
How the config file works is described in First Setup; backups in Backup and Restore.
Do not use sudo:
curl -fsSL https://raw.githubusercontent.com/MiCat-S/Mi302/main/install.sh | bash-
If you run it with
sudo, the script stops. -
The install folder is
~/Mi302. Mi302 runs as your own account; the script does not ask which user to use. -
If Python has to be installed, the script uses Homebrew to install
python@3.12; ffmpeg is also installed with Homebrew. If Python is needed and Homebrew is missing, the script stops: install Homebrew first, or install Python 3.12 from python.org. -
Start at login is handled by launchd (
~/Library/LaunchAgents/com.mi302.server.plist). Mi302 starts after you log in to macOS and is restarted if it exits abnormally. -
Terminal output goes to
~/Mi302/config/data/logs/console.log. -
The
mi302command is written to/usr/local/bin. If that folder does not exist, or your account cannot write to it (for example because it is owned by root), the script silently skips the command. The only sign is that the management commands line (管理指令) at the end showsbash /Users/<you>/Mi302/install.sh status | logs | …instead ofmi302 …. In that case replacemi302withbash ~/Mi302/install.sheverywhere on this page:bash ~/Mi302/install.sh status bash ~/Mi302/install.sh reset-password admin NEW_PASSWORD
Always give a subcommand. Without one, the script runs a reinstall, which updates Mi302 and restarts it.
Run this inside that folder (without sudo on macOS):
sudo bash install.sh- The script installs in place. Your existing
config.yamlanddata/stay where they are and keep being used; they are not moved intoconfig/. - Stop the Mi302 you started by hand first, or the port will be taken. If the script finds the port in use, it warns you and asks whether it has been stopped (已經關掉了,繼續安裝?).
- The code is updated to the latest
main. Files you changed in the program folder are first saved aslocal-changes-YYYYMMDD-HHMMSS.patch, then reset to the latest version.
Docker is no longer supported, but the settings and data in config/ carry over unchanged:
-
Note the values of
MI302_PORT(the host port) andMI302_MEDIA(the media folder) in.envin the old folder..envis rewritten by the new installer. -
Run
docker compose downin the old folder to stop the container. Keep theconfig/folder. -
Run the new installer with the one-line command and point
--dirat the old folder. If the old host port was not 8096, pass it with--port:# old folder is /opt/mi302, old host port was 8097 curl -fsSL https://raw.githubusercontent.com/MiCat-S/Mi302/main/install.sh | sudo bash -s -- --dir /opt/mi302 --port 8097
Do not run the
install.shinside the old folder: that is the old script, which still handles the install the Docker way. The new script reports that it found an old Docker install and is switching to plain Python (偵測到舊的 Docker 安裝,改成直接用 Python 執行), then installs as usual. -
Inside the container the media folder was
/media; Mi302 now sees the host's real paths. If library folders or the local folders of sync tasks still point to/media/..., change them in the web admin page to the host paths (underMI302_MEDIA). The same applies to MoviePilot path mappings. -
The container wrote files as root, so existing
.strmand.nfofiles in your media folders may belong to root. If the Mi302 user cannot change them, fix the owner withsudo chown -R USER MEDIA_FOLDER.
The old --docker and --media options are gone; passing them is an error.
Without systemd, the script runs Mi302 as a background process and reminds you to run mi302 start yourself after every reboot.
- The process ID is stored in
config/mi302.pid;mi302 stopandmi302 restartuse it to find Mi302. - Terminal output goes to
config/data/logs/console.log. - On WSL with systemd enabled, Mi302 is set up as a systemd service like on any other Linux.
After installing, manage Mi302 with mi302:
| Command | What it does |
|---|---|
mi302 or mi302 status
|
Whether Mi302 is running, the web admin URL, the version |
mi302 logs |
Show the last 100 lines of the log file and follow new lines (Ctrl+C to exit) |
mi302 start, mi302 stop, mi302 restart
|
Start, stop, restart |
mi302 update |
Update to the latest version and restart; settings and data are not touched |
mi302 reset-password USER NEW_PASSWORD |
Reset a forgotten password; if the account does not exist, it is created as an administrator |
mi302 uninstall |
Remove start at boot and the mi302 command; program, settings and data stay |
-
mi302is/usr/local/bin/mi302, which runs theinstall.shin the install folder. Somi302 statusis the same assudo bash /opt/mi302/install.sh status. - On Linux every command needs root;
mi302re-runs itself withsudo, so you may be asked for your password. - On Linux the service is the systemd unit
mi302.service, sosystemctl status mi302andjournalctl -u mi302 -falso work. On macOS it is the launchd jobcom.mi302.server.
Run the installer again with the new option. Everything already installed is reused, and Mi302 is updated along the way:
sudo bash /opt/mi302/install.sh --port 8097
sudo bash /opt/mi302/install.sh --user catTo change only the port, you can also edit server.port in config.yaml and run mi302 restart. After changing the port, update the server address in your players and your firewall rules.
You need Python 3.10 or newer (check with python3 --version). On Debian and Ubuntu, if the venv module is missing, run sudo apt install python3-venv first.
git clone https://github.com/MiCat-S/Mi302.git
cd Mi302
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
.venv/bin/python -m embyserverThen open http://<host>:8096/web and continue with First Setup.
-
config.yamland thedata/folder are created in the folder you run the command from, which isMi302/in the example. The defaultdata_dirof./datais relative to that folder, not to the config file. - Media info probing needs ffprobe. Install ffmpeg yourself, for example
sudo apt install ffmpegorbrew install ffmpeg. - To change the port, edit
server.portinconfig.yamland restart. - If pip is slow from mainland China, add
-i https://pypi.tuna.tsinghua.edu.cn/simple. - Windows: replace
.venv/bin/with.venv\Scripts\in the commands. The one-line installer does not support Windows.
| Option | What it does |
|---|---|
-c PATH, --config PATH
|
Config file to use. Without it, the environment variable EMBYSERVER_CONFIG is used, and failing that config.yaml in the current folder |
--reset-password USER NEW_PASSWORD |
Reset the password and exit. If the account does not exist, it is created as an administrator |
--scan |
Scan all libraries and exit |
--sync-115 |
Run a full 115 sync of the .strm files, then scan and send to scraping according to your settings, and exit. --sync-115 incremental runs an incremental sync instead |
Without --reset-password, --scan or --sync-115, the server starts.
Replace cat and the paths with yours and save this as /etc/systemd/system/mi302.service. WorkingDirectory must be the folder that holds data/:
[Unit]
Description=Mi302
Wants=network-online.target
After=network-online.target remote-fs.target
[Service]
User=cat
WorkingDirectory=/home/cat/Mi302
ExecStart=/home/cat/Mi302/.venv/bin/python -m embyserver -c /home/cat/Mi302/config.yaml
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.targetThen run:
sudo systemctl daemon-reload
sudo systemctl enable --now mi302Alternatively, run sudo bash install.sh inside the program folder to hand it over to the installer (see "You already cloned and ran Mi302 yourself" above).
If you already run MoviePilot V3, you can install Mi302 as a MoviePilot plugin instead of installing Python and setting up a service: Mi302 runs inside MoviePilot, starts and stops with it, and updates through its plugin market. It is the same program as a standalone install, with the same features.
- Under MoviePilot's Settings → System → Plugin market add
https://github.com/MiCat-S/Mi302-MoviePilot-Pluginsand save. - Find Mi302 in the market on the Plugins page and install it. MoviePilot installs the packages Mi302 needs (p115cipher, pypinyin, zhconv) by itself, so it must reach PyPI; MoviePilot's proxy and PIP mirror settings apply.
- Open the plugin's settings, turn on Enable (啟用) and save.
- Open
http://<host>:8096/webin a browser and follow First Setup. Add an Emby serverhttp://<host>:8096in your player.
The plugin has only these settings; everything else is in Mi302's own admin page:
| Setting | Meaning |
|---|---|
| Enable (啟用) | Mi302 runs only when this is on |
| Port (埠號) | Port for players and the admin page, 8096 by default; overrides server.port in the config file |
| Config file (設定檔) | Empty = in the plugin folder, <MoviePilot config dir>/plugins/Mi302/config.yaml, with the database, logs and backups in data/ next to it. A relative data_dir in the config file is taken from the config file's folder |
| Forgot password (忘記密碼) | Fill in a user and a new password and save to reset it (a missing user is created as an administrator); both fields are cleared after saving |
Differences from a standalone install:
- Leave MoviePilot's URL and API token empty on the MoviePilot page: Mi302 then uses the MoviePilot it runs in. If you fill in the URL of another MoviePilot, fill in its token too.
- With MoviePilot in Docker, publish Mi302's port from the container (for example
-p 8096:8096, or use host networking), and write strm files to folders the container can see and MoviePilot can use. - Updates come through MoviePilot's plugin market. Version and updates on the admin page only shows the version; Restart restarts Mi302 only, not MoviePilot.
- There is no
mi302command. Logs are on the admin page's Logs tab and indata/logs/mi302.log; info-level messages and above also go to MoviePilot's plugin log. - Saving the plugin settings in MoviePilot restarts Mi302 only when Enable, Port or Config file changed. Mi302 starts and stops when MoviePilot starts, stops or reloads the plugin; scanning, sync schedules and backups begin 10 seconds after it starts.
No copying needed; the plugin uses the existing config file and folder:
- Stop the standalone Mi302 and turn off its start at boot:
mi302 uninstallfor the one-line installer (program, settings and data stay),sudo systemctl disable --now mi302for a manual systemd setup. Both cannot run at once; they would want the same port. - Install the plugin, set Config file to the existing config file (
/opt/mi302/config/config.yamlfor the one-line installer, for example/root/Mi302/config.yamlfor a manual install) and Port to the existing port, turn on Enable and save. The database, 115 login, watch history and backups are used in place, and players need no changes. - The account MoviePilot runs as must be able to read and write the existing folder (the config file and database are readable by their owner only). With MoviePilot in Docker, mount the existing folder and the strm folders into the container at the same paths, because the config file and database record those paths.
To go back to a standalone install, disable the plugin in MoviePilot and start Mi302 the way you did before (rerun the installer for a one-line install).
MoviePilot plugin: update it on MoviePilot's Plugins page.
Installed with the one-line installer:
mi302 updateThis downloads the latest version (with git; installs unpacked from a ZIP download a tarball instead), updates the dependencies, rewrites the start-at-boot configuration, restarts Mi302 and prints the URLs. Settings and data in config/ are not touched. Files you changed in the program folder are saved as local-changes-*.patch and then reset to the latest version. Updating needs access to GitHub. Running the one-line install command again also updates.
Installed manually:
cd Mi302
git pull
.venv/bin/pip install -r requirements.txtThen restart Mi302. With the systemd unit above, run sudo systemctl restart mi302.
If you used the one-line installer (or your own git clone), you don't need a terminal: at the bottom of the left sidebar there is a version card with Restart (重新啟動) and Log out (登出) below it. Normally the card shows a tick with Up to date (已是最新版) and the current version (e.g. 0.1.0・472298c). When there is a new version it turns blue with New version (N) (有新版本) and a dot. It shows a spinner while checking or updating, Update check failed (檢查更新失敗) when a check fails, and only the version if it has never checked. The last check result survives restarts. On narrow screens they are icons in the top bar. The version card opens Version and updates (版本與更新):
- Current version: version number, commit, date and the title of this version.
-
Check for updates (檢查更新) asks GitHub right away. With Check for updates automatically (自動檢查更新) on (the default;
server.update_checkin the config file), Mi302 checks one minute after it starts and every 6 hours after that. - When there is a new version, a notice appears at the top of every page and the version card changes to New version (N) (有新版本) with a dot; the dialog lists the title of every update. Not now (先不要) on the notice hides it for that version only; the next version is announced again.
-
Update to the latest version (更新到最新版), or Update now (立即更新) on the notice, downloads the new version like
mi302 update, installs dependencies whenrequirements.txtchanged, and first tries to load the new version. If any step fails, Mi302 goes back to the previous version and does not restart; the page keeps working and shows why. Otherwise Mi302 restarts by itself and the page reloads once it is back, which takes about 10 seconds to a minute. Files you changed in the program folder are saved aslocal-changes-*.patchfirst, as withmi302 update. - Restart (重新啟動), in the sidebar or the dialog, only restarts, in about 5 to 10 seconds. A running 115 sync, scan, scrape or reorganisation is interrupted; the confirmation lists them. Playing videos may stall briefly.
-
Cannot reach GitHub: proxy, GitHub accelerator (連不上 GitHub:代理、GitHub 加速): when update checks fail because GitHub is unreachable (the error message points here), fill in one of these and click Save and check for updates (儲存並檢查更新) to try it right away. They work like MoviePilot's network proxy and GitHub accelerator settings:
-
Proxy (
server.update_proxy):http://orsocks5://, for example the local port of Clash or v2rayN,http://127.0.0.1:7890. Both git and the dependency install use it. Installing dependencies through socks5 needs PySocks, so http is recommended. -
GitHub accelerator (
server.update_github_proxy): for examplehttps://ghfast.top/, put in front of the GitHub URL when downloading. Accelerators come and go; switch to another one if it stops working. - They only apply to update checks and updates; playback, 115 and MoviePilot do not use them. Dependency installs still use the pip mirror recorded by the installer (
--mirror).
-
Proxy (
The web update only replaces the program and its dependencies. What the installer manages (the systemd or launchd service definition, ffprobe, the Python version) still needs mi302 update in a terminal. In these cases Version and updates explains why and you need mi302 update:
- Installed from a ZIP download (the program folder is not a git checkout).
-
gitis not installed on the machine. - The account Mi302 runs as may not modify the program folder or
.venv(for example--usernames another account while the program folder belongs to root).
Restarting means Mi302 stops and starts itself again with the same command and the same process ID, so it works under systemd, launchd, and the background mode used without systemd. If it is not back after three minutes, the page tells you to check mi302 status and mi302 logs on the server.
mi302 uninstallAfter you confirm, it stops Mi302 and removes start at boot (the systemd service, the launchd job or the background process) and the mi302 command. The program, settings and data stay, so running the installer again brings everything back.
To remove everything, delete the install folder as well. This deletes settings, database, backups and logs; back up first if you may want them later:
sudo rm -rf /opt/mi302 # macOS: rm -rf ~/Mi302The .strm files and scraped metadata in your media folders are not inside the install folder and are not deleted.
Installed manually: stop Mi302. If you set up systemd, run sudo systemctl disable --now mi302 and delete /etc/systemd/system/mi302.service. Then delete the Mi302 folder.
To watch away from home, put a reverse proxy in front of Mi302 and set the public address; see Playback.
For devices that cannot connect, port conflicts, permissions, network problems in mainland China, forgotten passwords and more, see Logs and FAQ.
Mi302(覺得好用請點個 ⭐ Star/Star it if you like it)· 授權 License:PolyForm Noncommercial 1.0.0,不能商用/no commercial use · 這些頁面的原始檔在倉庫的 docs/wiki · 这些页面的源文件在仓库的 docs/wiki · Source files live in docs/wiki in the repository
繁體中文
简体中文
English