MediumI Made Plex Forget Where I Stopped — On Purpose | by Atomik Factory | Oct, 2026 | Medium
Sitemap

I Made Plex Forget Where I Stopped — On Purpose

10 min readOct 7, 2026

--

Plex is great at remembering where you stopped. For music videos and personal footage, I wanted the exact opposite.

Plex is usually very good at remembering where you stopped.

Watch half a movie tonight.

Come back tomorrow.

Press play.

Plex takes you right back to the same spot.

Perfect.

Except sometimes that is exactly what I don’t want.

I have a Plex library containing things like music videos and personal footage.

If I stop a concert clip seven minutes in, I don’t necessarily want to come back three days later and land in the middle of the guitar solo.

I want:

Play → start from the beginning.

Every time.

So I wrote a tiny Python script that resets the playback status of one Plex library automatically every night.

It runs directly on my Synology NAS, right next to Plex.

No complicated service.

No Docker container.

No database.

Just one Python file, one dependency, and a scheduled task.

Plex Is Doing the Right Thing

This is important.

I’m not trying to “fix” Plex because Plex is broken.

Its resume behavior makes perfect sense for:

  • movies
  • TV shows
  • documentaries
  • long-form videos

If I pause a two-hour movie at 1:14:32, I absolutely want Plex to remember that.

The problem is that not every video library behaves like a movie library.

For things like:

  • music videos
  • concert clips
  • family footage
  • short personal videos
  • looping visual content

the resume point can become annoying.

I don’t want to remember that I watched 37% of a three-minute music video six weeks ago.

I just want it to start again.

The Script Is Only 36 Lines

The script lives in my Atomik Scripts repository:

plex-reset-videos.py

It uses the Python PlexAPI library to connect to the Plex server, open one specific library, and inspect every item inside it.

The logic is deliberately simple.

For each video, it asks:

Does this video have a playback offset?

or:

Has this video already been marked as watched?

If either answer is yes, the script marks the item as unwatched.

The current code checks Plex’s viewOffset and viewCount values, then calls markUnwatched() when needed. PlexAPI itself supports connecting directly to a Plex server using a base URL and authentication token.

Conceptually:

Open Plex library
↓
Check every video
↓
Partially played?
│
├── yes ──► mark unwatched
│
Already watched?
│
├── yes ──► mark unwatched
│
▼
Continue

At the end, the script prints how many items it reset.

That’s really the whole thing.

Why I Target One Library Only

This script is intentionally blunt.

That means I do not want it running against my entire Plex server.

It resets playback status.

That includes videos that were only partially watched and videos that were fully watched.

So if I pointed it at my movie library, I would lose useful watch-state information.

That would be terrible.

Instead, the script targets one library by exact name.

For example:

LIBRARY_NAME = "Clip and Live"

That library is the one I specifically want to behave this way.

Everything else stays untouched.

This is the most important rule in the whole setup:

Do not point this at your Movies or TV Shows library unless you genuinely want those watch states reset.

There Are Only Three Settings

The script needs three pieces of configuration.

1. Your Plex server address

Something like:

PLEX_BASE_URL = "http://192.168.1.50:32400"

Plex uses port 32400 by default, and PlexAPI connects using the server base URL plus an authentication token.

Since my script runs on the same NAS as Plex, I can also use:

PLEX_BASE_URL = "http://127.0.0.1:32400"

That has one nice advantage:

if the NAS gets a different LAN IP later, the script doesn’t care.

It is talking to Plex locally.

2. The exact library name

For example:

LIBRARY_NAME = "Clip and Live"

Exact means exact.

If I type the wrong name, the script stops and tells me it could not find the library.

That is much better than silently targeting something unexpected.

3. Your Plex authentication token

The script also needs a Plex token.

That token gives it permission to communicate with the server.

Which means:

treat it like a password.

The current script stores the token directly in the configuration section, so file permissions matter.

The PlexAPI documentation explicitly recommends locking down token-containing configuration files and even suggests environment variables as a safer alternative to hardcoding sensitive values.

For my small local setup, I keep the script in a restricted directory on the NAS.

Getting the Plex Token

One straightforward way to retrieve the token is through Plex Web.

Open Plex in the browser.

Pick a media item.

Open the three-dot menu.

Choose:

Get Info

Then:

View XML

That opens the XML representation in a browser tab.

In the URL, you should see something like:

