pkkid / python-plexapi

Python bindings for the Plex API.
BSD 3-Clause "New" or "Revised" License
1.14k stars 196 forks source link

SeekTo seems to timeout waiting for response #1004

Open 23doors opened 2 years ago

23doors commented 2 years ago

Describe the Bug

Code in snippet works fine to the point where seekTo is called. I see on client (iPhone latest client) that seek was received and properly works. But code hangs and waits indefinitely, then it times out.

This kind of seems like a bug in Plex iOS client, cause API is processed just doesn't respond with anything? Tried with proxy through server enabled/disabled. Same results.

Seems that Plex for Mac and Plex Web in chrome doesn't support advertise as player anymore. So couldn't test it with these.

Code Snippets

p = plex.clients()[0]

    print(p.state)
    print(p.address)
    print(p.isPlayingMedia())
    print(p.fetchItem(p.timeline.key))
    print(p.timeline.time)
    print(p.timeline.duration)

    p.seekTo(5000)


### Expected Behavior

seekTo should immediately return after it's processed.

### Additional Context

_No response_

### Operating System and Version

iOS 15.5

### Plex Media Server Version

1.28.0.5999

### Python Version

3.9.13

### PlexAPI Version

4.12.0
JonnyWong16 commented 2 years ago

I can't reproduce this with Plex HTPC or an Android client. They both seek fine and the code doesn't block. I don't have any iOS devices to test.

DennisFury commented 1 year ago

I have this exact same issue. Using seekTo will always cause a system timeout, even though the players do in fact move to the offset time. The timeout takes 30 seconds, so if I have 3-4 players I'm syncing to the same offset, it would take 2+ minutes to run. I've tried w/ multiple computers / devices running the script, all get the same timeout. All players are Apple TVs.

To overcome this, I created a new function that can be run as a system thread-- then python will run the function and continue with the script and not wait for a system time out response. Now I can sync all my players instantly, but it's a wonky compromise.

e.g.

from threading import Thread

#fill a list of offsets from other logic
offsets = []

#create seek function
def seek(target):
        target.seekTo(offsets[0], mtype='video')

#within some other code...execute seek to on players
try:
    Thread(target=seek, args=(client_player, )).start()

I also suppress console output with sys.stderr = object since I don't care to see the timeout on the CLI