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.autoPlay = False
|
||||||
self.autoPlayThreshold = None
|
self.autoPlayThreshold = None
|
||||||
|
|
||||||
|
self._lastPlayerCommand = time.time()
|
||||||
|
|
||||||
self.autoplayTimer = task.LoopingCall(self.autoplayCountdown)
|
self.autoplayTimer = task.LoopingCall(self.autoplayCountdown)
|
||||||
self.autoplayTimeLeft = constants.AUTOPLAY_DELAY
|
self.autoplayTimeLeft = constants.AUTOPLAY_DELAY
|
||||||
|
|
||||||
@ -137,6 +139,16 @@ class SyncplayClient(object):
|
|||||||
constants.OSD_WARNING_MESSAGE_DURATION = constants.NO_SECONDARY_OSD_WARNING_DURATION
|
constants.OSD_WARNING_MESSAGE_DURATION = constants.NO_SECONDARY_OSD_WARNING_DURATION
|
||||||
self.scheduleAskPlayer()
|
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):
|
def scheduleAskPlayer(self, when=constants.PLAYER_ASK_DELAY):
|
||||||
self._askPlayerTimer = task.LoopingCall(self.askPlayer)
|
self._askPlayerTimer = task.LoopingCall(self.askPlayer)
|
||||||
self._askPlayerTimer.start(when)
|
self._askPlayerTimer.start(when)
|
||||||
@ -145,7 +157,7 @@ class SyncplayClient(object):
|
|||||||
if not self._running:
|
if not self._running:
|
||||||
return
|
return
|
||||||
if self._player:
|
if self._player:
|
||||||
self._player.askForStatus()
|
self._playerRequest(self._player.askForStatus)
|
||||||
self.checkIfConnected()
|
self.checkIfConnected()
|
||||||
|
|
||||||
def checkIfConnected(self):
|
def checkIfConnected(self):
|
||||||
@ -163,14 +175,19 @@ class SyncplayClient(object):
|
|||||||
seeked = _playerDiff > constants.SEEK_THRESHOLD and _globalDiff > constants.SEEK_THRESHOLD
|
seeked = _playerDiff > constants.SEEK_THRESHOLD and _globalDiff > constants.SEEK_THRESHOLD
|
||||||
return pauseChange, seeked
|
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()
|
position -= self.getUserOffset()
|
||||||
pauseChange, seeked = self._determinePlayerStateChange(paused, position)
|
pauseChange, seeked = self._determinePlayerStateChange(paused, position)
|
||||||
self._playerPosition = position
|
self._playerPosition = position
|
||||||
self._playerPaused = paused
|
self._playerPaused = paused
|
||||||
if pauseChange and utils.meetsMinVersion(self.serverVersion, constants.USER_READY_MIN_VERSION):
|
if pauseChange and utils.meetsMinVersion(self.serverVersion, constants.USER_READY_MIN_VERSION):
|
||||||
if not self.userlist.currentUser.canControl():
|
if not self.userlist.currentUser.canControl():
|
||||||
self._player.setPaused(self._globalPaused)
|
self._playerCommand(self._player.setPaused, self._globalPaused)
|
||||||
self.toggleReady(manuallyInitiated=True)
|
self.toggleReady(manuallyInitiated=True)
|
||||||
self._playerPaused = self._globalPaused
|
self._playerPaused = self._globalPaused
|
||||||
pauseChange = False
|
pauseChange = False
|
||||||
@ -180,7 +197,7 @@ class SyncplayClient(object):
|
|||||||
self.ui.showMessage(getMessage("set-as-not-ready-notification"))
|
self.ui.showMessage(getMessage("set-as-not-ready-notification"))
|
||||||
elif not paused and not self.instaplayConditionsMet():
|
elif not paused and not self.instaplayConditionsMet():
|
||||||
paused = True
|
paused = True
|
||||||
self._player.setPaused(paused)
|
self._playerCommand(self._player.setPaused, paused)
|
||||||
self._playerPaused = paused
|
self._playerPaused = paused
|
||||||
self.changeReadyState(True, manuallyInitiated=True)
|
self.changeReadyState(True, manuallyInitiated=True)
|
||||||
pauseChange = False
|
pauseChange = False
|
||||||
@ -213,7 +230,7 @@ class SyncplayClient(object):
|
|||||||
def _initPlayerState(self, position, paused):
|
def _initPlayerState(self, position, paused):
|
||||||
if self.userlist.currentUser.file:
|
if self.userlist.currentUser.file:
|
||||||
self.setPosition(position)
|
self.setPosition(position)
|
||||||
self._player.setPaused(paused)
|
self._playerCommand(self._player.setPaused, paused)
|
||||||
madeChangeOnPlayer = True
|
madeChangeOnPlayer = True
|
||||||
return madeChangeOnPlayer
|
return madeChangeOnPlayer
|
||||||
|
|
||||||
@ -241,7 +258,7 @@ class SyncplayClient(object):
|
|||||||
|
|
||||||
def _serverUnpaused(self, setBy):
|
def _serverUnpaused(self, setBy):
|
||||||
hideFromOSD = not constants.SHOW_SAME_ROOM_OSD
|
hideFromOSD = not constants.SHOW_SAME_ROOM_OSD
|
||||||
self._player.setPaused(False)
|
self._playerCommand(self._player.setPaused, False)
|
||||||
madeChangeOnPlayer = True
|
madeChangeOnPlayer = True
|
||||||
self.ui.showMessage(getMessage("unpause-notification").format(setBy), hideFromOSD)
|
self.ui.showMessage(getMessage("unpause-notification").format(setBy), hideFromOSD)
|
||||||
return madeChangeOnPlayer
|
return madeChangeOnPlayer
|
||||||
@ -250,7 +267,7 @@ class SyncplayClient(object):
|
|||||||
hideFromOSD = not constants.SHOW_SAME_ROOM_OSD
|
hideFromOSD = not constants.SHOW_SAME_ROOM_OSD
|
||||||
if constants.SYNC_ON_PAUSE and self.getUsername() <> setBy:
|
if constants.SYNC_ON_PAUSE and self.getUsername() <> setBy:
|
||||||
self.setPosition(self.getGlobalPosition())
|
self.setPosition(self.getGlobalPosition())
|
||||||
self._player.setPaused(True)
|
self._playerCommand(self._player.setPaused, True)
|
||||||
madeChangeOnPlayer = True
|
madeChangeOnPlayer = True
|
||||||
if (self.lastLeftTime < time.time() - constants.OSD_DURATION) or (hideFromOSD == True):
|
if (self.lastLeftTime < time.time() - constants.OSD_DURATION) or (hideFromOSD == True):
|
||||||
self.ui.showMessage(getMessage("pause-notification").format(setBy), hideFromOSD)
|
self.ui.showMessage(getMessage("pause-notification").format(setBy), hideFromOSD)
|
||||||
@ -498,13 +515,13 @@ class SyncplayClient(object):
|
|||||||
if position < 0:
|
if position < 0:
|
||||||
position = 0
|
position = 0
|
||||||
self._protocol.sendState(self.getPlayerPosition(), self.getPlayerPaused(), True, None, True)
|
self._protocol.sendState(self.getPlayerPosition(), self.getPlayerPaused(), True, None, True)
|
||||||
self._player.setPosition(position)
|
self._playerCommand(self._player.setPosition, position)
|
||||||
|
|
||||||
def setPaused(self, paused):
|
def setPaused(self, paused):
|
||||||
if self._player and self.userlist.currentUser.file:
|
if self._player and self.userlist.currentUser.file:
|
||||||
if self._lastPlayerUpdate and not paused:
|
if self._lastPlayerUpdate and not paused:
|
||||||
self._lastPlayerUpdate = time.time()
|
self._lastPlayerUpdate = time.time()
|
||||||
self._player.setPaused(paused)
|
self._playerCommand(self._player.setPaused, paused)
|
||||||
|
|
||||||
def start(self, host, port):
|
def start(self, host, port):
|
||||||
if self._running:
|
if self._running:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user