X-Plex-Token=xxxxxxxxxxxxxxxx

That long value is the token.

Copy it into the script.

And again:

don’t publish it, commit it to GitHub, or leave the script world-readable.

Anyone with that token may be able to authenticate against your Plex server depending on its access and configuration.

Why I Run the Script on the NAS

I could run this script from another computer.

But that would create a new dependency.

My desktop would need to be turned on.

The network path would matter.

The scheduler would live somewhere else.

Instead, Plex and the Python script live on the same Synology NAS.

That makes the workflow self-contained:

Synology NAS
├── Plex Media Server
├── Python
└── nightly reset script

The NAS is already running.

The script talks to Plex locally.

And Synology DSM already includes a Task Scheduler capable of running user-defined scripts on a schedule.

No extra server is necessary.

I Use a Python Virtual Environment

I also don’t like installing random Python packages directly into a system Python environment if I can avoid it.

So I create a virtual environment specifically for the script.

Inside the script directory:

python3 -m venv .venv

Then activate it:

source .venv/bin/activate

And install PlexAPI:

pip install plexapi

That keeps the dependency isolated.

The PlexAPI project itself documents installation with:

pip install plexapi

and provides Python bindings for browsing and controlling Plex libraries.

Test It Manually First

Before scheduling anything, I run the script manually.

Something like:

python plex-reset-videos.py

Then I watch the terminal output.

If it finds videos that have been watched or partially watched, I should see titles being reset.

At the end:

Done. Reset 17 items to unwatched.

At that point I know:

  • the Plex URL works
  • the token works
  • the library name is correct
  • PlexAPI is installed
  • the script has permission to do its job

Only after that do I automate it.

Then I Turn SSH Back Off

I only need SSH during setup.

Once the script, virtual environment, and dependency are in place, the scheduled job can run locally on the NAS without an interactive SSH session.

So after testing, I disable SSH again.

I don’t like leaving services enabled when I’m not using them.

Especially on a device storing personal data.

The Final Step Is Synology Task Scheduler

DSM already provides the automation piece.

Go to:

Control Panel → Task Scheduler

Create a new:

Scheduled Task → User-defined script

Synology officially supports user-defined scheduled scripts from DSM’s Task Scheduler.

Get Atomik Factory’s stories in your inbox

Join Medium for free to get updates from this writer.

Give the task a useful name, for example:

Reset Plex Clip Library

Then choose how often it should run.

I use:

once per day at 4:00 AM.

There is nothing special about 4 AM.

I just know I’m unlikely to be using that library then.

Press enter or click to view image in full size

Use the Virtual Environment Python Directly

You do not need to activate the virtual environment inside the scheduled task.

Instead, call its Python executable directly.

Something like:

/volume1/scripts/plex-reset/.venv/bin/python \
/volume1/scripts/plex-reset/plex-reset-videos.py

That ensures the scheduled task uses the Python environment where plexapi is installed.

No shell activation logic required.

No guessing which Python DSM happens to invoke.

I Run It as an Admin User, Not Root

The script does one thing:

talk to Plex.

It does not need unrestricted control over the NAS.

So I don’t run the scheduled task as root.

I run it using an account with access to the script directory and whatever permissions are needed to execute the job.

The general principle is simple:

give automation the permissions it actually needs, not the maximum permissions available.

Especially when the script contains an authentication token.

Failure Emails Make This Almost Maintenance-Free

Synology Task Scheduler can notify you when scheduled jobs fail.

I enable failure notifications.

Then the normal experience is:

nothing happens.

Which is exactly what I want.

The script runs overnight.

Plex gets cleaned up.

And I forget the automation exists.

If something breaks, I get an email.

That’s my favorite kind of home-server automation.

It Is Not Instant

There is an important limitation.

The script does not monitor Plex continuously.

It runs on a schedule.

So suppose I watch half of a music video at 9 PM.

Then I come back at 10 PM.

The nightly task hasn’t run yet.

Plex will still resume from the middle.

After the scheduled reset runs overnight, the next playback will start from the beginning.

For my use case, that’s perfectly fine.

I wanted:

reset by tomorrow

not:

reset immediately after playback.

Keeping the logic simple was more valuable to me than building a constantly running watcher.

It Also Clears the Watched Checkmark

This is the biggest limitation.

The script does not distinguish between:

I stopped halfway through.

