diff --git a/syncplay/constants.py b/syncplay/constants.py
index 98c2743..a506fe7 100644
--- a/syncplay/constants.py
+++ b/syncplay/constants.py
@@ -91,6 +91,7 @@ MPC_RETRY_WAIT_TIME = 0.01
MPC_MAX_RETRIES = 30
MPC_PAUSE_TOGGLE_DELAY = 0.05
MPV_NEWFILE_IGNORE_TIME = 1
+MPV_LOCK_WAIT_TIME = 0.2
VLC_OPEN_MAX_WAIT_TIME = 15
VLC_MIN_PORT = 10000
VLC_MAX_PORT = 55000
diff --git a/syncplay/players/mplayer.py b/syncplay/players/mplayer.py
index efee9fc..03b1ea2 100644
--- a/syncplay/players/mplayer.py
+++ b/syncplay/players/mplayer.py
@@ -25,7 +25,6 @@ class MplayerPlayer(BasePlayer):
self.quitReason = None
self.lastLoadedTime = None
self.fileLoaded = False
- self.lastResetTime = None
try:
self._listener = self.__Listener(self, playerPath, filePath, args)
except ValueError:
@@ -93,8 +92,7 @@ class MplayerPlayer(BasePlayer):
self._listener.sendLine(u'loadfile {}'.format(self._quoteArg(filePath)))
def openFile(self, filePath, resetPosition=False):
- if resetPosition:
- self.lastResetTime = time.time()
+ self._filepath = filePath
self._loadFile(filePath)
self._onFileUpdate()
if self._paused != self._client.getGlobalPaused():
@@ -135,9 +133,6 @@ class MplayerPlayer(BasePlayer):
def _fileIsLoaded(self):
return True
- def _clearFileLoaded(self):
- pass
-
def _handleUnknownLine(self, line):
pass
diff --git a/syncplay/players/mpv.py b/syncplay/players/mpv.py
index fcf36a6..6f8d277 100644
--- a/syncplay/players/mpv.py
+++ b/syncplay/players/mpv.py
@@ -6,130 +6,22 @@ from syncplay import constants
import os, sys, time
class MpvPlayer(MplayerPlayer):
- POSITION_QUERY = 'time-pos'
- OSD_QUERY = 'show_text'
RE_VERSION = re.compile('.*mpv (\d)\.(\d)\.\d.*')
- def _setProperty(self, property_, value):
- self._listener.sendLine("no-osd set {} {}".format(property_, value))
-
- def setPaused(self, value):
- if self._paused <> value:
- self._paused = not self._paused
- self._listener.sendLine('cycle pause')
-
- def _storePosition(self, value):
- if self._recentlyReset():
- self._position = 0
- elif self._fileIsLoaded():
- self._position = value
- else:
- self._position = self._client.getGlobalPosition()
-
- def _storePauseState(self, value):
- if self._fileIsLoaded():
- self._paused = value
- else:
- self._paused = self._client.getGlobalPaused()
-
- def _onFileUpdate(self):
- if not constants.MPV_NEW_VERSION:
- oldFilename = self._filename
- oldLength = self._duration
- oldFilepath = self._filepath
- self._fileUpdateClearEvents()
- self._getFilename()
- self._getLength()
- self._getFilepath()
- self._fileUpdateWaitEvents()
- if (self._filename != oldFilename) or (self._duration != oldLength) or (self._filepath != oldFilepath):
- self._client.updateFile(self._filename, self._duration, self._filepath)
-
- def _clearFileLoaded(self):
- self.fileLoaded = False
- self.lastLoadedTime = None
-
- def _loadFile(self, filePath):
- if constants.MPV_NEW_VERSION:
- self._clearFileLoaded()
- self._listener.sendLine(u'loadfile {}'.format(self._quoteArg(filePath)))
-
- def openFile(self, filePath, resetPosition=False):
- if resetPosition:
- self.lastResetTime = time.time()
- self._loadFile(filePath)
- if self._paused != self._client.getGlobalPaused():
- self.setPaused(self._client.getGlobalPaused())
- self.setPosition(self._client.getGlobalPosition())
-
- def _handleUnknownLine(self, line):
- if "Error parsing option" in line or "Error parsing commandline option" in line:
- self.quitReason = getMessage("mpv-version-error")
-
- elif "Could not open pipe at '/dev/stdin'" in line:
- self.reactor.callFromThread(self._client.ui.showErrorMessage, getMessage("mpv-version-error"), True)
- self.drop()
-
- elif line == "":
- self._clearFileLoaded()
-
- elif line == "":
- self._onMPVFileUpdate()
-
- elif "Failed to get value of property" in line:
- if "filename" in line:
- self._getFilename()
- elif "length" in line:
- self._getLength()
- elif "path" in line:
- self._getFilepath()
- elif "time-pos" in line:
- self.setPosition(self._client.getGlobalPosition())
- self._positionAsk.set()
-
- elif "Playing:" in line:
- if constants.MPV_NEW_VERSION:
- self._clearFileLoaded()
- else:
- self.fileLoaded = True
- if not self._recentlyReset():
- self._onMPVFileUpdate()
- self.reactor.callFromThread(self._onFileUpdate)
-
- def _recentlyReset(self):
- if not self.lastResetTime:
- return False
- elif time.time() < self.lastResetTime + constants.MPV_NEWFILE_IGNORE_TIME:
- return True
- else:
- return False
-
- def _onMPVFileUpdate(self):
- self.fileLoaded = True
- self.lastLoadedTime = time.time()
- self.reactor.callFromThread(self._client.updateFile, self._filename, self._duration, self._filepath)
- if not (self._recentlyReset()):
- self.reactor.callFromThread(self.setPosition, self._client.getGlobalPosition())
- if self._paused != self._client.getGlobalPaused():
- self.reactor.callFromThread(self._client.getGlobalPaused)
-
- def _fileIsLoaded(self):
- if self.fileLoaded == True and self.lastLoadedTime != None and time.time() > (self.lastLoadedTime + constants.MPV_NEWFILE_IGNORE_TIME):
- return True
- else:
- return False
-
@staticmethod
def run(client, playerPath, filePath, args):
- return MpvPlayer(client, MpvPlayer.getExpandedPath(playerPath), filePath, args)
-
- @staticmethod
- def getStartupArgs(path):
try:
- ver = MpvPlayer.RE_VERSION.search(subprocess.check_output([path, '--version']))
+ ver = MpvPlayer.RE_VERSION.search(subprocess.check_output([playerPath, '--version']))
except:
ver = None
constants.MPV_NEW_VERSION = ver is None or int(ver.group(1)) > 0 or int(ver.group(2)) >= 5
+ if constants.MPV_NEW_VERSION:
+ return NewMpvPlayer(client, MpvPlayer.getExpandedPath(playerPath), filePath, args)
+ else:
+ return OldMpvPlayer(client, MpvPlayer.getExpandedPath(playerPath), filePath, args)
+
+ @staticmethod
+ def getStartupArgs(path):
args = constants.MPV_SLAVE_ARGS
if constants.MPV_NEW_VERSION or sys.platform.startswith('win'):
args.extend(constants.MPV_SLAVE_ARGS_NEW)
@@ -173,3 +65,112 @@ class MpvPlayer(MplayerPlayer):
@staticmethod
def getIconPath(path):
return constants.MPV_ICONPATH
+
+class OldMpvPlayer(MpvPlayer):
+ POSITION_QUERY = 'time-pos'
+ OSD_QUERY = 'show_text'
+
+ def _setProperty(self, property_, value):
+ self._listener.sendLine("no-osd set {} {}".format(property_, value))
+
+ def setPaused(self, value):
+ if self._paused <> value:
+ self._paused = not self._paused
+ self._listener.sendLine('cycle pause')
+
+ def mpvVersionErrorCheck(self, line):
+ if "Error parsing option" in line or "Error parsing commandline option" in line:
+ self.quitReason = getMessage("mpv-version-error")
+
+ elif "Could not open pipe at '/dev/stdin'" in line:
+ self.reactor.callFromThread(self._client.ui.showErrorMessage, getMessage("mpv-version-error"), True)
+ self.drop()
+
+ def _handleUnknownLine(self, line):
+ self.mpvVersionErrorCheck(line)
+ if "Playing: " in line:
+ newpath = line[9:]
+ oldpath = self._filepath
+ if newpath != oldpath and oldpath is not None:
+ self.reactor.callFromThread(self._onFileUpdate)
+ if self._paused != self._client.getGlobalPaused():
+ self.setPaused(self._client.getGlobalPaused())
+ self.setPosition(self._client.getGlobalPosition())
+
+class NewMpvPlayer(OldMpvPlayer):
+ lastResetTime = None
+
+ def _storePosition(self, value):
+ if self._recentlyReset():
+ self._position = 0
+ elif self._fileIsLoaded():
+ self._position = value
+ else:
+ self._position = self._client.getGlobalPosition()
+
+ def _storePauseState(self, value):
+ if self._fileIsLoaded():
+ self._paused = value
+ else:
+ self._paused = self._client.getGlobalPaused()
+
+ def askForStatus(self):
+ self._positionAsk.clear()
+ self._pausedAsk.clear()
+ self._getPaused()
+ self._getPosition()
+ self._positionAsk.wait(constants.MPV_LOCK_WAIT_TIME)
+ self._pausedAsk.wait(constants.MPV_LOCK_WAIT_TIME)
+ self._client.updatePlayerStatus(self._paused, self._position)
+
+ def _preparePlayer(self):
+ self.setPaused(True)
+ self.reactor.callLater(0, self._client.initPlayer, self)
+
+ def _clearFileLoaded(self):
+ self.fileLoaded = False
+ self.lastLoadedTime = None
+
+ def _loadFile(self, filePath):
+ self._clearFileLoaded()
+ self._listener.sendLine(u'loadfile {}'.format(self._quoteArg(filePath)))
+
+ def openFile(self, filePath, resetPosition=False):
+ if resetPosition:
+ self.lastResetTime = time.time()
+ self._loadFile(filePath)
+ if self._paused != self._client.getGlobalPaused():
+ self.setPaused(self._client.getGlobalPaused())
+ self.setPosition(self._client.getGlobalPosition())
+
+ def _handleUnknownLine(self, line):
+ self.mpvVersionErrorCheck(line)
+
+ if line == "" or "Playing:" in line:
+ self._clearFileLoaded()
+
+ elif line == "":
+ self._onFileUpdate()
+
+ def _recentlyReset(self):
+ if not self.lastResetTime:
+ return False
+ elif time.time() < self.lastResetTime + constants.MPV_NEWFILE_IGNORE_TIME:
+ return True
+ else:
+ return False
+
+ def _onFileUpdate(self):
+ self.fileLoaded = True
+ self.lastLoadedTime = time.time()
+ self.reactor.callFromThread(self._client.updateFile, self._filename, self._duration, self._filepath)
+ if not (self._recentlyReset()):
+ self.reactor.callFromThread(self.setPosition, self._client.getGlobalPosition())
+ if self._paused != self._client.getGlobalPaused():
+ self.reactor.callFromThread(self._client.getGlobalPaused)
+
+ def _fileIsLoaded(self):
+ if self.fileLoaded == True and self.lastLoadedTime != None and time.time() > (self.lastLoadedTime + constants.MPV_NEWFILE_IGNORE_TIME):
+ return True
+ else:
+ return False
\ No newline at end of file