Plexy
Plexy is a command line tool. It selects the audio and subtitle tracks for your Plex movies and shows, in the language that you want.
plexy preferences --language en --title "The Matrix (1999)" --full-summary original
Configuring watching preferences [####################################] 100%
1 movie changed out of 1 selected movie
The Matrix (1999) changed from pt-BR: Português (SRT External) to no subtitles
Why
Plex does not have one setting for "always play the original audio with subtitles in my language". You must select the audio and subtitle tracks for each movie or show. With a large library, this takes a long time. Plexy does it for all your library, or for the titles that you select, with one command.
How it works
You give a language and a watching preference: original or dubbed.
| Preference | Audio track | Subtitle track |
|---|---|---|
original |
The original audio. | Your language, if the audio is not in your language. |
dubbed |
Your language. | Your language, only if no audio track is in your language. |
Plexy finds the original language in the media file: the language of the default video track, or else of the default audio track. Some files have a default track in a dubbed language. For a better result, give a TMDB key (see Original language from TMDB).
Plexy gives a lower priority to:
- Commentary audio tracks.
- Closed caption (CC) and hearing-impaired (SDH) subtitle tracks.
Install
Plexy needs Python. The supported versions are in pyproject.toml.
With uv (recommended):
uv tool install "plexy[yaml]"
Or with pipx:
pipx install "plexy[yaml]"
The yaml extra is necessary only for a YAML configuration file. A JSON file works without it.
With Docker, see Use Docker.
Quick start
-
Get your Plex token. Follow the Plex article Finding an authentication token.
-
Make a file
plexy.ymlin the current folder, with your server address and your token:url: http://myplexserver:32400 token: ABCDEFGHIJ1234567890
-
Run plexy on one movie first:
plexy preferences --language pt-BR --title "The Matrix (1999)" --full-summary original
-
If the result is correct, run it on all your libraries:
plexy preferences --language pt-BR original
You can also give the server address and the token on the command line:
plexy --url http://myplexserver:32400 --token ABCDEFGHIJ1234567890 preferences --language pt-BR original
Examples
The examples use the configuration file from Quick start.
Select titles
Only Game of Thrones, French subtitles with the original audio:
plexy preferences --language fr --title "Game of Thrones" original
Only The Mandalorian, season 2, German audio:
plexy preferences --language de --title "Mandalorian s02" dubbed
Only Game of Thrones, season 3, episode 9, German audio:
plexy preferences --language de --title "Game of Thrones s03e09" dubbed
All Matrix movies and the first Avatar movie, Spanish audio:
plexy preferences --language es --title "Matrix" --title "Avatar (2009)" dubbed
Select a library
Only the "Movies" library, English audio:
plexy preferences --library Movies --language en dubbed
Select by date added
Titles added in the last week:
plexy preferences --language pt --newer-than 1w original
Titles in the "Movies" library, added before the last week:
plexy preferences --library Movies --language pt-BR --older-than 1w original
Exclude a codec
Some players cannot play all codecs. For example, the Chromecast with Google TV cannot play Dolby TrueHD audio. This command does not select TrueHD audio tracks:
plexy preferences --language pt-BR --excluded-audio-codec truehd original
Configuration file
A configuration file can contain all the options. Put the options of the preferences command under preferences:
url: http://myplexserver:32400
token: ABCDEFGHIJ1234567890
preferences:
library:
- Movies
- TV Shows
excluded_subtitle_codec:
- eia_608
full_summary: True
language: pt-BR
watching_preference: original
With this file, this command is sufficient:
plexy preferences
Plexy reads the configuration files in this order. A later file overrides an earlier file.
-
config.json,config.yaml, orconfig.ymlin the user folder:- macOS:
~/Library/Preferences/plexy - Linux:
~/.config/plexy/ - Windows:
C:\Users\<USER>\AppData\Local\plexy\plexy
- macOS:
-
plexy.json,plexy.yaml, orplexy.ymlin the current folder. -
The file of the
--configoption:plexy --config myconfig.yml preferences
Options on the command line override the configuration files.
Original language from TMDB
With a TMDB key, original gets the original language of each movie and show from
TMDB. Plexy uses the media file when TMDB has no answer, or when no audio
track has the TMDB language.
-
Make a free TMDB account.
-
Open the API settings and request an API key.
-
Copy the API Read Access Token. The API Key also works, but it goes in the request URL.
-
Add it to your configuration file:
tmdb_key: eyJhbGciOiJIUzI1NiJ9...
Plexy sends one request for each movie and each show. It keeps the answers in a cache, so a later run sends requests only for new titles.
Use Docker
The Docker image reads JSON and YAML configuration files. For example, plexy.json:
{
"url": "http://myplexserver:32400",
"token": "ABCDEFGHIJ1234567890"
}
Then run:
docker run --rm -v "$PWD/plexy.json:/plexy.json" ratoaq2/plexy preferences --language pt-BR original
All options
plexy preferences --help
Usage: plexy preferences [OPTIONS] {original|dubbed}
Your watching preferences
Dubbed prefers an audio track with the desired language.
Original prefers the original audio and an additional subtitle track if the audio is not in the desired language.
Options:
-L, --library TEXT Library to be used. e.g: Movies, Shows.
-t, --title TITLE Filter for titles in your library. It could refer to a movie, a
show, a season or an episode. e.g: Avatar, The Matrix (1999),
The Boys s2, Chernobyl s01e03, Game of Thrones (2011) s03e09
-l, --language LANGUAGE Desired watching language as IETF code, e.g.: en, pt-BR.
-a, --audio-codec [dca|aac|opus|ac3|eac3|truehd|flac|mp2|mp3|vorbis|pcm|unknown]
Accepted audio codec.
-A, --excluded-audio-codec [dca|aac|opus|ac3|eac3|truehd|flac|mp2|mp3|vorbis|pcm|unknown]
Excluded audio codec.
-s, --subtitle-codec [srt|pgs|vobsub|ass|mov_text|eia_608|dvb_subtitle|unknown]
Accepted subtitle codec.
-S, --excluded-subtitle-codec [srt|pgs|vobsub|ass|mov_text|eia_608|dvb_subtitle|unknown]
Excluded subtitle codec.
-n, --newer-than AGE Filter movies/episodes newer than AGE, e.g. 12h, 1w2d
-o, --older-than AGE Filter movies/episodes older than AGE, e.g. 12h, 1w2d
-f, --full-summary Print the full summary of changed preferences.
--skip-watching Skip movies/episodes that watch is in progress.
--keep-selected-audio Do not change the selected audio. Useful when using original
watching preference.
--keep-selected-subtitle Do not change the selected subtitle.
--force-subtitles Select subtitles, even when the audio already matches the
desired language.
--debug Print useful information for debugging and for reporting bugs.
--help Show this message and exit.
Report a bug
Open an issue. Add the output of the command with the --debug option.
Before you send the output, make sure that it does not contain your Plex token or your TMDB key.
Contribute
See CONTRIBUTING.md.
License
MIT. See LICENSE.
Release files for plexy 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| plexy-0.2.1.tar.gz | 115.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| plexy-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 133.1 kB
Release files / plexy-0.2.1.tar.gz
| Download URL | plexy-0.2.1.tar.gz |
|---|---|
| Size | 115.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ac3af6f9a3c1cd0f53658b543205a57bcce6944babce8ab5619f79eb964e44b9
|
|
BLAKE2b-256 checksum How to use checksums |
eb2db055baaaa34fe4c70b17e0e39ff767d510b0a4673eca37e415e0540c965c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 26, 2026.
Transparency logRelease files / plexy-0.2.1-py3-none-any.whl
| Download URL | plexy-0.2.1-py3-none-any.whl |
|---|---|
| Size | 17.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
533beb2906b8138f44ae22ec2fb8080eb3d9309257cf3503706376295226611a
|
|
BLAKE2b-256 checksum How to use checksums |
d5e662a631f86eeb46b60eb92b92bdbe6a7a9ff124c5f9755e8c7cb84c7193b8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 26, 2026.
Transparency log