and:

I watched the entire thing.

Both states get reset.

That means the watched checkmark disappears too.

Again, for my music videos and personal clips, that’s exactly what I want.

But this is why I keep repeating:

do not run this against a library where watched history matters.

The script is deliberately opinionated.

It assumes:

Everything in this library should behave like something I might replay from the beginning.

Your Token Is Stored in Plain Text

The current version keeps configuration directly inside the Python file.

That includes the Plex token.

So if somebody can read that file, they can read the token.

For a small home setup, the simplest mitigation is to restrict access to the directory containing the script.

A more advanced version could move the token to:

  • an environment variable
  • a secrets file
  • DSM credential storage
  • another protected configuration mechanism

The PlexAPI documentation itself recommends restricting permissions on token-containing configuration and suggests local environment variables as an alternative.

This script is intentionally tiny.

Tiny doesn’t mean security considerations disappear.

DSM Updates Can Break the Virtual Environment

There’s one more slightly annoying reality.

The Python environment belongs to the NAS.

A major DSM update can change system Python components or paths.

If that happens, the virtual environment may stop working correctly.

That’s another reason I like failure notifications.

If the scheduled task suddenly fails after an update, rebuilding the virtual environment is usually a reasonable first thing to try:

rm -rf .venv
python3 -m venv .venv
source .venv/bin/activate
pip install plexapi

Then test the script again.

Not elegant.

But also not something I expect to do regularly.

Is All This Worth It for 36 Lines of Python?

For me?

Absolutely.

Because the alternative was a small annoyance that happened constantly.

I would open a music video.

Plex would drop me somewhere in the middle.

I’d manually restart it.

Again.

And again.

And again.

The script took a few minutes to set up.

Now the problem disappears automatically every night.

That is exactly the type of automation I like:

small problem + small script + permanent fix.

Not Every Automation Needs AI

I spend a lot of time experimenting with AI and automation.

But this is a good example of something I think is important:

don’t use AI when a 36-line Python script solves the problem.

There is nothing intelligent happening here.

No model.

No agent.

No machine learning.

Just:

if watched or partially watched:
reset it

And honestly, that’s better.

It is predictable.

Cheap.

Fast.

Easy to understand.

Easy to modify.

And once it works, it stays out of the way.

Sometimes the best automation is the boring one.

The Entire Workflow

The full setup looks like this:

Plex library
↓
Nightly DSM Task Scheduler
↓
plex-reset-videos.py
↓
Python PlexAPI
↓
partially watched or watched?
↓
mark unwatched
↓
next playback starts from the beginning

That’s it.

No service to maintain.

No subscription.

No dashboard.

No cloud dependency beyond whatever Plex itself already uses in your setup.

Just a tiny script solving one weirdly specific annoyance.

Who This Is For

I would use this approach if you have a dedicated Plex library containing things like:

  • music videos
  • concert clips
  • home videos
  • family footage
  • short clips
  • personal archives

where you generally want playback to start from the beginning.

I would not recommend using it for:

  • movies
  • TV shows
  • long documentaries
  • anything where progress tracking matters

unless resetting watched state is genuinely what you want.

The script doesn’t know your intent.

It simply does what you told it to do.

A Ten-Minute Fix That Stays Fixed

That’s really the whole appeal.

I had one very specific annoyance:

Plex kept remembering something I wanted it to forget.

So I automated the forgetting.

Now every night, the NAS resets that one library.

The next time I open a concert clip, I hear the intro.

Not minute seven.

Not the middle of the solo.

The very first note.

And I never have to think about it.

Atomik Factory is where I document the scripts, software, automations, self-hosted tools, and experiments I build for my own everyday workflows — around technology, privacy, productivity, and open source.

Most projects start because something annoys me repeatedly.

If a small script can make that annoyance disappear permanently, I build it.

Then I document it so I can find it again later.

And if somebody else has the same oddly specific problem, hopefully it helps them too.

Build. Learn. Share.

The script is available in my open-source Atomik Scripts repository:

github.com/atomikfactory/atomik-scripts/blob/main/python/plex/plex-reset-videos.py

Copy it, change it, make it yours.

And enjoy the guitar solo from the very first note.

--

--

Atomik Factory
Atomik Factory

Written by Atomik Factory

AI • Tech • Automation • Privacy • Finance • Productivity ⚙️ Build. Learn. Share