Fixed mplayer/mpv not closing properly

This commit is contained in:
Uriziel 2014-07-01 00:21:08 +02:00
parent f8af9ce927
commit 4c695fc0be
3 changed files with 132 additions and 121 deletions

View File

@ -384,7 +384,7 @@ class SyncplayClient(object):
return return
self._running = True self._running = True
if self._playerClass: if self._playerClass:
self._playerClass.run(self, self._config['playerPath'], self._config['file'], self._config['playerArgs']) reactor.callLater(0.1, self._playerClass.run, self, self._config['playerPath'], self._config['file'], self._config['playerArgs'])
self._playerClass = None self._playerClass = None
self.protocolFactory = SyncClientFactory(self) self.protocolFactory = SyncClientFactory(self)
port = int(port) port = int(port)

View File

@ -1,23 +1,23 @@
#You might want to change these # You might want to change these
DEFAULT_PORT = 8999 DEFAULT_PORT = 8999
OSD_DURATION = 3 OSD_DURATION = 3
OSD_WARNING_MESSAGE_DURATION = 15 OSD_WARNING_MESSAGE_DURATION = 15
MPC_OSD_POSITION = 2 #Right corner, 1 for left MPC_OSD_POSITION = 2 #Right corner, 1 for left
MPLAYER_OSD_LEVEL = 1 MPLAYER_OSD_LEVEL = 1
UI_TIME_FORMAT = "[%X] " UI_TIME_FORMAT = "[%X] "
CONFIG_NAMES = [".syncplay", "syncplay.ini"] #Syncplay searches first to last CONFIG_NAMES = [".syncplay", "syncplay.ini"] #Syncplay searches first to last
DEFAULT_CONFIG_NAME_WINDOWS = "syncplay.ini" DEFAULT_CONFIG_NAME_WINDOWS = "syncplay.ini"
DEFAULT_CONFIG_NAME_LINUX = ".syncplay" DEFAULT_CONFIG_NAME_LINUX = ".syncplay"
RECENT_CLIENT_THRESHOLD = "1.2.8" #This and higher considered 'recent' clients (no warnings) RECENT_CLIENT_THRESHOLD = "1.2.8" #This and higher considered 'recent' clients (no warnings)
WARN_OLD_CLIENTS = True #Use MOTD to inform old clients to upgrade WARN_OLD_CLIENTS = True #Use MOTD to inform old clients to upgrade
SHOW_OSD = True # Sends Syncplay messages to media player OSD SHOW_OSD = True # Sends Syncplay messages to media player OSD
SHOW_OSD_WARNINGS = True # Show warnings if playing different file, alone in room SHOW_OSD_WARNINGS = True # Show warnings if playing different file, alone in room
SHOW_SLOWDOWN_OSD = True # Show notifications of slowing down / reverting on time difference SHOW_SLOWDOWN_OSD = True # Show notifications of slowing down / reverting on time difference
SHOW_SAME_ROOM_OSD = True # Show OSD notifications for events relating to room user is in SHOW_SAME_ROOM_OSD = True # Show OSD notifications for events relating to room user is in
SHOW_DIFFERENT_ROOM_OSD = False # Show OSD notifications for events relating to room user is not in SHOW_DIFFERENT_ROOM_OSD = False # Show OSD notifications for events relating to room user is not in
LIST_RELATIVE_CONFIGS = True # Print list of relative configs loaded LIST_RELATIVE_CONFIGS = True # Print list of relative configs loaded
SHOW_CONTACT_INFO = True # Displays dev contact details below list in GUI SHOW_CONTACT_INFO = True # Displays dev contact details below list in GUI
SHOW_BUTTON_LABELS = True # If disabled, only shows icons for main GUI buttons SHOW_BUTTON_LABELS = True # If disabled, only shows icons for main GUI buttons
SHOW_TOOLTIPS = True SHOW_TOOLTIPS = True
#Changing these might be ok #Changing these might be ok
@ -33,7 +33,7 @@ RECONNECT_RETRIES = 10
SERVER_STATE_INTERVAL = 1 SERVER_STATE_INTERVAL = 1
WARNING_OSD_MESSAGES_LOOP_INTERVAL = 1 WARNING_OSD_MESSAGES_LOOP_INTERVAL = 1
MERGE_PLAYPAUSE_BUTTONS = False MERGE_PLAYPAUSE_BUTTONS = False
SYNC_ON_PAUSE = True # Client seek to global position - subtitles may disappear on some media players SYNC_ON_PAUSE = True # Client seek to global position - subtitles may disappear on some media players
#Usually there's no need to adjust these #Usually there's no need to adjust these
FILENAME_STRIP_REGEX = u"[-~_\.\[\](): ]" FILENAME_STRIP_REGEX = u"[-~_\.\[\](): ]"
COMMANDS_UNDO = ["u", "undo", "revert"] COMMANDS_UNDO = ["u", "undo", "revert"]
@ -45,25 +45,27 @@ MPC_MIN_VER = "1.6.4"
VLC_MIN_VERSION = "2.0.0" VLC_MIN_VERSION = "2.0.0"
VLC_INTERFACE_MIN_VERSION = "0.2.1" VLC_INTERFACE_MIN_VERSION = "0.2.1"
MPC_PATHS = [ MPC_PATHS = [
r"C:\Program Files (x86)\MPC-HC\mpc-hc.exe", r"C:\Program Files (x86)\MPC-HC\mpc-hc.exe",
r"C:\Program Files\MPC-HC\mpc-hc.exe", r"C:\Program Files\MPC-HC\mpc-hc.exe",
r"C:\Program Files\MPC-HC\mpc-hc64.exe", r"C:\Program Files\MPC-HC\mpc-hc64.exe",
r"C:\Program Files\Media Player Classic - Home Cinema\mpc-hc.exe", r"C:\Program Files\Media Player Classic - Home Cinema\mpc-hc.exe",
r"C:\Program Files\Media Player Classic - Home Cinema\mpc-hc64.exe", r"C:\Program Files\Media Player Classic - Home Cinema\mpc-hc64.exe",
r"C:\Program Files (x86)\Media Player Classic - Home Cinema\mpc-hc.exe", r"C:\Program Files (x86)\Media Player Classic - Home Cinema\mpc-hc.exe",
r"C:\Program Files (x86)\K-Lite Codec Pack\Media Player Classic\mpc-hc.exe", r"C:\Program Files (x86)\K-Lite Codec Pack\Media Player Classic\mpc-hc.exe",
r"C:\Program Files\K-Lite Codec Pack\Media Player Classic\mpc-hc.exe", r"C:\Program Files\K-Lite Codec Pack\Media Player Classic\mpc-hc.exe",
r"C:\Program Files (x86)\Combined Community Codec Pack\MPC\mpc-hc.exe", r"C:\Program Files (x86)\Combined Community Codec Pack\MPC\mpc-hc.exe",
r"C:\Program Files\Combined Community Codec Pack\MPC\mpc-hc.exe", r"C:\Program Files\Combined Community Codec Pack\MPC\mpc-hc.exe",
r"C:\Program Files\MPC HomeCinema (x64)\mpc-hc64.exe", r"C:\Program Files\MPC HomeCinema (x64)\mpc-hc64.exe",
] ]
MPLAYER_PATHS = ["mplayer2", "mplayer"] MPLAYER_PATHS = ["mplayer2", "mplayer"]
MPV_PATHS = ["mpv", "/opt/mpv/mpv", r"C:\Program Files\mpv\mpv.exe", r"C:\Program Files\mpv-player\mpv.exe", r"C:\Program Files (x86)\mpv\mpv.exe", r"C:\Program Files (x86)\mpv-player\mpv.exe","/Applications/mpv.app/Contents/MacOS/mpv"] MPV_PATHS = ["mpv", "/opt/mpv/mpv", r"C:\Program Files\mpv\mpv.exe", r"C:\Program Files\mpv-player\mpv.exe",
r"C:\Program Files (x86)\mpv\mpv.exe", r"C:\Program Files (x86)\mpv-player\mpv.exe",
"/Applications/mpv.app/Contents/MacOS/mpv"]
VLC_PATHS = [ VLC_PATHS = [
r"C:\Program Files (x86)\VideoLAN\VLC\vlc.exe", r"C:\Program Files (x86)\VideoLAN\VLC\vlc.exe",
r"C:\Program Files\VideoLAN\VLC\vlc.exe", r"C:\Program Files\VideoLAN\VLC\vlc.exe",
"/Applications/VLC.app/Contents/MacOS/VLC" "/Applications/VLC.app/Contents/MacOS/VLC"
] ]
VLC_ICONPATH = "vlc.png" VLC_ICONPATH = "vlc.png"
MPLAYER_ICONPATH = "mplayer.png" MPLAYER_ICONPATH = "mplayer.png"
@ -84,12 +86,13 @@ VLC_MIN_PORT = 10000
VLC_MAX_PORT = 55000 VLC_MAX_PORT = 55000
#These are not changes you're looking for #These are not changes you're looking for
MPLAYER_SLAVE_ARGS = [ '-slave', '--hr-seek=always', '-nomsgcolor', '-msglevel', 'all=1:global=4:cplayer=4'] MPLAYER_SLAVE_ARGS = ['-slave', '--hr-seek=always', '-nomsgcolor', '-msglevel', 'all=1:global=4:cplayer=4']
# --quiet works with both mpv 0.2 and 0.3 # --quiet works with both mpv 0.2 and 0.3
MPV_SLAVE_ARGS = ['--slave-broken', '--hr-seek=always', '--quiet','--keep-open'] MPV_SLAVE_ARGS = ['--slave-broken', '--hr-seek=always', '--quiet', '--keep-open']
VLC_SLAVE_ARGS = ['--extraintf=luaintf','--lua-intf=syncplay','--no-quiet','--no-input-fast-seek','--play-and-pause'] VLC_SLAVE_ARGS = ['--extraintf=luaintf', '--lua-intf=syncplay', '--no-quiet', '--no-input-fast-seek',
VLC_SLAVE_NONOSX_ARGS = ['--no-one-instance','--no-one-instance-when-started-from-file'] '--play-and-pause']
MPLAYER_ANSWER_REGEX = "^ANS_([a-zA-Z_-]+)=(.+)$" VLC_SLAVE_NONOSX_ARGS = ['--no-one-instance', '--no-one-instance-when-started-from-file']
MPLAYER_ANSWER_REGEX = "^ANS_([a-zA-Z_-]+)=(.+)$|^(Exiting)\.\.\. \((.+)\)$"
VLC_ANSWER_REGEX = r"(?:^(?P<command>[a-zA-Z_]+)(?:\: )?(?P<argument>.*))" VLC_ANSWER_REGEX = r"(?:^(?P<command>[a-zA-Z_]+)(?:\: )?(?P<argument>.*))"
UI_COMMAND_REGEX = r"^(?P<command>[^\ ]+)(?:\ (?P<parameter>.+))?" UI_COMMAND_REGEX = r"^(?P<command>[^\ ]+)(?:\ (?P<parameter>.+))?"
UI_OFFSET_REGEX = r"^(?:o|offset)\ ?(?P<sign>[/+-])?(?P<time>\d{1,4}(?:[^\d\.](?:\d{1,6})){0,2}(?:\.(?:\d{1,3}))?)$" UI_OFFSET_REGEX = r"^(?:o|offset)\ ?(?P<sign>[/+-])?(?P<time>\d{1,4}(?:[^\d\.](?:\d{1,6})){0,2}(?:\.(?:\d{1,3}))?)$"
@ -101,5 +104,5 @@ PRIVACY_SENDHASHED_MODE = "SendHashed"
PRIVACY_DONTSEND_MODE = "DoNotSend" PRIVACY_DONTSEND_MODE = "DoNotSend"
PRIVACY_HIDDENFILENAME = "**Hidden filename**" PRIVACY_HIDDENFILENAME = "**Hidden filename**"
OPTION_AUTO = "Automatic" OPTION_AUTO = "Automatic"
OPTION_ALWAYS= "Always" OPTION_ALWAYS = "Always"
OPTION_NEVER = "Never" OPTION_NEVER = "Never"

