Use managed version of Python MPV JSONIPC to improve initialisation reliability

This commit is contained in:
et0h 2020-05-12 00:38:29 +01:00
parent 33319401c2
commit 76439a47eb
2 changed files with 38 additions and 40 deletions

View File

@ -235,9 +235,16 @@ USERLIST_GUI_USERNAME_COLUMN = 0
USERLIST_GUI_FILENAME_COLUMN = 3 USERLIST_GUI_FILENAME_COLUMN = 3
MPLAYER_SLAVE_ARGS = ['-slave', '--hr-seek=always', '-nomsgcolor', '-msglevel', 'all=1:global=4:cplayer=4', '-af-add', 'scaletempo'] MPLAYER_SLAVE_ARGS = ['-slave', '--hr-seek=always', '-nomsgcolor', '-msglevel', 'all=1:global=4:cplayer=4', '-af-add', 'scaletempo']
MPV_ARGS = ['--force-window', '--idle', '--hr-seek=always', '--keep-open'] MPV_ARGS = {'force-window': 'yes',
MPV_SLAVE_ARGS = ['--msg-level=all=error,cplayer=info,term-msg=info', '--input-terminal=no'] 'idle': 'yes',
MPV_SLAVE_ARGS_NEW = ['--term-playing-msg=<SyncplayUpdateFile>\nANS_filename=${filename}\nANS_length=${=duration:${=length:0}}\nANS_path=${path}\n</SyncplayUpdateFile>', '--terminal=yes'] 'hr-seek': 'always',
'keep-open': 'yes',
'input-terminal': 'no',
'terminal': 'yes',
'term-playing-msg': '<SyncplayUpdateFile>\nANS_filename=${filename}\nANS_length=${=duration:${=length:0}}\nANS_path=${path}\n</SyncplayUpdateFile>',
}
MPV_NEW_VERSION = False MPV_NEW_VERSION = False
MPV_OSC_VISIBILITY_CHANGE_VERSION = False MPV_OSC_VISIBILITY_CHANGE_VERSION = False
MPV_INPUT_PROMPT_START_CHARACTER = "" MPV_INPUT_PROMPT_START_CHARACTER = ""

View File

