PlexAutoSkip - Automatically skip content in Plex

Overview

PlexAutoSkip

Automatically skip tagged content in Plex

A background python script that monitors local playback on your server (LAN only) and will automatically 'press' the Skip Intro button or skip other similarly tagged content automatically

Only works on LAN sessions (not remote) as Plex does not allow seeking adjustments via the API for remote sessions

Currently Plex uses markers and chapters to tag potentially skippable content as follows:

  • Markers
    • Intros
    • Commercials
  • Chapters
    • Advertisements

Requirements

  • Python3
  • PIP
  • PlexPass (for automatic markers)
  • PlexAPI
  • Websocket-client

Setup

  1. Ensure you have Python and PIP installed
  2. Clone the repository
  3. Install requirements using pip install -R ./setup/requirements.txt
  4. Run main.py once to generate config files or copy samples from the ./setup directory
  5. Edit ./config/config.ini with your Plex account or Plex server settings
  6. Run main.py

config.ini

custom.json

Optional custom parameters for which movie, show, season, or episode should be included or blocked. You can also define custom skip segments for media if you do not have Plex Pass or would like to skip additional areas of content

Docker

Special Thanks

Comments
  • Repeating last show in series

    Repeating last show in series

    Now that we have it skipping to the next episode before the countdown starts, it seems that this causes it to just repeat the same episode over and over if you're at the last episode in the series (rather than just returning to the main menu).

    I remember seeing this very rarely before (I assume that it was just a timing issue where it happened to check the show time at the exact right time before the player had returned to the main menu), but now it happens every time at the end of the last episode in the series.

    Is there any way to check if there's a next episode via the API before attempting to skip to it?

    opened by cjmanca 48
  • Docker image detects intro marker then errors

    Docker image detects intro marker then errors

    ERROR - Error seeking
    Traceback (most recent call last):
      File "/usr/local/pas/resources/introSkipper.py", line 85, in seekTo
        if self.checkPlayerForMedia(player, mediaWrapper.media):
      File "/usr/local/pas/resources/introSkipper.py", line 102, in checkPlayerForMedia
        return not player.timeline or (player.isPlayingMedia(False) and player.timeline.key == media.key)
      File "/usr/local/pas/venv/lib/python3.6/site-packages/plexapi/client.py", line 584, in timeline
        return next((x for x in self.timelines() if x.state != 'stopped'), None)
      File "/usr/local/pas/venv/lib/python3.6/site-packages/plexapi/client.py", line 576, in timelines
        timelines = self.sendCommand(ClientTimeline.key, wait=wait) or []
      File "/usr/local/pas/venv/lib/python3.6/site-packages/plexapi/client.py", line 231, in sendCommand
        return query(key, headers=headers)
      File "/usr/local/pas/venv/lib/python3.6/site-packages/plexapi/server.py", line 669, in query
        raise BadRequest(message)
    plexapi.exceptions.BadRequest: (500) internal_server_error; IP-REMOVED .plex.direct:32400/player/timeline/poll?commandID=338&wait=0 <?xml version='1.0' encoding='utf-8'?> <Response code="2000" status="FrameworkException: Unable to find player with identifier 1c7136cf62378fe0-com-plexapp-android">   <Traceback>Traceback (most recent call last):   File "C:\Program Files (x86)\Plex\Plex Media Server\Resources\Plug-ins-f11334058\Framework.bundle\Contents\Resources\Versions\2\Python\Framework\components\runtime.py", line 843, in handle_request     result = f(**d)   File "C:\Program Files (x86)\Plex\Plex Media Server\Resources\Plug-ins-f11334058\System.bundle\Contents\Code\playerservice.py", line 50, in process_remote_command     raise FrameworkException('Unable to find player with identifier %s' % identifier) FrameworkException: Unable to find player with identifier 1c7136cf62378fe0-com-plexapp-android </Traceback> </Response> 
    
    

    The player is an Nvidia Shield and the Android TV Plex app. Server is Windows, latest public PMS.

    bug 
    opened by AndiTails 47
  • Custom definition option to mute instead of skip?

    Custom definition option to mute instead of skip?

    I am not that familiar with the Plex API, so my apologies if this is not doable.

    Would it be possible for you to implement an option for custom defined sections of media to mute, rather than skip?

    enhancement 
    opened by mmguero 17
  • Fails to move to next episode on FireTV

    Fails to move to next episode on FireTV

    First - I love the script, and it works great for my windows player, but on my FireTV it's able to skip intros, but when it tries to skip at the end of the episode to the next episode, the player reports:

    "An error occurred while attempting to play this video. Please check your connection and try again."

    When this happens, the script says the following:

    INFO - Seek target is the end of 94 [122646] (Peppa Pig s01e07 - Mommy Pig at Work) TV for Plex for Android (TV) player , going to next
    ERROR - Connection to remote host was lost.
    ERROR - [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
    ERROR - [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
    ERROR - [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
    ERROR - [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
    ERROR - [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
    ERROR - [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
    ERROR - [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
    ERROR - [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
    ERROR - Connection to remote host was lost.
    

    The episodes in question have been played entirely too many times (seriously, make it stop), so I know they'll play normally without the auto skip.

    opened by cjmanca 15
  • fails to skip for roku client

    fails to skip for roku client

    Here is a relevant part of the logs. It finds the intro but is unable to skip.

    INFO - Found an intro marker for media 40 [19134] (It's Always Sunny in Philadelphia s01e06 - The Gang Finds A Dead Guy) Living room with range 64890-88235 and viewOffset 65122
    ERROR - Error seeking
    Traceback (most recent call last):
      File "/usr/local/pas/resources/introSkipper.py", line 140, in checkPlayerForMedia
        return not player.timeline or (player.isPlayingMedia(False) and player.timeline.key == media.key)
      File "/usr/local/pas/venv/lib/python3.6/site-packages/plexapi/client.py", line 584, in timeline
        return next((x for x in self.timelines() if x.state != 'stopped'), None)
      File "/usr/local/pas/venv/lib/python3.6/site-packages/plexapi/client.py", line 576, in timelines
        timelines = self.sendCommand(ClientTimeline.key, wait=wait) or []
      File "/usr/local/pas/venv/lib/python3.6/site-packages/plexapi/client.py", line 231, in sendCommand
        return query(key, headers=headers)
      File "/usr/local/pas/venv/lib/python3.6/site-packages/plexapi/server.py", line 669, in query
        raise BadRequest(message)
    plexapi.exceptions.BadRequest: (500) internal_server_error; https://192-168-2-95.8b9e77ceda2941d3a1bd538fe151daba.plex.direct:32400/player/timeline/poll?commandID=1&wait=0 <?xml version='1.0' encoding='utf-8'?> <Response code="2000" status="FrameworkException: Unable to find player with identifier 41c403359976dbcfb82f6c700be4534b">   <Traceback>Traceback (most recent call last):   File "/usr/lib/plexmediaserver/Resources/Plug-ins-f11334058/Framework.bundle/Contents/Resources/Versions/2/Python/Framework/components/runtime.py", line 843, in handle_request     result = f(**d)   File "/usr/lib/plexmediaserver/Resources/Plug-ins-f11334058/System.bundle/Contents/Code/playerservice.py", line 50, in process_remote_command     raise FrameworkException('Unable to find player with identifier %s' % identifier) FrameworkException: Unable to find player with identifier 41c403359976dbcfb82f6c700be4534b </Traceback> </Response> 
    During handling of the above exception, another exception occurred:
    Traceback (most recent call last):
      File "/usr/local/pas/venv/lib/python3.6/site-packages/urllib3/connection.py", line 175, in _new_conn
        (self._dns_host, self.port), self.timeout, **extra_kw
      File "/usr/local/pas/venv/lib/python3.6/site-packages/urllib3/util/connection.py", line 95, in create_connection
        raise err
      File "/usr/local/pas/venv/lib/python3.6/site-packages/urllib3/util/connection.py", line 85, in create_connection
        sock.connect(sa)
    socket.timeout: timed out
    During handling of the above exception, another exception occurred:
    Traceback (most recent call last):
      File "/usr/local/pas/venv/lib/python3.6/site-packages/urllib3/connectionpool.py", line 710, in urlopen
        chunked=chunked,
      File "/usr/local/pas/venv/lib/python3.6/site-packages/urllib3/connectionpool.py", line 398, in _make_request
        conn.request(method, url, **httplib_request_kw)
      File "/usr/local/pas/venv/lib/python3.6/site-packages/urllib3/connection.py", line 239, in request
        super(HTTPConnection, self).request(method, url, body=body, headers=headers)
      File "/usr/lib/python3.6/http/client.py", line 1285, in request
        self._send_request(method, url, body, headers, encode_chunked)
      File "/usr/lib/python3.6/http/client.py", line 1331, in _send_request
        self.endheaders(body, encode_chunked=encode_chunked)
      File "/usr/lib/python3.6/http/client.py", line 1280, in endheaders
        self._send_output(message_body, encode_chunked=encode_chunked)
      File "/usr/lib/python3.6/http/client.py", line 1046, in _send_output
        self.send(msg)
      File "/usr/lib/python3.6/http/client.py", line 984, in send
        self.connect()
      File "/usr/local/pas/venv/lib/python3.6/site-packages/urllib3/connection.py", line 205, in connect
        conn = self._new_conn()
      File "/usr/local/pas/venv/lib/python3.6/site-packages/urllib3/connection.py", line 182, in _new_conn
        % (self.host, self.timeout),
    urllib3.exceptions.ConnectTimeoutError: (<urllib3.connection.HTTPConnection object at 0x7f4f725283c8>, 'Connection to 192.168.2.118 timed out. (connect timeout=30)')
    During handling of the above exception, another exception occurred:
    Traceback (most recent call last):
      File "/usr/local/pas/venv/lib/python3.6/site-packages/requests/adapters.py", line 450, in send
        timeout=timeout
      File "/usr/local/pas/venv/lib/python3.6/site-packages/urllib3/connectionpool.py", line 786, in urlopen
        method, url, error=e, _pool=self, _stacktrace=sys.exc_info()[2]
      File "/usr/local/pas/venv/lib/python3.6/site-packages/urllib3/util/retry.py", line 592, in increment
        raise MaxRetryError(_pool, url, error or ResponseError(cause))
    urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='192.168.2.118', port=32500): Max retries exceeded with url: /resources (Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x7f4f725283c8>, 'Connection to 192.168.2.118 timed out. (connect timeout=30)'))
    During handling of the above exception, another exception occurred:
    Traceback (most recent call last):
      File "/usr/local/pas/resources/introSkipper.py", line 104, in seekTo
        if self.checkPlayerForMedia(player, mediaWrapper.media):
      File "/usr/local/pas/resources/introSkipper.py", line 149, in checkPlayerForMedia
    
        raise(e)
      File "/usr/local/pas/resources/introSkipper.py", line 144, in checkPlayerForMedia
        player = self.recoverPlayer(player)
      File "/usr/local/pas/resources/introSkipper.py", line 159, in recoverPlayer
        return PlexClient(self.server, baseurl=baseurl, token=self.server._token)
      File "/usr/local/pas/venv/lib/python3.6/site-packages/plexapi/client.py", line 81, in __init__
        self.connect(timeout=timeout)
      File "/usr/local/pas/venv/lib/python3.6/site-packages/plexapi/client.py", line 95, in connect
        data = self.query(self.key, timeout=timeout)
      File "/usr/local/pas/venv/lib/python3.6/site-packages/plexapi/client.py", line 182, in query
        response = method(url, headers=headers, timeout=timeout, **kwargs)
      File "/usr/local/pas/venv/lib/python3.6/site-packages/requests/sessions.py", line 542, in get
        return self.request('GET', url, **kwargs)
      File "/usr/local/pas/venv/lib/python3.6/site-packages/requests/sessions.py", line 529, in request
        resp = self.send(prep, **send_kwargs)
      File "/usr/local/pas/venv/lib/python3.6/site-packages/requests/sessions.py", line 645, in send
        r = adapter.send(request, **kwargs)
      File "/usr/local/pas/venv/lib/python3.6/site-packages/requests/adapters.py", line 507, in send
        raise ConnectTimeout(e, request=request)
    requests.exceptions.ConnectTimeout: HTTPConnectionPool(host='192.168.2.118', port=32500): Max retries exceeded with url: /resources (Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x7f4f725283c8>, 'Connection to 192.168.2.118 timed out. (connect timeout=30)'))
    
    
    bug 
    opened by dnikles 14
  • Plex.tv web not skipping

    Plex.tv web not skipping

    Thanks for a great application.

    When I log in to the web player via my_ip:32400 when on LAN, autoskip works ok. However, if I login via app.plex.tv, I get the debug level errors below. I have tried configs with either plex.tv credentials or 127.0.0.1 with port 32400. My smart TVs have no issues. My SSL settings are set to Preferred.

    I'm on Win11.

    Thanks for your help.

    2022-06-10 14:51:43 - __main__ - INFO - Found new session 15 [2117] (iCarly (2021) s02e04 - iHire a New Assistant) Chrome viewOffset 0 ['mikethebos'], sessions: 2
    2022-06-10 14:51:51 - __main__ - INFO - Found skippable chapter Advertisement for media 15 [2117] (iCarly (2021) s02e04 - iHire a New Assistant) Chrome with range 7818-29584 and viewOffset 8068
    2022-06-10 14:51:51 - __main__ - INFO - Seeking Plex Web player playing 15 [2117] (iCarly (2021) s02e04 - iHire a New Assistant) Chrome from 8069 to 29584
    2022-06-10 14:51:51 - __main__ - ERROR - BadRequest Error, see https://github.com/mdhiggins/PlexAutoSkip/wiki/Troubleshooting#badrequest-error
    2022-06-10 14:51:51 - __main__ - DEBUG - Player Chrome (Plex Web) does not support direct IP connections, nothing to fall back upon, returning None
    2022-06-10 14:51:56 - __main__ - DEBUG - Skipping update session 15 [2117] (iCarly (2021) s02e04 - iHire a New Assistant) Chrome is actively seeking
    ```
    opened by mikethebos 12
  • Request: Custom markers for skipping outro

    Request: Custom markers for skipping outro

    First of all, thanks for the good work. I am using the containerized version and it works perfectly!

    One thing that would greatly improve upon the existing features would be to allow "negative" values for the custom markers. For example, most shows have the same outro sequence so we could essentially add to the custom.json markers for specific shows / seasons to skip to the next episode when there is X amount of milliseconds left.

    enhancement 
    opened by saivajr 9
  • PlexAutoSkip doesn't seem to be able to reach/control my players at all

    PlexAutoSkip doesn't seem to be able to reach/control my players at all

    Hello,

    I've just installed PlexAutoSkip using your docker container but I can't seem to get it to skip anything. I've tried it on both my Apple TV and iPhone and nothing happens.

    Here are the logs:

    2022-09-08 18:58:58 - __main__ - INFO - /usr/local/pas/venv/bin/python3
    2022-09-08 18:58:58 - __main__ - DEBUG - Loading default config file.
    2022-09-08 18:58:58 - __main__ - INFO - Loading config file /usr/local/pas/config/config.ini.
    2022-09-08 18:58:58 - __main__ - INFO - Loading custom JSON file /usr/local/pas/config/custom.json
    2022-09-08 18:58:58 - __main__ - INFO - Connecting to Plex server...
    2022-09-08 18:58:59 - __main__ - INFO - Connected to Plex server PLEX Home using plex.tv account
    2022-09-08 18:58:59 - __main__ - DEBUG - IntroSeeker init with leftOffset 1000 rightOffset 1000
    2022-09-08 18:58:59 - __main__ - DEBUG - Operating in MODE_TYPES.SKIP mode
    2022-09-08 18:58:59 - __main__ - DEBUG - Skip tags ['intro', 'commercial', 'advertisement']
    2022-09-08 18:58:59 - __main__ - DEBUG - Skip S01E01 SKIP_TYPES.WATCHED
    2022-09-08 18:58:59 - __main__ - DEBUG - Skip S**E01 SKIP_TYPES.ALWAYS
    2022-09-08 18:58:59 - __main__ - DEBUG - Skip last chapter 0.0
    2022-09-08 18:58:59 - __main__ - INFO - Skipper initiated and ready
    2022-09-08 18:58:59 - __main__ - DEBUG - Starting listener
    2022-09-08 18:58:59 - websocket - WARNING - websocket connected
    

    As you can see there are no messages indicating that it's finding sessions/detecting intros. GDM is enabled on the server and my Apple TV's Plex app has "Advertise as player" set to on. My Plex server is running in a container too for what it's worth (hotio's image), but both containers are on the same subnet.

    Do you have any idea of what could be the problem?

    Thanks!

    opened by Keagel 8
  • Ability customise skipping for specific shows

    Ability customise skipping for specific shows

    Just wondering if it would be possible to have the ability to customise the skipping for shows?

    For example, parks and rec has a obnoxious intro, but no outro, where as I would like to skip both on futurama.

    Hopefully i’m not asking too much lol

    opened by tom-dell 7
  • Allow setting offset per show

    Allow setting offset per show

    Thanks for this project, it's working great.

    It would be great if it were possible to set the offset per show rather than globally, Plex seems to pick up the intro on one of my shows a little too early

    enhancement 
    opened by KibosJ 7
  • Up next skip restarts last episode if there are no others to play

    Up next skip restarts last episode if there are no others to play

    If there are no episodes left in a series, plex auto skip continues to restart the last few seconds of the last episode. Is there any way to change this behavior?

    opened by joshali1990 6
Owner
Michael Higgins
Michael Higgins
A Python Client to View F1TV Content the right way

F1Hub is a terminal application running directly on your computer -- no connection to the website needed* *In theory. As of now, the F1TV website is needed for some content

kodos 3 Jun 14, 2022
Widevine MPD Content Downloader & Decryptor

Widevine-DL Encrypted MPD Manifest Content Downloader + Decryptor (not a Widevine Key Extractor!) Requirements ffmpeg, yt-dlp, aria2, widevine-l3-decr

Vank0n (SJJeon) 170 Dec 30, 2022
WILSON Cloud Respwnder is a Web Interaction Logger Sending Out Notifications with the ability to serve custom content in order to appropriately respond to client-issued requests.

WILSON Cloud Respwnder What is this? WILSON Cloud Respwnder is a Web Interaction Logger Sending Out Notifications (WILSON) with the ability to serve c

null 48 Oct 31, 2022
The Bot provide Hadith API and fetch content via api.hadith.sutanlab.id

Bot Hadith-API on Telegram The Bot provide Hadith API and fetch content via api.hadith.sutanlab.id Built With Python Asynchronous HTTP protocol client

xMan 12 Feb 19, 2022
A simple message content sniping Discord bot which you can run yourself! Sniping API pulled from isobot and Arch bot

Discord Snipe Bot This is a bot made with the same message content sniping API from isobot and Arch bot. It's default prefix is -, however you can als

notsniped 5 Aug 11, 2022
A simple telegram bot to save restricted content with custom thumbmail support by Mahesh Chauhan

Save Restricted Content Bot A simple telegram bot to save restricted content with custom thumbmail support by Mahesh Chauhan. Variables API_ID API_HAS

Mahesh Chauhan 532 Jan 2, 2023
Savecontentbot - Telegram Save Content Bot With Same more Features

Save Restricted Content Bot A simple telegram bot to save restricted content wit

Group Dc Bots 3 Jan 26, 2022
Notion4ever - Python tool for export all your content of Notion page using official Notion API

NOTION4EVER Notion4ever is a small python tool that allows you to free your cont

null 50 Dec 30, 2022
A Discord bot that automatically saves SHSH blobs for all of your iOS devices.

AutoTSS AutoTSS is a Discord bot that automatically saves SHSH blobs for all of your iOS devices. Want a CLI automatic blob saver? Check out AutoTSS-c

adam 79 Dec 13, 2022
Automatically searching for vaccine appointments

Vaccine Appointments Automatically searching for vaccine appointments Usage To copy this package, run: git clone https://github.com/TheIronicCurtain/v

null 58 Apr 13, 2021
Retrieve information from DBLP and update BibTex files automatically

Rebib TLDR: This script retrieves information from DBLP to update your BibTex files. python rebib.py --bibfile xxx.bib It first parses the bib entries

Shangtong Zhang 49 Jan 1, 2023
Automatically compile an AWS Service Control Policy that ONLY allows AWS services that are compliant with your preferred compliance frameworks.

aws-allowlister Automatically compile an AWS Service Control Policy that ONLY allows AWS services that are compliant with your preferred compliance fr

Salesforce 189 Dec 8, 2022
Automatically load stolen cookies from ChromePass

AutoCookie - Automatically loading stolen cookies from ChromePass View Demo · Report Bug · Request Feature Table of Contents About the Project Getting

darkArp 21 Oct 11, 2022
Automatically Edits Videos and Uploads to Tiktok with 1 line of code.

TiktokAutoUploader - Open to code contributions Automatically Edits Videos and Uploads to Tiktok with 1 line of code. Setup pip install -r requirement

Michael Peres 199 Dec 27, 2022
null 471 Dec 24, 2022
Automatically detect changes made to the official Telegram sites.

?? Telegram Web Crawler This project is developed to automatically detect changes made to the official Telegram sites. This is necessary for anticipat

Il'ya 115 Dec 31, 2022
Automatically scrape all of your artifacts in Genshin Impact.

Genshin Artifact Scraper Automatically scrape all of your artifacts in Genshin Impact. Features: Simple recalibration (2 steps). GUI to select OCR reg

null 21 Dec 17, 2022
A telegram bot to forward messages automatically when they arrived.

Telegram Message Forwarder Bot A telegram bot, which can forward messages from channel, group or chat to another channel, group or chat automatically.

Adnan Ahmad 181 Jan 7, 2023