Add status query cookie.
This helps prevent fighting when the player takes a long time to report changes in status. It currently fails to play/pause in response to remote commands when latency is sufficiently high, however.
This commit is contained in:
parent
9752aad75d
commit
e9d25a69a0
@ -110,6 +110,8 @@ class SyncplayClient(object):
|
||||
self.autoPlay = False
|
||||
self.autoPlayThreshold = None
|
||||
|
||||
self._lastPlayerCommand = time.time()
|
||||
|
||||
self.autoplayTimer = task.LoopingCall(self.autoplayCountdown)
|
||||
self.autoplayTimeLeft = constants.AUTOPLAY_DELAY
|
||||
|
||||
@ -137,6 +139,16 @@ class SyncplayClient(object):
|
||||
constants.OSD_WARNING_MESSAGE_DURATION = constants.NO_SECONDARY_OSD_WARNING_DURATION
|
||||
self.scheduleAskPlayer()
|
||||
|
||||
def _playerRequest(self, f, *args, **kwargs):
|
||||
"""Send a request with cookie to the player."""
|
||||
kwargs['cookie'] = time.time()
|
||||
f(*args, **kwargs)
|
||||
|
||||
def _playerCommand(self, f, *args, **kwargs):
|
||||
"""Send a command to the player, affecting cookie freshness."""
|
||||
self._lastPlayerCommand = time.time()
|
||||
f(*args, **kwargs)
|
||||
|
||||
def scheduleAskPlayer(self, when=constants.PLAYER_ASK_DELAY):
|
||||
self._askPlayerTimer = task.LoopingCall(self.askPlayer)
|
||||
self._askPlayerTimer.start(when)
|
||||
@ -145,7 +157,7 @@ class SyncplayClient(object):
|
||||
if not self._running:
|
||||
return
|
||||
if self._player:
|
||||
self._player.askForStatus()
|
||||
self._playerRequest(self._player.askForStatus)
|
||||
self.checkIfConnected()
|
||||
|
||||
def checkIfConnected(self):
|
||||
@ -163,14 +175,19 @@ class SyncplayClient(object):
|
||||
seeked = _playerDiff > constants.SEEK_THRESHOLD and _globalDiff > constants.SEEK_THRESHOLD
|
||||
return pauseChange, seeked
|
||||
|
||||
def updatePlayerStatus(self, paused, position):
|
||||
def updatePlayerStatus(self, paused, position, cookie=None):
|
||||
# Ignore status report if the cookie is stale
|
||||
if cookie is not None and \
|
||||
cookie < constants.PLAYER_COMMAND_DELAY + self._lastPlayerCommand:
|
||||
return
|
||||
|
||||
position -= self.getUserOffset()
|
||||
pauseChange, seeked = self._determinePlayerStateChange(paused, position)
|
||||
self._playerPosition = position
|
||||
self._playerPaused = paused
|
||||
if pauseChange and utils.meetsMinVersion(self.serverVersion, constants.USER_READY_MIN_VERSION):
|
||||
if not self.userlist.currentUser.canControl():
|
||||
self._player.setPaused(self._globalPaused)
|
||||
self._playerCommand(self._player.setPaused, self._globalPaused)
|
||||
self.toggleReady(manuallyInitiated=True)
|
||||
self._playerPaused = self._globalPaused
|
||||
pauseChange = False
|
||||
@ -180,7 +197,7 @@ class SyncplayClient(object):
|
||||
self.ui.showMessage(getMessage("set-as-not-ready-notification"))
|
||||
elif not paused and not self.instaplayConditionsMet():
|
||||
paused = True
|
||||
self._player.setPaused(paused)
|
||||
self._playerCommand(self._player.setPaused, paused)
|
||||
self._playerPaused = paused
|
||||
self.changeReadyState(True, manuallyInitiated=True)
|
||||
pauseChange = False
|
||||
@ -213,7 +230,7 @@ class SyncplayClient(object):
|
||||
def _initPlayerState(self, position, paused):
|
||||
if self.userlist.currentUser.file:
|
||||
self.setPosition(position)
|
||||
self._player.setPaused(paused)
|
||||
self._playerCommand(self._player.setPaused, paused)
|
||||
madeChangeOnPlayer = True
|
||||
return madeChangeOnPlayer
|
||||
|
||||
@ -241,7 +258,7 @@ class SyncplayClient(object):
|
||||
|
||||
def _serverUnpaused(self, setBy):
|
||||
hideFromOSD = not constants.SHOW_SAME_ROOM_OSD
|
||||
self._player.setPaused(False)
|
||||
self._playerCommand(self._player.setPaused, False)
|
||||
madeChangeOnPlayer = True
|
||||
self.ui.showMessage(getMessage("unpause-notification").format(setBy), hideFromOSD)
|
||||
return madeChangeOnPlayer
|
||||
@ -250,7 +267,7 @@ class SyncplayClient(object):
|
||||
hideFromOSD = not constants.SHOW_SAME_ROOM_OSD
|
||||
if constants.SYNC_ON_PAUSE and self.getUsername() <> setBy:
|
||||
self.setPosition(self.getGlobalPosition())
|
||||
self._player.setPaused(True)
|
||||
self._playerCommand(self._player.setPaused, True)
|
||||
madeChangeOnPlayer = True
|
||||
if (self.lastLeftTime < time.time() - constants.OSD_DURATION) or (hideFromOSD == True):
|
||||
self.ui.showMessage(getMessage("pause-notification").format(setBy), hideFromOSD)
|
||||
@ -498,13 +515,13 @@ class SyncplayClient(object):
|
||||
if position < 0:
|
||||
position = 0
|
||||
self._protocol.sendState(self.getPlayerPosition(), self.getPlayerPaused(), True, None, True)
|
||||
self._player.setPosition(position)
|
||||
self._playerCommand(self._player.setPosition, position)
|
||||
|
||||
def setPaused(self, paused):
|
||||
if self._player and self.userlist.currentUser.file:
|
||||
if self._lastPlayerUpdate and not paused:
|
||||
self._lastPlayerUpdate = time.time()
|
||||
self._player.setPaused(paused)
|
||||
self._playerCommand(self._player.setPaused, paused)
|
||||
|
||||
def start(self, host, port):
|
||||
if self._running:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user