View File

@ -19,6 +19,7 @@ class MplayerPlayer(BasePlayer):
self.reactor = reactor self.reactor = reactor
self._client = client self._client = client
self._paused = None self._paused = None
self._position = 0.0
self._duration = None self._duration = None
self._filename = None self._filename = None
self._filepath = None self._filepath = None
@ -27,7 +28,7 @@ class MplayerPlayer(BasePlayer):
except ValueError: except ValueError:
self._client.ui.showMessage(getMessage("en", "mplayer-file-required-notification")) self._client.ui.showMessage(getMessage("en", "mplayer-file-required-notification"))
self._client.ui.showMessage(getMessage("en", "mplayer-file-required-notification/example")) self._client.ui.showMessage(getMessage("en", "mplayer-file-required-notification/example"))
self.reactor.callFromThread(self._client.stop, (True),) self.drop()
return return
self._listener.setDaemon(True) self._listener.setDaemon(True)
self._listener.start() self._listener.start()
@ -60,7 +61,7 @@ class MplayerPlayer(BasePlayer):
self._client.updateFile(self._filename, self._duration, self._filepath) self._client.updateFile(self._filename, self._duration, self._filepath)
def _preparePlayer(self): def _preparePlayer(self):
self.reactor.callFromThread(self._client.initPlayer, (self),) self.reactor.callLater(0, self._client.initPlayer, self)
self._onFileUpdate() self._onFileUpdate()
def askForStatus(self): def askForStatus(self):
@ -124,22 +125,29 @@ class MplayerPlayer(BasePlayer):
match = self.RE_ANSWER.match(line) match = self.RE_ANSWER.match(line)
if not match: if not match:
return return
name, value = match.group(1).lower(), match.group(2)
if(name == self.POSITION_QUERY): name, value =[m for m in match.groups() if m]
name = name.lower()
if name == self.POSITION_QUERY:
self._position = float(value) self._position = float(value)
self._positionAsk.set() self._positionAsk.set()
elif(name == "pause"): elif name == "pause":
self._paused = bool(value == 'yes') self._paused = bool(value == 'yes')
self._pausedAsk.set() self._pausedAsk.set()
elif(name == "length"): elif name == "length":
self._duration = float(value) self._duration = float(value)
self._durationAsk.set() self._durationAsk.set()
elif(name == "path"): elif name == "path":
self._filepath = value self._filepath = value
self._pathAsk.set() self._pathAsk.set()
elif(name == "filename"): elif name == "filename":
self._filename = value.decode('utf-8') self._filename = value.decode('utf-8')
self._filenameAsk.set() self._filenameAsk.set()
elif name == "exiting":
if value != 'Quit':
self.reactor.callFromThread(self._client.ui.showErrorMessage, value, True)
self.drop()
@staticmethod @staticmethod
def run(client, playerPath, filePath, args): def run(client, playerPath, filePath, args):
@ -161,7 +169,7 @@ class MplayerPlayer(BasePlayer):
@staticmethod @staticmethod
def isValidPlayerPath(path): def isValidPlayerPath(path):
if("mplayer" in path and MplayerPlayer.getExpandedPath(path)): if "mplayer" in path and MplayerPlayer.getExpandedPath(path):
return True return True
return False return False
@ -184,7 +192,7 @@ class MplayerPlayer(BasePlayer):
def notMplayer2(self): def notMplayer2(self):
print getMessage("en", "mplayer2-required") print getMessage("en", "mplayer2-required")
self._listener.sendLine('quit') self._listener.sendLine('quit')
self.reactor.callFromThread(self._client.stop, (True),) self.drop()
def _takeLocksDown(self): def _takeLocksDown(self):
self._durationAsk.set() self._durationAsk.set()
@ -196,12 +204,12 @@ class MplayerPlayer(BasePlayer):
def drop(self): def drop(self):
self._listener.sendLine('quit') self._listener.sendLine('quit')
self._takeLocksDown() self._takeLocksDown()
self.reactor.callFromThread(self._client.stop, (False),) self.reactor.callFromThread(self._client.stop, True)
class __Listener(threading.Thread): class __Listener(threading.Thread):
def __init__(self, playerController, playerPath, filePath, args): def __init__(self, playerController, playerPath, filePath, args):
self.__playerController = playerController self.__playerController = playerController
if(not filePath): if not filePath:
raise ValueError() raise ValueError()
if '://' not in filePath: if '://' not in filePath:
if not os.path.isfile(filePath) and 'PWD' in os.environ: if not os.path.isfile(filePath) and 'PWD' in os.environ:
@ -210,7 +218,7 @@ class MplayerPlayer(BasePlayer):
call = [playerPath, filePath] call = [playerPath, filePath]
call.extend(playerController.SLAVE_ARGS) call.extend(playerController.SLAVE_ARGS)
if(args): if args:
call.extend(args) call.extend(args)
# At least mpv may output escape sequences which result in syncplay # At least mpv may output escape sequences which result in syncplay
# trying to parse something like # trying to parse something like
@ -236,12 +244,12 @@ class MplayerPlayer(BasePlayer):
def run(self): def run(self):
line = self.__process.stdout.readline() line = self.__process.stdout.readline()
if("MPlayer 1" in line): if "MPlayer 1" in line:
self.__playerController.notMplayer2() self.__playerController.notMplayer2()
else: else:
line = line.rstrip("\r\n") line = line.rstrip("\r\n")
self.__playerController.lineReceived(line) self.__playerController.lineReceived(line)
while(self.__process.poll() is None): while self.__process.poll() is None:
line = self.__process.stdout.readline() line = self.__process.stdout.readline()
line = line.rstrip("\r\n") line = line.rstrip("\r\n")
self.__playerController.lineReceived(line) self.__playerController.lineReceived(line)