@ -6,7 +6,6 @@ import time
import subprocess import subprocess
import threading import threading
import ast import ast
import random
from syncplay import constants from syncplay import constants
from syncplay.messages import getMessage from syncplay.messages import getMessage
@ -54,17 +53,23 @@ class MpvPlayer(BasePlayer):
return MpvPlayer(client, MpvPlayer.getExpandedPath(playerPath), filePath, args) return MpvPlayer(client, MpvPlayer.getExpandedPath(playerPath), filePath, args)
@staticmethod @staticmethod
def getStartupArgs(path, userArgs, socketName=None): def getStartupArgs(userArgs):
args = constants.MPV_ARGS args = constants.MPV_ARGS
args["script"] = findResourcePath("syncplayintf.lua")
if userArgs: if userArgs:
args.extend(userArgs) for argToAdd in userArgs:
args.extend(constants.MPV_SLAVE_ARGS) if argToAdd.startswith('--'):
if constants.MPV_NEW_VERSION: argToAdd = argToAdd[2:]
args.extend(constants.MPV_SLAVE_ARGS_NEW) elif argToAdd.startswith('-'):
args.extend(["--script={}".format(findResourcePath("syncplayintf.lua"))]) argToAdd = argToAdd[1:]
if socketName: if argToAdd.strip() == "":
args.extend((["--input-ipc-server={}".format(socketName)])) continue
print(args) if "=" in argToAdd:
(argName, argValue) = argToAdd.split("=")
else:
argName = argToAdd
argValue = "yes"
args[argName] = argValue
return args return args
@staticmethod @staticmethod
@ -541,14 +546,13 @@ class MpvPlayer(BasePlayer):
class __Listener(threading.Thread): class __Listener(threading.Thread):
def __init__(self, playerController, playerPath, filePath, args): def __init__(self, playerController, playerPath, filePath, args):
self.playerPath = playerPath
self.mpv_arguments = playerController.getStartupArgs(args)
self.mpv_running = True self.mpv_running = True
self.sendQueue = [] self.sendQueue = []
self.readyToSend = True self.readyToSend = True
self.lastSendTime = None self.lastSendTime = None
self.lastNotReadyTime = None self.lastNotReadyTime = None
self.mpvGUID = random.randrange(constants.VLC_MIN_PORT, constants.VLC_MAX_PORT) if (
constants.VLC_MIN_PORT < constants.VLC_MAX_PORT) else constants.VLC_MIN_PORT
self.socketName = "/tmp/syncplay-mpv-socket-{}".format(self.mpvGUID)
self.__playerController = playerController self.__playerController = playerController
if not self.__playerController._client._config["chatOutputEnabled"]: if not self.__playerController._client._config["chatOutputEnabled"]:
self.__playerController.alertOSDSupported = False self.__playerController.alertOSDSupported = False
@ -560,14 +564,8 @@ class MpvPlayer(BasePlayer):
filePath = os.environ['PWD'] + os.path.sep + filePath filePath = os.environ['PWD'] + os.path.sep + filePath
filePath = os.path.realpath(filePath) filePath = os.path.realpath(filePath)
call = [playerPath]
if filePath: if filePath:
if isWindows() and not isASCII(filePath): self.__playerController.delayedFilePath = filePath
self.__playerController.delayedFilePath = filePath
filePath = None
else:
call.extend([filePath])
call.extend(playerController.getStartupArgs(playerPath, args, self.socketName))
# 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
@ -590,15 +588,8 @@ class MpvPlayer(BasePlayer):
if pythonPath is not None: if pythonPath is not None:
env['PATH'] = '/usr/bin:/usr/local/bin' env['PATH'] = '/usr/bin:/usr/local/bin'
env['PYTHONPATH'] = pythonPath env['PYTHONPATH'] = pythonPath
if filePath: self.mpvpipe = MPV(mpv_location=self.playerPath, loglevel="info", log_handler=self.__playerController.mpv_log_handler, **self.mpv_arguments)
self.__process = subprocess.Popen( self.__process = self.mpvpipe
call, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT,
cwd=self.__getCwd(filePath, env), env=env, bufsize=0)
else:
self.__process = subprocess.Popen(
call, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT,
env=env, bufsize=0)
self.mpvpipe = MPV(start_mpv=False, ipc_socket=self.socketName, log_handler=self.__playerController.mpv_log_handler, loglevel="info")
#self.mpvpipe.show_text("HELLO WORLD!", 1000) #self.mpvpipe.show_text("HELLO WORLD!", 1000)
threading.Thread.__init__(self, name="MPV Listener") threading.Thread.__init__(self, name="MPV Listener")
@ -617,13 +608,7 @@ class MpvPlayer(BasePlayer):
return cwd return cwd
def run(self): def run(self):
line = self.__process.stdout.readline() pass
while self.__process.poll() is None:
line = self.__process.stdout.readline()
self.mpvpipe.terminate()
time.sleep(0.5)
self.__playerController.drop()
def sendChat(self, message): def sendChat(self, message):
if message: if message:
@ -713,6 +698,12 @@ class MpvPlayer(BasePlayer):
def actuallySendLine(self, line): def actuallySendLine(self, line):
try: try:
self.__playerController._client.ui.showDebugMessage("player >> {}".format(line)) self.__playerController._client.ui.showDebugMessage("player >> {}".format(line))
self.mpvpipe.command(*line) try:
self.mpvpipe.command(*line)
except Exception as e:
self.__playerController._client.ui.showDebugMessage("CANNOT SEND {} DUE TO {}".format(line, e))
self.mpvpipe.terminate()
self.__playerController._takeLocksDown()
self.__playerController.reactor.callFromThread(self.__playerController._client.stop, False)
except IOError: except IOError:
pass pass