fix formattings

This commit is contained in:
Daniel Ahn 2018-07-20 12:12:55 -07:00
parent 759f1e1457
commit f01de206d8
13 changed files with 362 additions and 225 deletions

View File

@ -7,16 +7,18 @@ import os.path
application = defines.get('app', 'dist/Syncplay.app')
appname = os.path.basename(application)
def icon_from_app(app_path):
plist_path = os.path.join(app_path, 'Contents', 'Info.plist')
plist = biplist.readPlist(plist_path)
icon_name = plist['CFBundleIconFile']
icon_root,icon_ext = os.path.splitext(icon_name)
icon_root, icon_ext = os.path.splitext(icon_name)
if not icon_ext:
icon_ext = '.icns'
icon_name = icon_root + icon_ext
return os.path.join(app_path, 'Contents', 'Resources', icon_name)
# Volume format (see hdiutil create -help)
format = defines.get('format', 'UDZO')
@ -27,10 +29,19 @@ compression_level = 9
size = defines.get('size', None)
# Files to include
files = [ application, 'resources/lua/intf/.syncplay.lua', 'resources/.macos_vlc_install.command', 'resources/.macOS_readme.pdf' ]
files = [
application,
'resources/lua/intf/.syncplay.lua',
'resources/.macos_vlc_install.command',
'resources/.macOS_readme.pdf'
]
# Symlinks to create
symlinks = { 'Applications': '/Applications', 'Install for VLC': '.macos_vlc_install.command', 'Read Me': '.macOS_readme.pdf' }
symlinks = {
'Applications': '/Applications',
'Install for VLC': '.macos_vlc_install.command',
'Read Me': '.macOS_readme.pdf'
}
# Volume icon
#
@ -38,12 +49,12 @@ symlinks = { 'Applications': '/Applications', 'Install for VLC': '.macos_vlc_ins
# image, *or* you can define badge_icon, in which case the icon file you specify
# will be used to badge the system's Removable Disk icon
#
#icon = '/path/to/icon.icns'
# icon = '/path/to/icon.icns'
badge_icon = icon_from_app(application)
# Where to put the icons
icon_locations = {
appname: (150, 110),
appname: (150, 110),
'Applications': (450, 110),
'Read Me': (100, 285),
'Install for VLC': (500, 285)
@ -106,7 +117,7 @@ arrange_by = None
grid_offset = (0, 0)
grid_spacing = 20
scroll_position = (0, 0)
label_pos = 'bottom' # or 'right'
label_pos = 'bottom' # or 'right'
text_size = 12
icon_size = 80

View File

@ -1,12 +1,12 @@
#!/usr/bin/env python
#coding:utf8
# coding:utf8
#*** TROUBLESHOOTING ***
#1) If you get the error "ImportError: No module named zope.interface" then add an empty __init__.py file to the PYTHONDIR/Lib/site-packages/zope directory
#2) It is expected that you will have NSIS 3 NSIS from http://nsis.sourceforge.net installed.
import sys, codecs
# *** TROUBLESHOOTING ***
# 1) If you get the error "ImportError: No module named zope.interface" then add an empty __init__.py file to the PYTHONDIR/Lib/site-packages/zope directory
# 2) It is expected that you will have NSIS 3 NSIS from http://nsis.sourceforge.net installed.
import codecs
import sys
# try:
# if (sys.version_info.major != 2) or (sys.version_info.minor < 7):
# raise Exception("You must build Syncplay with Python 2.7!")
@ -14,18 +14,20 @@ import sys, codecs
# import warnings
# warnings.warn("You must build Syncplay with Python 2.7!")
import os
import subprocess
from string import Template
import syncplay
import os
import subprocess
from syncplay.messages import getMissingStrings
missingStrings = getMissingStrings()
if missingStrings is not None and missingStrings is not "":
import warnings
warnings.warn("MISSING/UNUSED STRINGS DETECTED:\n{}".format(missingStrings))
def get_nsis_path():
bin_name = "makensis.exe"
from winreg import HKEY_LOCAL_MACHINE as HKLM
@ -39,9 +41,11 @@ def get_nsis_path():
raise Exception("You must install NSIS 3 or later.")
except WindowsError:
return bin_name
NSIS_COMPILE = get_nsis_path()
OUT_DIR = "dist\Syncplay"
OUT_DIR = r"dist\Syncplay"
SETUP_SCRIPT_PATH = "syncplay_setup.nsi"
NSIS_SCRIPT_TEMPLATE = r"""
!include LogicLib.nsh
@ -241,11 +245,11 @@ NSIS_SCRIPT_TEMPLATE = r"""
Push English
Push $${LANG_POLISH}
Push Polski
Push $${LANG_RUSSIAN}
Push $${LANG_RUSSIAN}
Push Русский
Push $${LANG_GERMAN}
Push Deutsch
Push $${LANG_ITALIAN}
Push $${LANG_ITALIAN}
Push Italiano
Push A ; A means auto count languages
LangDLL::LangDialog "Language Selection" "Please select the language of Syncplay and the installer"
@ -317,25 +321,25 @@ NSIS_SCRIPT_TEMPLATE = r"""
;$${EndIf}
$${If} $$CheckBox_VLC_State == $${BST_CHECKED}
$${NSD_Check} $$CheckBox_VLC
$${NSD_Check} $$CheckBox_VLC
$${EndIf}
Call UpdateVLCCheckbox
$${If} $$CheckBox_StartMenuShortcut_State == $${BST_CHECKED}
$${NSD_Check} $$CheckBox_StartMenuShortcut
$${NSD_Check} $$CheckBox_StartMenuShortcut
$${EndIf}
$${If} $$CheckBox_DesktopShortcut_State == $${BST_CHECKED}
$${NSD_Check} $$CheckBox_DesktopShortcut
$${NSD_Check} $$CheckBox_DesktopShortcut
$${EndIf}
$${If} $$CheckBox_QuickLaunchShortcut_State == $${BST_CHECKED}
$${NSD_Check} $$CheckBox_QuickLaunchShortcut
$${NSD_Check} $$CheckBox_QuickLaunchShortcut
$${EndIf}
$${If} $$CheckBox_AutomaticUpdates_State == $${BST_CHECKED}
$${NSD_Check} $$CheckBox_AutomaticUpdates
$${NSD_Check} $$CheckBox_AutomaticUpdates
$${EndIf}
nsDialogs::Show
@ -608,6 +612,7 @@ NSIS_SCRIPT_TEMPLATE = r"""
SectionEnd
"""
class NSISScript(object):
def create(self):
fileList, totalSize = self.getBuildDirContents(OUT_DIR)
@ -617,12 +622,12 @@ class NSISScript(object):
if os.path.isfile(SETUP_SCRIPT_PATH):
raise RuntimeError("Cannot create setup script, file exists at {}".format(SETUP_SCRIPT_PATH))
contents = Template(NSIS_SCRIPT_TEMPLATE).substitute(
version = syncplay.version,
uninstallFiles = uninstallFiles,
installFiles = installFiles,
totalSize = totalSize,
)
contents = Template(NSIS_SCRIPT_TEMPLATE).substitute(
version=syncplay.version,
uninstallFiles=uninstallFiles,
installFiles=installFiles,
totalSize=totalSize,
)
with codecs.open(SETUP_SCRIPT_PATH, "w", "utf-8-sig") as outfile:
outfile.write(contents)
@ -664,29 +669,37 @@ class NSISScript(object):
delete.append('RMdir "$INSTDIR\\{}"'.format(file_))
return "\n".join(delete)
guiIcons = ['resources/accept.png', 'resources/arrow_undo.png', 'resources/clock_go.png',
'resources/control_pause_blue.png', 'resources/cross.png', 'resources/door_in.png',
'resources/folder_explore.png', 'resources/help.png', 'resources/table_refresh.png',
'resources/timeline_marker.png','resources/control_play_blue.png',
'resources/mpc-hc.png','resources/mpc-hc64.png','resources/mplayer.png',
'resources/mpc-be.png',
'resources/mpv.png','resources/vlc.png', 'resources/house.png', 'resources/film_link.png',
'resources/eye.png', 'resources/comments.png', 'resources/cog_delete.png', 'resources/chevrons_right.png',
'resources/user_key.png', 'resources/lock.png', 'resources/key_go.png', 'resources/page_white_key.png',
'resources/tick.png', 'resources/lock_open.png', 'resources/empty_checkbox.png', 'resources/tick_checkbox.png',
'resources/world_explore.png', 'resources/application_get.png', 'resources/cog.png', 'resources/arrow_switch.png',
'resources/film_go.png', 'resources/world_go.png', 'resources/arrow_refresh.png', 'resources/bullet_right_grey.png',
'resources/user_comment.png',
'resources/error.png',
'resources/film_folder_edit.png',
'resources/film_edit.png',
'resources/folder_film.png',
'resources/shield_edit.png',
'resources/shield_add.png',
'resources/email_go.png',
'resources/world_add.png', 'resources/film_add.png', 'resources/delete.png', 'resources/spinner.mng'
]
resources = ["resources/icon.ico", "resources/syncplay.png", "resources/syncplayintf.lua", "resources/license.rtf", "resources/third-party-notices.rtf"]
guiIcons = [
'resources/accept.png', 'resources/arrow_undo.png', 'resources/clock_go.png',
'resources/control_pause_blue.png', 'resources/cross.png', 'resources/door_in.png',
'resources/folder_explore.png', 'resources/help.png', 'resources/table_refresh.png',
'resources/timeline_marker.png', 'resources/control_play_blue.png',
'resources/mpc-hc.png', 'resources/mpc-hc64.png', 'resources/mplayer.png',
'resources/mpc-be.png',
'resources/mpv.png', 'resources/vlc.png', 'resources/house.png', 'resources/film_link.png',
'resources/eye.png', 'resources/comments.png', 'resources/cog_delete.png', 'resources/chevrons_right.png',
'resources/user_key.png', 'resources/lock.png', 'resources/key_go.png', 'resources/page_white_key.png',
'resources/tick.png', 'resources/lock_open.png', 'resources/empty_checkbox.png', 'resources/tick_checkbox.png',
'resources/world_explore.png', 'resources/application_get.png', 'resources/cog.png', 'resources/arrow_switch.png',
'resources/film_go.png', 'resources/world_go.png', 'resources/arrow_refresh.png', 'resources/bullet_right_grey.png',
'resources/user_comment.png',
'resources/error.png',
'resources/film_folder_edit.png',
'resources/film_edit.png',
'resources/folder_film.png',
'resources/shield_edit.png',
'resources/shield_add.png',
'resources/email_go.png',
'resources/world_add.png', 'resources/film_add.png', 'resources/delete.png', 'resources/spinner.mng'
]
resources = [
"resources/icon.ico",
"resources/syncplay.png",
"resources/syncplayintf.lua",
"resources/license.rtf",
"resources/third-party-notices.rtf"
]
resources.extend(guiIcons)
intf_resources = ["resources/lua/intf/syncplay.lua"]

View File

@ -14,16 +14,21 @@ DATA_FILES = [
('resources', glob('resources/*.png') + glob('resources/*.rtf') + glob('resources/*.lua')),
]
OPTIONS = {
'iconfile':'resources/icon.icns',
'iconfile': 'resources/icon.icns',
'extra_scripts': 'syncplayServer.py',
'includes': {'PySide2.QtCore', 'PySide2.QtUiTools', 'PySide2.QtGui','PySide2.QtWidgets', 'certifi'},
'includes': {'PySide2.QtCore', 'PySide2.QtUiTools', 'PySide2.QtGui', 'PySide2.QtWidgets', 'certifi'},
'excludes': {'PySide', 'PySide.QtCore', 'PySide.QtUiTools', 'PySide.QtGui'},
'qt_plugins': ['platforms/libqcocoa.dylib', 'platforms/libqminimal.dylib','platforms/libqoffscreen.dylib', 'styles/libqmacstyle.dylib'],
'qt_plugins': [
'platforms/libqcocoa.dylib',
'platforms/libqminimal.dylib',
'platforms/libqoffscreen.dylib',
'styles/libqmacstyle.dylib'
],
'plist': {
'CFBundleName':'Syncplay',
'CFBundleShortVersionString':syncplay.version,
'CFBundleIdentifier':'pl.syncplay.Syncplay',
'LSMinimumSystemVersion':'10.11.0',
'CFBundleName': 'Syncplay',
'CFBundleShortVersionString': syncplay.version,
'CFBundleIdentifier': 'pl.syncplay.Syncplay',
'LSMinimumSystemVersion': '10.11.0',
'NSHumanReadableCopyright': '@ 2018 Syncplay All Rights Reserved'
}
}

View File

@ -12,5 +12,6 @@ except ImportError:
from syncplay.players.basePlayer import DummyPlayer
MpcBePlayer = DummyPlayer
def getAvailablePlayers():
return [MPCHCAPIPlayer, MplayerPlayer, MpvPlayer, VlcPlayer, MpcBePlayer]

View File

@ -1,4 +1,6 @@
from syncplay import constants
class BasePlayer(object):
'''
@ -12,7 +14,9 @@ class BasePlayer(object):
'''
Display given message on player's OSD or similar means
'''
def displayMessage(self, message, duration = (constants.OSD_DURATION*1000), secondaryOSD=False, mood=constants.MESSAGE_NEUTRAL):
def displayMessage(
self, message, duration=(constants.OSD_DURATION*1000), secondaryOSD=False, mood=constants.MESSAGE_NEUTRAL
):
raise NotImplementedError()
'''
@ -58,7 +62,6 @@ class BasePlayer(object):
def openFile(self, filePath, resetPosition=False):
raise NotImplementedError()
'''
@return: list of strings
'''
@ -107,6 +110,7 @@ class BasePlayer(object):
def getPlayerPathErrors(playerPath, filePath):
raise NotImplementedError()
class DummyPlayer(BasePlayer):
@staticmethod

View File

@ -1,15 +1,18 @@
#coding:utf8
import os.path
import re
import time
import threading
import _thread
import win32con, win32api, win32gui, ctypes, ctypes.wintypes #@UnresolvedImport @UnusedImport
from functools import wraps
from syncplay.players.basePlayer import BasePlayer
import re
from syncplay.utils import retry
import win32con, win32api, win32gui, ctypes, ctypes.wintypes #@UnresolvedImport @UnusedImport
from syncplay import constants
from syncplay.messages import getMessage
import os.path
from syncplay.players.basePlayer import BasePlayer
from syncplay.utils import retry
class MpcHcApi:
def __init__(self):
@ -30,7 +33,7 @@ class MpcHcApi:
self.__listener.start()
self.__locks.listenerStart.wait()
def waitForFileStateReady(f): #@NoSelf
def waitForFileStateReady(f): #@NoSelf
@wraps(f)
def wrapper(self, *args, **kwds):
if not self.__locks.fileReady.wait(constants.MPC_LOCK_WAIT_TIME):
@ -49,7 +52,7 @@ class MpcHcApi:
self.__listener.SendCommand(self.CMD_OPENFILE, filePath)
def isPaused(self):
return self.playState != self.__MPC_PLAYSTATE.PS_PLAY and self.playState != None
return self.playState != self.__MPC_PLAYSTATE.PS_PLAY and self.playState is not None
def askForVersion(self):
self.__listener.SendCommand(self.CMD_GETVERSION)
@ -99,18 +102,22 @@ class MpcHcApi:
self.__listener.mpcHandle = int(value)
self.__locks.mpcStart.set()
if self.callbacks.onConnected:
_thread.start_new_thread(self.callbacks.onConnected, ())
_thread.start_new_thread(self.callbacks.onConnected, ())
elif cmd == self.CMD_STATE:
self.loadState = int(value)
fileNotReady = self.loadState == self.__MPC_LOADSTATE.MLS_CLOSING or self.loadState == self.__MPC_LOADSTATE.MLS_LOADING or self.loadState == self.__MPC_LOADSTATE.MLS_CLOSED
fileNotReady = (
self.loadState == self.__MPC_LOADSTATE.MLS_CLOSING or
self.loadState == self.__MPC_LOADSTATE.MLS_LOADING or
self.loadState == self.__MPC_LOADSTATE.MLS_CLOSED
)
if fileNotReady:
self.playState = None
self.__locks.fileReady.clear()
else:
self.__locks.fileReady.set()
if self.callbacks.onFileStateChange:
_thread.start_new_thread(self.callbacks.onFileStateChange, (self.loadState,))
_thread.start_new_thread(self.callbacks.onFileStateChange, (self.loadState,))
elif cmd == self.CMD_PLAYMODE:
self.playState = int(value)
@ -125,31 +132,31 @@ class MpcHcApi:
self.filePlaying = value[3].split('\\').pop()
self.fileDuration = float(value[4])
if self.callbacks.onUpdatePath:
_thread.start_new_thread(self.callbacks.onUpdatePath, (self.onUpdatePath,))
_thread.start_new_thread(self.callbacks.onUpdatePath, (self.onUpdatePath,))
if self.callbacks.onUpdateFilename:
_thread.start_new_thread(self.callbacks.onUpdateFilename, (self.filePlaying,))
_thread.start_new_thread(self.callbacks.onUpdateFilename, (self.filePlaying,))
if self.callbacks.onUpdateFileDuration:
_thread.start_new_thread(self.callbacks.onUpdateFileDuration, (self.fileDuration,))
_thread.start_new_thread(self.callbacks.onUpdateFileDuration, (self.fileDuration,))
elif cmd == self.CMD_CURRENTPOSITION:
self.lastFilePosition = float(value)
if self.callbacks.onGetCurrentPosition:
_thread.start_new_thread(self.callbacks.onGetCurrentPosition, (self.lastFilePosition,))
_thread.start_new_thread(self.callbacks.onGetCurrentPosition, (self.lastFilePosition,))
elif cmd == self.CMD_NOTIFYSEEK:
if self.lastFilePosition != float(value): #Notify seek is sometimes sent twice
if self.lastFilePosition != float(value): # Notify seek is sometimes sent twice
self.lastFilePosition = float(value)
if self.callbacks.onSeek:
_thread.start_new_thread(self.callbacks.onSeek, (self.lastFilePosition,))
elif cmd == self.CMD_DISCONNECT:
if self.callbacks.onMpcClosed:
_thread.start_new_thread(self.callbacks.onMpcClosed, (None,))
_thread.start_new_thread(self.callbacks.onMpcClosed, (None,))
elif cmd == self.CMD_VERSION:
if self.callbacks.onVersion:
self.version = value
_thread.start_new_thread(self.callbacks.onVersion, (value,))
self.version = value
_thread.start_new_thread(self.callbacks.onVersion, (value,))
class PlayerNotReadyException(Exception):
pass
@ -198,11 +205,11 @@ class MpcHcApi:
CMD_ADDTOPLAYLIST = 0xA0001000
CMD_CLEARPLAYLIST = 0xA0001001
CMD_STARTPLAYLIST = 0xA0001002
CMD_REMOVEFROMPLAYLIST = 0xA0001003 # TODO
CMD_REMOVEFROMPLAYLIST = 0xA0001003 # TODO
CMD_SETPOSITION = 0xA0002000
CMD_SETAUDIODELAY = 0xA0002001
CMD_SETSUBTITLEDELAY = 0xA0002002
CMD_SETINDEXPLAYLIST = 0xA0002003 # DOESNT WORK
CMD_SETINDEXPLAYLIST = 0xA0002003 # DOESNT WORK
CMD_SETAUDIOTRACK = 0xA0002004
CMD_SETSUBTITLETRACK = 0xA0002005
CMD_GETSUBTITLETRACKS = 0xA0003000
@ -256,7 +263,7 @@ class MpcHcApi:
wc.lpszClassName = 'MPCApiListener'
hinst = wc.hInstance = win32api.GetModuleHandle(None)
classAtom = win32gui.RegisterClass(wc)
self.hwnd = win32gui.CreateWindow (
self.hwnd = win32gui.CreateWindow(
classAtom,
"ListenerGUI",
0,
@ -272,14 +279,13 @@ class MpcHcApi:
self.locks.listenerStart.set()
win32gui.PumpMessages()
def OnCopyData(self, hwnd, msg, wparam, lparam):
pCDS = ctypes.cast(lparam, self.__PCOPYDATASTRUCT)
#print "API:\tin>\t 0x%X\t" % int(pCDS.contents.dwData), ctypes.wstring_at(pCDS.contents.lpData)
# print "API:\tin>\t 0x%X\t" % int(pCDS.contents.dwData), ctypes.wstring_at(pCDS.contents.lpData)
self.__mpcApi.handleCommand(pCDS.contents.dwData, ctypes.wstring_at(pCDS.contents.lpData))
def SendCommand(self, cmd, message=''):
#print "API:\t<out\t 0x%X\t" % int(cmd), message
# print "API:\t<out\t 0x%X\t" % int(cmd), message
if not win32gui.IsWindow(self.mpcHandle):
if self.__mpcApi.callbacks.onMpcClosed:
self.__mpcApi.callbacks.onMpcClosed(None)
@ -304,6 +310,7 @@ class MpcHcApi:
('lpData', ctypes.c_void_p)
]
class MPCHCAPIPlayer(BasePlayer):
speedSupported = False
alertOSDSupported = False
@ -400,7 +407,10 @@ class MPCHCAPIPlayer(BasePlayer):
def openFile(self, filePath, resetPosition=False):
self._mpcApi.openFile(filePath)
def displayMessage(self, message, duration = (constants.OSD_DURATION*1000), OSDType=constants.OSD_NOTIFICATION, mood=constants.MESSAGE_NEUTRAL):
def displayMessage(
self, message,
duration=(constants.OSD_DURATION*1000), OSDType=constants.OSD_NOTIFICATION, mood=constants.MESSAGE_NEUTRAL
):
self._mpcApi.sendOsd(message, constants.MPC_OSD_POSITION, duration)
@retry(MpcHcApi.PlayerNotReadyException, constants.MPC_MAX_RETRIES, constants.MPC_RETRY_WAIT_TIME, 1)
@ -412,6 +422,7 @@ class MPCHCAPIPlayer(BasePlayer):
self._mpcApi.pause()
else:
self._mpcApi.unpause()
def setFeatures(self, featureList):
pass
@ -482,7 +493,10 @@ class MPCHCAPIPlayer(BasePlayer):
@staticmethod
def getIconPath(path):
if MPCHCAPIPlayer.getExpandedPath(path).lower().endswith('mpc-hc64.exe'.lower()) or MPCHCAPIPlayer.getExpandedPath(path).lower().endswith('mpc-hc64_nvo.exe'.lower()):
if (
MPCHCAPIPlayer.getExpandedPath(path).lower().endswith('mpc-hc64.exe'.lower()) or
MPCHCAPIPlayer.getExpandedPath(path).lower().endswith('mpc-hc64_nvo.exe'.lower())
):
return constants.MPC64_ICONPATH
else:
return constants.MPC_ICONPATH
@ -496,7 +510,11 @@ class MPCHCAPIPlayer(BasePlayer):
@staticmethod
def getExpandedPath(path):
if os.path.isfile(path):
if path.lower().endswith('mpc-hc.exe'.lower()) or path.lower().endswith('mpc-hcportable.exe'.lower()) or path.lower().endswith('mpc-hc64.exe'.lower()) or path.lower().endswith('mpc-hc64_nvo.exe'.lower()) or path.lower().endswith('mpc-hc_nvo.exe'.lower()):
if (
path.lower().endswith('mpc-hc.exe'.lower()) or path.lower().endswith('mpc-hcportable.exe'.lower()) or
path.lower().endswith('mpc-hc64.exe'.lower()) or path.lower().endswith('mpc-hc64_nvo.exe'.lower()) or
path.lower().endswith('mpc-hc_nvo.exe'.lower())
):
return path
if os.path.isfile(path + "mpc-hc.exe"):
path += "mpc-hc.exe"
@ -528,4 +546,3 @@ class MPCHCAPIPlayer(BasePlayer):
if os.path.isfile(path + "\\mpc-hc64_nvo.exe"):
path += "\\mpc-hc64_nvo.exe"
return path

View File

@ -1,8 +1,11 @@
from syncplay import constants
import os.path
from syncplay import constants
from syncplay.messages import getMessage
from syncplay.players.mpc import MPCHCAPIPlayer
class MpcBePlayer(MPCHCAPIPlayer):
@staticmethod
def run(client, playerPath, filePath, args):
@ -30,7 +33,11 @@ class MpcBePlayer(MPCHCAPIPlayer):
@staticmethod
def getExpandedPath(path):
if os.path.isfile(path):
if path.lower().endswith('mpc-be.exe'.lower()) or path.lower().endswith('mpc-be64.exe'.lower() or path.lower().endswith('mpc-beportable.exe'.lower())):
if (
path.lower().endswith('mpc-be.exe'.lower()) or
path.lower().endswith('mpc-be64.exe'.lower()) or
path.lower().endswith('mpc-beportable.exe'.lower())
):
return path
if os.path.isfile(path + "mpc-be.exe"):
path += "mpc-be.exe"

View File

@ -1,14 +1,18 @@
# coding:utf8
import subprocess
import os
import re
import subprocess
import sys
import threading
import time
from syncplay.players.basePlayer import BasePlayer
from syncplay import constants, utils
from syncplay.players.basePlayer import BasePlayer
from syncplay.messages import getMessage
import os, sys
from syncplay.utils import isWindows
class MplayerPlayer(BasePlayer):
speedSupported = True
customOpenDialog = False
@ -90,15 +94,20 @@ class MplayerPlayer(BasePlayer):
def _getProperty(self, property_):
self._listener.sendLine("get_property {}".format(property_))
def displayMessage(self, message, duration=(constants.OSD_DURATION * 1000), OSDType=constants.OSD_NOTIFICATION, mood=constants.MESSAGE_NEUTRAL):
def displayMessage(
self, message,
duration=(constants.OSD_DURATION * 1000), OSDType=constants.OSD_NOTIFICATION, mood=constants.MESSAGE_NEUTRAL
):
messageString = self._sanitizeText(message.replace("\\n", "<NEWLINE>")).replace("<NEWLINE>", "\\n")
self._listener.sendLine('{} "{!s}" {} {}'.format(self.OSD_QUERY, messageString, duration, constants.MPLAYER_OSD_LEVEL))
self._listener.sendLine('{} "{!s}" {} {}'.format(
self.OSD_QUERY, messageString, duration, constants.MPLAYER_OSD_LEVEL))
def displayChatMessage(self, username, message):
messageString = "<{}> {}".format(username, message)
messageString = self._sanitizeText(messageString.replace("\\n", "<NEWLINE>")).replace("<NEWLINE>", "\\n")
duration = int(constants.OSD_DURATION * 1000)
self._listener.sendLine('{} "{!s}" {} {}'.format(self.OSD_QUERY, messageString, duration, constants.MPLAYER_OSD_LEVEL))
self._listener.sendLine('{} "{!s}" {} {}'.format(
self.OSD_QUERY, messageString, duration, constants.MPLAYER_OSD_LEVEL))
def setSpeed(self, value):
self._setProperty('speed', "{:.2f}".format(value))
@ -118,7 +127,7 @@ class MplayerPlayer(BasePlayer):
pass
def setPosition(self, value):
self._position = max(value,0)
self._position = max(value, 0)
self._setProperty(self.POSITION_QUERY, "{}".format(value))
time.sleep(0.03)
@ -151,7 +160,7 @@ class MplayerPlayer(BasePlayer):
text = text.replace("\\", "\\\\")
text = text.replace("{", "\\\\{")
text = text.replace("}", "\\\\}")
text = text.replace("<SYNCPLAY_QUOTE>","\\\"")
text = text.replace("<SYNCPLAY_QUOTE>", "\\\"")
return text
def _quoteArg(self, arg):
@ -169,7 +178,7 @@ class MplayerPlayer(BasePlayer):
pass
def _storePosition(self, value):
self._position = max(value,0)
self._position = max(value, 0)
def _storePauseState(self, value):
self._paused = value
@ -179,9 +188,15 @@ class MplayerPlayer(BasePlayer):
self._client.ui.showDebugMessage("player << {}".format(line))
line = line.replace("[cplayer] ", "") # -v workaround
line = line.replace("[term-msg] ", "") # -v workaround
line = line.replace(" cplayer: ","") # --msg-module workaround
line = line.replace(" cplayer: ", "") # --msg-module workaround
line = line.replace(" term-msg: ", "")
if "Failed to get value of property" in line or "=(unavailable)" in line or line == "ANS_filename=" or line == "ANS_length=" or line == "ANS_path=":
if (
"Failed to get value of property" in line or
"=(unavailable)" in line or
line == "ANS_filename=" or
line == "ANS_length=" or
line == "ANS_path="
):
if "filename" in line:
self._getFilename()
elif "length" in line:
@ -194,7 +209,7 @@ class MplayerPlayer(BasePlayer):
self._handleUnknownLine(line)
return
name, value =[m for m in match.groups() if m]
name, value = [m for m in match.groups() if m]
name = name.lower()
if name == self.POSITION_QUERY:
@ -250,7 +265,7 @@ class MplayerPlayer(BasePlayer):
@staticmethod
def isValidPlayerPath(path):
if "mplayer" in path and MplayerPlayer.getExpandedPath(path) and not "mplayerc.exe" in path: # "mplayerc.exe" is Media Player Classic (not Home Cinema):
if "mplayer" in path and MplayerPlayer.getExpandedPath(path) and "mplayerc.exe" not in path: # "mplayerc.exe" is Media Player Classic (not Home Cinema):
return True
return False
@ -301,7 +316,7 @@ class MplayerPlayer(BasePlayer):
if not self.__playerController._client._config["chatOutputEnabled"]:
self.__playerController.alertOSDSupported = False
self.__playerController.chatOSDSupported = False
if self.__playerController.getPlayerPathErrors(playerPath,filePath):
if self.__playerController.getPlayerPathErrors(playerPath, filePath):
raise ValueError()
if filePath and '://' not in filePath:
if not os.path.isfile(filePath) and 'PWD' in os.environ:
@ -324,12 +339,15 @@ class MplayerPlayer(BasePlayer):
if 'TERM' in env:
del env['TERM']
if filePath:
self.__process = subprocess.Popen(call, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=self.__getCwd(filePath, env), env=env, bufsize=0)
self.__process = subprocess.Popen(
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.__process = subprocess.Popen(
call, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT,
env=env, bufsize=0)
threading.Thread.__init__(self, name="MPlayer Listener")
def __getCwd(self, filePath, env):
if not filePath:
return None
@ -365,8 +383,8 @@ class MplayerPlayer(BasePlayer):
if command and command[:1] == "/":
message = message[1:]
else:
self.__playerController.reactor.callFromThread(self.__playerController._client.ui.executeCommand,
command)
self.__playerController.reactor.callFromThread(
self.__playerController._client.ui.executeCommand, command)
return
self.__playerController.reactor.callFromThread(self.__playerController._client.sendChat, message)
@ -377,12 +395,12 @@ class MplayerPlayer(BasePlayer):
def setReadyToSend(self, newReadyState):
oldState = self.readyToSend
self.readyToSend = newReadyState
self.lastNotReadyTime = time.time() if newReadyState == False else None
if self.readyToSend == True:
self.lastNotReadyTime = time.time() if not newReadyState else None
if self.readyToSend:
self.__playerController._client.ui.showDebugMessage("<mpv> Ready to send: True")
else:
self.__playerController._client.ui.showDebugMessage("<mpv> Ready to send: False")
if self.readyToSend == True and oldState == False:
if self.readyToSend and not oldState:
self.processSendQueue()
def checkForReadinessOverride(self):
@ -391,7 +409,7 @@ class MplayerPlayer(BasePlayer):
def sendLine(self, line, notReadyAfterThis=None):
self.checkForReadinessOverride()
if self.readyToSend == False and "print_text ANS_pause" in line:
if not self.readyToSend and "print_text ANS_pause" in line:
self.__playerController._client.ui.showDebugMessage("<mpv> Not ready to get status update, so skipping")
return
try:
@ -401,11 +419,13 @@ class MplayerPlayer(BasePlayer):
if line.startswith(command):
for itemID, deletionCandidate in enumerate(self.sendQueue):
if deletionCandidate.startswith(command):
self.__playerController._client.ui.showDebugMessage("<mpv> Remove duplicate (supersede): {}".format(self.sendQueue[itemID]))
self.__playerController._client.ui.showDebugMessage(
"<mpv> Remove duplicate (supersede): {}".format(self.sendQueue[itemID]))
try:
self.sendQueue.remove(self.sendQueue[itemID])
except UnicodeWarning:
self.__playerController._client.ui.showDebugMessage("<mpv> Unicode mismatch occured when trying to remove duplicate")
self.__playerController._client.ui.showDebugMessage(
"<mpv> Unicode mismatch occured when trying to remove duplicate")
# TODO: Prevent this from being triggered
pass
break
@ -415,7 +435,8 @@ class MplayerPlayer(BasePlayer):
if line == command:
for itemID, deletionCandidate in enumerate(self.sendQueue):
if deletionCandidate == command:
self.__playerController._client.ui.showDebugMessage("<mpv> Remove duplicate (delete both): {}".format(self.sendQueue[itemID]))
self.__playerController._client.ui.showDebugMessage(
"<mpv> Remove duplicate (delete both): {}".format(self.sendQueue[itemID]))
self.__playerController._client.ui.showDebugMessage(self.sendQueue[itemID])
return
except:
@ -428,7 +449,9 @@ class MplayerPlayer(BasePlayer):
def processSendQueue(self):
while self.sendQueue and self.readyToSend:
if self.lastSendTime and time.time() - self.lastSendTime < constants.MPV_SENDMESSAGE_COOLDOWN_TIME:
self.__playerController._client.ui.showDebugMessage("<mpv> Throttling message send, so sleeping for {}".format(constants.MPV_SENDMESSAGE_COOLDOWN_TIME))
self.__playerController._client.ui.showDebugMessage(
"<mpv> Throttling message send, so sleeping for {}".format(
constants.MPV_SENDMESSAGE_COOLDOWN_TIME))
time.sleep(constants.MPV_SENDMESSAGE_COOLDOWN_TIME)
try:
lineToSend = self.sendQueue.pop()
@ -440,8 +463,8 @@ class MplayerPlayer(BasePlayer):
def actuallySendLine(self, line):
try:
#if not isinstance(line, str):
#line = line.decode('utf8')
# if not isinstance(line, str):
# line = line.decode('utf8')
line = line + "\n"
self.__playerController._client.ui.showDebugMessage("player >> {}".format(line))
line = line.encode('utf-8')

View File

@ -1,16 +1,20 @@
# coding:utf8
# coding:utf8x
import os
import re
import sys
import time
import subprocess
from syncplay import constants
from syncplay.players.mplayer import MplayerPlayer
from syncplay.messages import getMessage
from syncplay import constants
from syncplay.utils import isURL, findResourcePath
import os, sys, time
class MpvPlayer(MplayerPlayer):
RE_VERSION = re.compile('.*mpv (\d+)\.(\d+)\.\d+.*')
RE_VERSION = re.compile(r'.*mpv (\d+)\.(\d+)\.\d+.*')
osdMessageSeparator = "\\n"
osdMessageSeparator = "; " # TODO: Make conditional
osdMessageSeparator = "; " # TODO: Make conditional
@staticmethod
def run(client, playerPath, filePath, args):
@ -19,9 +23,11 @@ class MpvPlayer(MplayerPlayer):
except:
ver = None
constants.MPV_NEW_VERSION = ver is None or int(ver.group(1)) > 0 or int(ver.group(2)) >= 6
constants.MPV_OSC_VISIBILITY_CHANGE_VERSION = False if ver is None else int(ver.group(1)) > 0 or int(ver.group(2)) >= 28
constants.MPV_OSC_VISIBILITY_CHANGE_VERSION = False if ver is None else int(ver.group(1)) > 0 or int(ver.group(2)) >= 28
if not constants.MPV_OSC_VISIBILITY_CHANGE_VERSION:
client.ui.showDebugMessage("This version of mpv is not known to be compatible with changing the OSC visibility. Please use mpv >=0.28.0.")
client.ui.showDebugMessage(
"This version of mpv is not known to be compatible with changing the OSC visibility. "
"Please use mpv >=0.28.0.")
if constants.MPV_NEW_VERSION:
return NewMpvPlayer(client, MpvPlayer.getExpandedPath(playerPath), filePath, args)
else:
@ -77,6 +83,7 @@ class MpvPlayer(MplayerPlayer):
def getPlayerPathErrors(playerPath, filePath):
return None
class OldMpvPlayer(MpvPlayer):
POSITION_QUERY = 'time-pos'
OSD_QUERY = 'show_text'
@ -111,6 +118,7 @@ class OldMpvPlayer(MpvPlayer):
self.setPaused(self._client.getGlobalPaused())
self.setPosition(self._client.getGlobalPosition())
class NewMpvPlayer(OldMpvPlayer):
lastResetTime = None
lastMPVPositionUpdate = None
@ -120,17 +128,18 @@ class NewMpvPlayer(OldMpvPlayer):
def displayMessage(self, message, duration=(constants.OSD_DURATION * 1000), OSDType=constants.OSD_NOTIFICATION,
mood=constants.MESSAGE_NEUTRAL):
if not self._client._config["chatOutputEnabled"]:
super(self.__class__, self).displayMessage(message=message,duration=duration,OSDType=OSDType,mood=mood)
super(self.__class__, self).displayMessage(message=message, duration=duration, OSDType=OSDType, mood=mood)
return
messageString = self._sanitizeText(message.replace("\\n", "<NEWLINE>")).replace("\\\\",constants.MPV_INPUT_BACKSLASH_SUBSTITUTE_CHARACTER).replace("<NEWLINE>", "\\n")
messageString = self._sanitizeText(message.replace("\\n", "<NEWLINE>")).replace(
"\\\\", constants.MPV_INPUT_BACKSLASH_SUBSTITUTE_CHARACTER).replace("<NEWLINE>", "\\n")
self._listener.sendLine('script-message-to syncplayintf {}-osd-{} "{}"'.format(OSDType, mood, messageString))
def displayChatMessage(self, username, message):
if not self._client._config["chatOutputEnabled"]:
super(self.__class__, self).displayChatMessage(username,message)
super(self.__class__, self).displayChatMessage(username, message)
return
username = self._sanitizeText(username.replace("\\",constants.MPV_INPUT_BACKSLASH_SUBSTITUTE_CHARACTER))
message = self._sanitizeText(message.replace("\\",constants.MPV_INPUT_BACKSLASH_SUBSTITUTE_CHARACTER))
username = self._sanitizeText(username.replace("\\", sconstants.MPV_INPUT_BACKSLASH_SUBSTITUTE_CHARACTER))
message = self._sanitizeText(message.replace("\\", constants.MPV_INPUT_BACKSLASH_SUBSTITUTE_CHARACTER))
messageString = "<{}> {}".format(username, message)
self._listener.sendLine('script-message-to syncplayintf chat "{}"'.format(messageString))
@ -141,7 +150,7 @@ class NewMpvPlayer(OldMpvPlayer):
pauseValue = "yes" if value else "no"
self._setProperty("pause", pauseValue)
self._paused = value
if value == False:
if not value:
self.lastMPVPositionUpdate = time.time()
def _getProperty(self, property_):
@ -155,25 +164,34 @@ class NewMpvPlayer(OldMpvPlayer):
self._listener.sendLine("print_text ""ANS_{}=${{{}}}""".format(property_, propertyID))
def getCalculatedPosition(self):
if self.fileLoaded == False:
self._client.ui.showDebugMessage("File not loaded so using GlobalPosition for getCalculatedPosition({})".format(self._client.getGlobalPosition()))
if not self.fileLoaded:
self._client.ui.showDebugMessage(
"File not loaded so using GlobalPosition for getCalculatedPosition({})".format(
self._client.getGlobalPosition()))
return self._client.getGlobalPosition()
if self.lastMPVPositionUpdate is None:
self._client.ui.showDebugMessage("MPV not updated position so using GlobalPosition for getCalculatedPosition ({})".format(self._client.getGlobalPosition()))
self._client.ui.showDebugMessage(
"MPV not updated position so using GlobalPosition for getCalculatedPosition ({})".format(
self._client.getGlobalPosition()))
return self._client.getGlobalPosition()
if self._recentlyReset():
self._client.ui.showDebugMessage("Recently reset so using self.position for getCalculatedPosition ({})".format(self._position))
self._client.ui.showDebugMessage(
"Recently reset so using self.position for getCalculatedPosition ({})".format(
self._position))
return self._position
diff = time.time() - self.lastMPVPositionUpdate
if diff > constants.MPV_UNRESPONSIVE_THRESHOLD:
self.reactor.callFromThread(self._client.ui.showErrorMessage, getMessage("mpv-unresponsive-error").format(int(diff)), True)
self.reactor.callFromThread(
self._client.ui.showErrorMessage, getMessage("mpv-unresponsive-error").format(int(diff)), True)
self.drop()
if diff > constants.PLAYER_ASK_DELAY and not self._paused:
self._client.ui.showDebugMessage("mpv did not response in time, so assuming position is {} ({}+{})".format(self._position + diff, self._position, diff))
self._client.ui.showDebugMessage(
"mpv did not response in time, so assuming position is {} ({}+{})".format(
self._position + diff, self._position, diff))
return self._position + diff
else:
return self._position
@ -184,9 +202,10 @@ class NewMpvPlayer(OldMpvPlayer):
self._client.ui.showDebugMessage("Recently reset, so storing position as 0")
self._position = 0
elif self._fileIsLoaded() or (value < constants.MPV_NEWFILE_IGNORE_TIME and self._fileIsLoaded(ignoreDelay=True)):
self._position = max(value,0)
self._position = max(value, 0)
else:
self._client.ui.showDebugMessage("No file loaded so storing position as GlobalPosition ({})".format(self._client.getGlobalPosition()))
self._client.ui.showDebugMessage(
"No file loaded so storing position as GlobalPosition ({})".format(self._client.getGlobalPosition()))
self._position = self._client.getGlobalPosition()
def _storePauseState(self, value):
@ -205,7 +224,8 @@ class NewMpvPlayer(OldMpvPlayer):
self._getPausedAndPosition()
self._positionAsk.wait(constants.MPV_LOCK_WAIT_TIME)
self._pausedAsk.wait(constants.MPV_LOCK_WAIT_TIME)
self._client.updatePlayerStatus(self._paused if self.fileLoaded else self._client.getGlobalPaused(), self.getCalculatedPosition())
self._client.updatePlayerStatus(
self._paused if self.fileLoaded else self._client.getGlobalPaused(), self.getCalculatedPosition())
def _getPausedAndPosition(self):
self._listener.sendLine("print_text ANS_pause=${pause}\r\nprint_text ANS_time-pos=${=time-pos}")
@ -229,7 +249,8 @@ class NewMpvPlayer(OldMpvPlayer):
def setPosition(self, value):
if value < constants.DO_NOT_RESET_POSITION_THRESHOLD and self._recentlyReset():
self._client.ui.showDebugMessage("Did not seek as recently reset and {} below 'do not reset position' threshold".format(value))
self._client.ui.showDebugMessage(
"Did not seek as recently reset and {} below 'do not reset position' threshold".format(value))
return
super(self.__class__, self).setPosition(value)
self.lastMPVPositionUpdate = time.time()
@ -245,7 +266,7 @@ class NewMpvPlayer(OldMpvPlayer):
self._client.ui.showDebugMessage("Want to set paused to {}".format(self._client.getGlobalPaused()))
else:
self._client.ui.showDebugMessage("Don't want to set paused to {}".format(self._client.getGlobalPaused()))
if resetPosition == False:
if not resetPosition:
self.setPosition(self._client.getGlobalPosition())
else:
self._storePosition(0)
@ -285,7 +306,14 @@ class NewMpvPlayer(OldMpvPlayer):
self._listener.setReadyToSend(True)
def _setOSDPosition(self):
if self._client._config['chatMoveOSD'] and (self._client._config['chatOutputEnabled'] or (self._client._config['chatInputEnabled'] and self._client._config['chatInputPosition'] == constants.INPUT_POSITION_TOP)):
if (
self._client._config['chatMoveOSD'] and (
self._client._config['chatOutputEnabled'] or (
self._client._config['chatInputEnabled'] and
self._client._config['chatInputPosition'] == constants.INPUT_POSITION_TOP
)
)
):
self._setProperty("osd-align-y", "bottom")
self._setProperty("osd-margin-y", int(self._client._config['chatOSDMargin']))
@ -309,9 +337,9 @@ class NewMpvPlayer(OldMpvPlayer):
def _fileIsLoaded(self, ignoreDelay=False):
if ignoreDelay:
self._client.ui.showDebugMessage("Ignoring _fileIsLoaded MPV_NEWFILE delay")
return True if self.fileLoaded else False
return bool(self.fileLoaded)
if self.fileLoaded == True and self.lastLoadedTime != None and time.time() > (self.lastLoadedTime + constants.MPV_NEWFILE_IGNORE_TIME):
return True
else:
return False
return (
self.fileLoaded and self.lastLoadedTime is not None and
time.time() > (self.lastLoadedTime + constants.MPV_NEWFILE_IGNORE_TIME)
)

View File

@ -1,5 +1,6 @@
import syncplay.players
class PlayerFactory(object):
def __init__(self):
self._players = syncplay.players.getAvailablePlayers()

View File

@ -1,18 +1,24 @@
import subprocess
import re
import threading
from syncplay.players.basePlayer import BasePlayer
from syncplay import constants, utils
import asynchat
import asyncore
import os
import sys
import random
import re
import socket
import asynchat, asyncore
import urllib.request, urllib.parse, urllib.error
import subprocess
import sys
import threading
import time
import urllib.error
import urllib.parse
import urllib.request
from syncplay import constants, utils
from syncplay.messages import getMessage
from syncplay.players.basePlayer import BasePlayer
from syncplay.utils import isBSD, isLinux, isWindows, isMacOS
class VlcPlayer(BasePlayer):
speedSupported = True
customOpenDialog = False
@ -42,12 +48,13 @@ class VlcPlayer(BasePlayer):
self._previousPreviousPosition = -2
self._previousPosition = -1
self._position = 0
try: # Hack to fix locale issue without importing locale library
try: # Hack to fix locale issue without importing locale library
self.radixChar = "{:n}".format(1.5)[1:2]
if self.radixChar == "" or self.radixChar == "1" or self.radixChar == "5":
raise ValueError
except:
self._client.ui.showErrorMessage("Failed to determine locale. As a fallback Syncplay is using the following radix character: \".\".")
self._client.ui.showErrorMessage(
"Failed to determine locale. As a fallback Syncplay is using the following radix character: \".\".")
self.radixChar = "."
self._durationAsk = threading.Event()
@ -110,7 +117,8 @@ class VlcPlayer(BasePlayer):
return self._client.getGlobalPosition()
diff = time.time() - self._lastVLCPositionUpdate
if diff > constants.PLAYER_ASK_DELAY and not self._paused:
self._client.ui.showDebugMessage("VLC did not response in time, so assuming position is {} ({}+{})".format(self._position + diff, self._position, diff))
self._client.ui.showDebugMessage("VLC did not response in time, so assuming position is {} ({}+{})".format(
self._position + diff, self._position, diff))
if diff > constants.VLC_LATENCY_ERROR_THRESHOLD:
if not self.shownVLCLatencyError or constants.DEBUG_MODE:
self._client.ui.showErrorMessage(getMessage("media-player-latency-warning").format(int(diff)))
@ -119,7 +127,10 @@ class VlcPlayer(BasePlayer):
else:
return self._position
def displayMessage(self, message, duration=constants.OSD_DURATION * 1000, OSDType=constants.OSD_DURATION, mood=constants.MESSAGE_NEUTRAL):
def displayMessage(
self, message,
duration=constants.OSD_DURATION * 1000, OSDType=constants.OSD_DURATION, mood=constants.MESSAGE_NEUTRAL
):
duration /= 1000
if OSDType != constants.OSD_ALERT:
self._listener.sendLine('display-osd: {}, {}, {}'.format('top-right', duration, message))
@ -212,21 +223,25 @@ class VlcPlayer(BasePlayer):
self._duration = float(value.replace(",", "."))
self._durationAsk.set()
elif name == "playstate":
self._paused = bool(value != 'playing') if(value != "no-input" and self._filechanged == False) else self._client.getGlobalPaused()
self._paused = bool(value != 'playing') if (value != "no-input" and not self._filechanged) else self._client.getGlobalPaused()
diff = time.time() - self._lastVLCPositionUpdate if self._lastVLCPositionUpdate else 0
if self._paused == False \
and self._position == self._previousPreviousPosition \
and self._previousPosition == self._position \
and self._duration > constants.PLAYLIST_LOAD_NEXT_FILE_MINIMUM_LENGTH \
and (self._duration - self._position) < constants.VLC_EOF_DURATION_THRESHOLD \
and diff > constants.VLC_LATENCY_ERROR_THRESHOLD:
if (
not self._paused and
self._position == self._previousPreviousPosition and
self._previousPosition == self._position and
self._duration > constants.PLAYLIST_LOAD_NEXT_FILE_MINIMUM_LENGTH and
(self._duration - self._position) < constants.VLC_EOF_DURATION_THRandD and
diff > constants.VLC_LATENCY_ERROR_THRESHOLD
):
self._client.ui.showDebugMessage("Treating 'playing' response as 'paused' due to VLC EOF bug")
self.setPaused(True)
self._pausedAsk.set()
elif name == "position":
newPosition = float(value.replace(",", ".")) if (value != "no-input" and self._filechanged == False) else self._client.getGlobalPosition()
newPosition = float(value.replace(",", ".")) if (value != "no-input" and not self._filechanged) else self._client.getGlobalPosition()
if newPosition == self._previousPosition and newPosition != self._duration and not self._paused:
self._client.ui.showDebugMessage("Not considering position {} duplicate as new time because of VLC time precision bug".format(newPosition))
self._client.ui.showDebugMessage(
"Not considering position {} duplicate as new time because of VLC time precision bug".format(
newPosition))
self._previousPreviousPosition = self._previousPosition
self._previousPosition = self._position
self._positionAsk.set()
@ -347,7 +362,8 @@ class VlcPlayer(BasePlayer):
playerController.vlcIntfUserPath = os.path.join(os.getenv('HOME', '.'), ".local/share/vlc/lua/intf/")
elif isMacOS():
playerController.vlcIntfPath = "/Applications/VLC.app/Contents/MacOS/share/lua/intf/"
playerController.vlcIntfUserPath = os.path.join(os.getenv('HOME', '.'), "Library/Application Support/org.videolan.vlc/lua/intf/")
playerController.vlcIntfUserPath = os.path.join(
os.getenv('HOME', '.'), "Library/Application Support/org.videolan.vlc/lua/intf/")
elif isBSD():
# *BSD ports/pkgs install to /usr/local by default.
# This should also work for all the other BSDs, such as OpenBSD or DragonFly.
@ -358,14 +374,17 @@ class VlcPlayer(BasePlayer):
playerController.vlcIntfUserPath = os.path.join(os.getenv('APPDATA', '.'), "VLC\\lua\\intf\\")
playerController.vlcModulePath = playerController.vlcIntfPath + "modules/?.luac"
if _usevlcintf(playerController.vlcIntfPath, playerController.vlcIntfUserPath):
playerController.SLAVE_ARGS.append('--lua-config=syncplay={{port=\"{}\"}}'.format(str(playerController.vlcport)))
playerController.SLAVE_ARGS.append(
'--lua-config=syncplay={{port=\"{}\"}}'.format(str(playerController.vlcport)))
else:
if isLinux():
playerController.vlcDataPath = "/usr/lib/syncplay/resources"
else:
playerController.vlcDataPath = utils.findWorkingDir() + "\\resources"
playerController.SLAVE_ARGS.append('--data-path={}'.format(playerController.vlcDataPath))
playerController.SLAVE_ARGS.append('--lua-config=syncplay={{modulepath=\"{}\",port=\"{}\"}}'.format(playerController.vlcModulePath, str(playerController.vlcport)))
playerController.SLAVE_ARGS.append(
'--lua-config=syncplay={{modulepath=\"{}\",port=\"{}\"}}'.format(
playerController.vlcModulePath, str(playerController.vlcport)))
call.extend(playerController.SLAVE_ARGS)
if args:
@ -376,11 +395,15 @@ class VlcPlayer(BasePlayer):
self._vlcVersion = None
if self.oldIntfVersion:
self.__playerController.drop(getMessage("vlc-interface-version-mismatch").format(self.oldIntfVersion,constants.VLC_INTERFACE_MIN_VERSION))
self.__playerController.drop(
getMessage("vlc-interface-version-mismatch").format(
self.oldIntfVersion, constants.VLC_INTERFACE_MIN_VERSION))
else:
if isWindows() and getattr(sys, 'frozen', '') and getattr(sys, '_MEIPASS', '') is not None: #Needed for pyinstaller --onefile bundle
self.__process = subprocess.Popen(call, stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=False, creationflags=0x08000000)
if isWindows() and getattr(sys, 'frozen', '') and getattr(sys, '_MEIPASS', '') is not None: # Needed for pyinstaller --onefile bundle
self.__process = subprocess.Popen(
call, stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE,
shell=False, creationflags=0x08000000)
else:
self.__process = subprocess.Popen(call, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
self.timeVLCLaunched = time.time()
@ -405,7 +428,7 @@ class VlcPlayer(BasePlayer):
if not isMacOS():
self.__process.stderr = None
else:
vlcoutputthread = threading.Thread(target = self.handle_vlcoutput, args=())
vlcoutputthread = threading.Thread(target=self.handle_vlcoutput, args=())
vlcoutputthread.setDaemon(True)
vlcoutputthread.start()
threading.Thread.__init__(self, name="VLC Listener")
@ -416,10 +439,7 @@ class VlcPlayer(BasePlayer):
self._sendingData = threading.Lock()
def _shouldListenForSTDOUT(self):
if isWindows():
return False # Due to VLC3 not using STDOUT/STDERR
else:
return True
return not isWindows()
def initiate_send(self):
with self._sendingData:
@ -462,7 +482,6 @@ class VlcPlayer(BasePlayer):
break
out.close()
def found_terminator(self):
self.vlcHasResponded = True
self.__playerController.lineReceived(b"".join(self._ibuffer))

View File

@ -17,4 +17,3 @@ from syncplay.utils import blackholeStdoutForFrozenWindow
if __name__ == '__main__':
blackholeStdoutForFrozenWindow()
SyncplayClientManager().run()

View File

@ -19,5 +19,14 @@ from syncplay.server import SyncFactory, ConfigurationGetter
if __name__ == '__main__':
argsGetter = ConfigurationGetter()
args = argsGetter.getConfiguration()
reactor.listenTCP(int(args.port), SyncFactory(args.password, args.motd_file, args.isolate_rooms, args.salt, args.disable_ready,args.disable_chat, args.max_chat_message_length))
reactor.listenTCP(
int(args.port),
SyncFactory(
args.password,
args.motd_file,
args.isolate_rooms,
args.salt,
args.disable_ready,
args.disable_chat,
args.max_chat_message_length))
reactor.run()