embyToLocalPlayer: Local Playback for Emby, Jellyfin, and Plex
etlp - Emby/Jellyfin 调用外部本地播放器,并回传播放记录。适配 Plex。
At a glance
- What is it?
- embyToLocalPlayer redirects Emby and Jellyfin playback to supported desktop players and can report progress back to the server. It suits users with local media paths who want more control over the player.
- Who is it for?
- embyToLocalPlayer suits Emby, Jellyfin, or Plex users who have locally accessible media and are willing to run a Python service plus a browser userscript. It is a poor fit for users who only require remote browser playback, need confirmed macOS support, or cannot accept progress being sent when the player exits.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 17 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Why embyToLocalPlayer Exists
embyToLocalPlayer addresses the gap between a browser media interface and a desktop player. Its userscript changes the normal playback action in Emby or Jellyfin so the selected media is passed to PotPlayer, mpv, IINA, MPC-HC, MPC-BE, VLC, or another local application. The repository also says that the workflow is adapted for Plex.
The target audience is not limited to users with physically attached drives. The project has a local-mount mode that converts server paths into client paths when the files are available locally or through a mount. It also supports opening a corresponding folder, including through a documented qBittorrent WebUI companion script. A user without local media may still use server-network playback, but the value then comes mainly from the external player interface.
This is not a replacement media server. Emby, Jellyfin, or Plex remains responsible for the library and account interface. etlp changes the playback handoff. That distinction explains both its usefulness and its constraints: the browser script needs to recognize the server page, the local service needs to communicate with it, and the selected player needs to handle the resulting URL or file.
Browser Script, Python Service, and Progress Flow
The visible architecture has two components. A userscript is installed in Tampermonkey or Violentmonkey and modifies the Emby or Jellyfin page. A separate Python program, `embyToLocalPlayer.py`, runs on the viewing machine. The README identifies the successful service message as `serving at 127.0.0.1:58000`.
The userscript menu provides a server enable or disable choice and a switch for reading from disk. With read-disk mode off, the browser hands playback to the local player while retaining the server network link. With read-disk mode on, the local service converts the server path into a local file address using replacement rules in `embyToLocalPlayer_config.ini`. If the server itself is local, the README says no replacement rule is needed.
The optional `dev` setting `path_check = yes` checks whether converted files exist and handles NFC and NFD differences. The README says this produces clearer logs and better compatibility, but it is slower. Progress reporting is tied to player exit. This means that progress is not necessarily recorded immediately after playback begins, and keeping the player open can delay the update.
Installing the Correct etlp Archive
The README presents three archive choices. For Windows users who want the least configuration, the README recommends `etlp-mpv-py-embed-win32.zip`. This package includes mpv and is intended for Windows only. It does not require configuration-file edits, according to the README.
The `etlp-python-embed-win32.zip` package is also Windows-only. Users must edit `embyToLocalPlayer_config.ini` to set the player path and select the player. The cross-platform `embyToLocalPlayer.zip` is intended for Windows, Linux, and macOS. It requires Python to be installed with the add-to-path option selected, followed by the same configuration-file edits.
Install one userscript manager, then install the etlp script from its listed userscript page. The README links Tampermonkey and Violentmonkey and says that developer mode should be enabled for the Tampermonkey instructions shown there. Refresh the Emby page after installing the script. Before downloading a package, choose the embedded Windows build if you want bundled mpv, or the cross-platform build if you already manage Python and player paths yourself.
Windows First Playback Test
After extracting a Windows archive, double-click `embyToLocalPlayer_debug.bat`. If the window shows no error, press `1` and leave it open. The README says this runs the service in a visible debugging window. Then open Emby and click the original play button.
The expected result is that the configured player opens the selected media. If the service has started correctly, its log should contain the following text:
serving at 127.0.0.1:58000If playback still stays in the browser or the batch window gains no new log output, the README directs users to inspect the userscript menu after clicking the browser extension icon. That check helps distinguish a browser-side userscript problem from a player or local-service problem.
For background operation, press `2` in the batch menu. The README says this creates a startup item and runs the service with a hidden window. If the bundled mpv build does not behave as expected, the README recommends testing with the portable package containing mpv. If changing the player in an embedded build, the `mpv_embed` folder must be removed according to the Windows troubleshooting notes.
macOS and Linux Command Startup
The macOS instructions are provided, but the README explicitly states that macOS has not been environment-tested and cannot be offered as supported. On macOS, make the command file executable in the extracted folder:
chmod +x *.commandRun `etlp_run.command` from a terminal, then test playback. For background operation, the README offers a `screen` based option:
brew install screenThe README also documents saving `etlp_run.command` or `etlp_run_via_screen.command` through Automator and adding the resulting application to Login Items. It warns that the direct command-file approach may not work on newer macOS systems. An additional documented command for one Monterey case is:
cd ~/App/embyToLocalPlayer && nohup ./etlp_run.command > run.log 2&>1 &On Linux, the README lists `python3-tk` as an optional dependency:
apt install python3-tkGive `etlp_run.command` execute permission and run it from a terminal. For background startup, the README describes graphical-session autostart and also provides a systemd example. The unit waits for `graphical-session.target` and then starts the command after detecting an X11 or Wayland session.
Local Paths, Players, and Playlists
Local-disk mode depends on path replacement rules. A server library path must correspond to a readable client path, and the replacement must preserve the filename and relevant extensions. The `path_check = yes` option can reveal incorrect mappings, but the README says it is slower. Users troubleshooting this mode should compare the server path, the client path, and the generated logs.
The README says the mpv family generally offers the better experience when there are no special requirements. It also lists specific limitations. MPC-BE playlists may stall when there are more than ten entries. PotPlayer may disable the playlist when it cannot add an HTTP subtitle for the next item. IINA is documented as supporting local-disk playback and progress reporting on macOS, but the project does not claim tested macOS support. VLC, mpv, and PotPlayer have player-specific playlist caveats listed in the FAQ.
Subtitle selection is also split between the two sides of the system. The README says external subtitles and audio tracks selected in Emby work, while embedded subtitles in Emby are ignored and the player handles its own selection. Treating an embedded subtitle as an external subtitle can disable the player's language preference, so users should test the expected subtitle behavior with the selected player.
Updates, License, and Project Activity
The update procedure differs by platform. Windows users press `6` in the `.bat` menu. Linux and macOS users open a terminal in the directory containing the INI file and run:
python3 utils/update.pyThe updater compares old and new configuration fields and writes `embyToLocalPlayer_diff.ini`. The README also warns that the userscript may need updating separately. A browser-based installation therefore has two upgrade surfaces: the local Python files and the Tampermonkey or Violentmonkey script.
The repository is not archived, and its last push was on 2026-10-06. Releases are listed for 2026-07-18, 2025-11.13, and 2025-05-21. The README says small updates may be announced in a feedback channel, while also saying that there may not be many updates. This indicates recorded release activity, not a promise about future compatibility.
The stated license is Apache-2.0. The repository includes a LICENSE file, but the README excerpt does not explain how that license applies to a particular deployment or modification. Anyone planning redistribution should inspect the repository license directly instead of treating this review as legal advice.
Editorial conclusion
embyToLocalPlayer suits Emby, Jellyfin, or Plex users who have locally accessible media and are willing to run a Python service plus a browser userscript. It is a poor fit for users who only require remote browser playback, need confirmed macOS support, or cannot accept progress being sent when the player exits. Before adoption, verify that the selected archive matches the operating system, that the configured player path opens a real file or reachable stream, and that the browser userscript can reach `127.0.0.1:58000`.
Frequently asked questions
Which players can embyToLocalPlayer use?
The README lists mpv, mpv.net, PotPlayer, MPC-HC, MPC-BE, VLC, and IINA. It also says that an unadapted player may work, but it generally will not report playback progress.
How does embyToLocalPlayer report playback progress?
The README states that progress is reported when the player exits. Progress reporting can be disabled, and support depends on the selected player.
What does `serving at 127.0.0.1:58000` mean?
The README identifies this log message as confirmation that the local service started successfully. Users can check it before testing playback from the Emby web interface.
Official sources
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.
[](https://hysenlabs.com/projects/kjtsune-embytolocalplayer)Was this useful?