Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix MPV socket getting created in CWD #675

Merged
merged 3 commits into from
Apr 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 23 additions & 8 deletions syncplay/players/mpv.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# coding:utf8
import os
import random
import re
import sys
import time
Expand All @@ -10,7 +11,7 @@
from syncplay import constants
from syncplay.messages import getMessage
from syncplay.players.basePlayer import BasePlayer
from syncplay.utils import isURL, findResourcePath
from syncplay.utils import getRuntimeDir, isURL, findResourcePath
from syncplay.utils import isMacOS, isWindows, isASCII
from syncplay.vendor.python_mpv_jsonipc.python_mpv_jsonipc import MPV

Expand Down Expand Up @@ -375,7 +376,7 @@ def _loadFile(self, filePath):
self._listener.sendLine(['loadfile', filePath], notReadyAfterThis=True)

def setFeatures(self, featureList):
self.sendMpvOptions()
self._sendMpvOptions()

def setPosition(self, value):
if value < constants.DO_NOT_RESET_POSITION_THRESHOLD and self._recentlyReset():
Expand Down Expand Up @@ -408,7 +409,7 @@ def openFile(self, filePath, resetPosition=False):
self._storePosition(0)
# TO TRY: self._listener.setReadyToSend(False)

def sendMpvOptions(self):
def _sendMpvOptions(self):
options = []
for option in constants.MPV_SYNCPLAYINTF_OPTIONS_TO_SEND:
options.append("{}={}".format(option, self._client._config[option]))
Expand All @@ -420,8 +421,9 @@ def sendMpvOptions(self):
options_string = ", ".join(options)
self._listener.sendLine(["script-message-to", "syncplayintf", "set_syncplayintf_options", options_string])
self._setOSDPosition()
publicIPCSocket = self._listener.mpv_arguments.get("input-ipc-server") if self._listener.mpv_arguments.get("input-ipc-server") else "mpvSyncplaySocket"
self._setProperty("input-ipc-server", publicIPCSocket)
socketPath = self._listener.mpv_arguments.get("input-ipc-server")
if socketPath is not None:
self._setProperty("input-ipc-server", socketPath)

def _handleUnknownLine(self, line):
self.mpvErrorCheck(line)
Expand Down Expand Up @@ -449,7 +451,7 @@ def _handleUnknownLine(self, line):
#self._client.ui.showDebugMessage("{} = {} / {}".format(update_string, paused_update, position_update))

if "<get_syncplayintf_options>" in line:
self.sendMpvOptions()
self._sendMpvOptions()

if line == "<SyncplayUpdateFile>" or "Playing:" in line:
self._client.ui.showDebugMessage("Not ready to send due to <SyncplayUpdateFile>")
Expand Down Expand Up @@ -620,8 +622,15 @@ def __init__(self, playerController, playerIPCHandler, playerPath, filePath, arg
env['PATH'] = python_executable + ':' + env['PATH']
env['PYTHONPATH'] = pythonPath
try:
socket = self.mpv_arguments.get('input-ipc-server')
self.mpvpipe = self.playerIPCHandler(mpv_location=self.playerPath, ipc_socket=socket, loglevel="info", log_handler=self.__playerController.mpv_log_handler, quit_callback=self.stop_client, env=env, **self.mpv_arguments)
self.mpvpipe = self.playerIPCHandler(
loglevel="info",
ipc_socket=self._get_ipc_socket(),
mpv_location=self.playerPath,
log_handler=self.__playerController.mpv_log_handler,
quit_callback=self.stop_client,
env=env,
**self.mpv_arguments
)
except Exception as e:
self.quitReason = getMessage("media-player-error").format(str(e)) + " " + getMessage("mpv-failed-advice")
self.__playerController.reactor.callFromThread(self.__playerController._client.ui.showErrorMessage, self.quitReason, True)
Expand All @@ -630,6 +639,12 @@ def __init__(self, playerController, playerIPCHandler, playerPath, filePath, arg
#self.mpvpipe.show_text("HELLO WORLD!", 1000)
threading.Thread.__init__(self, name="MPV Listener")

def _get_ipc_socket(self):
if isWindows():
# On Windows, mpv expects a named pipe identifier (not a path)
return "syncplay-mpv-{0}".format(random.randint(0, 2**48))
return getRuntimeDir().joinpath("mpv-socket").as_posix()

def __getCwd(self, filePath, env):
if not filePath:
return None
Expand Down
23 changes: 22 additions & 1 deletion syncplay/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

import ast
import atexit
import datetime
import hashlib
import itertools
Expand All @@ -10,11 +10,13 @@
import string
import subprocess
import sys
import tempfile
import time
import traceback
import urllib.error
import urllib.parse
import urllib.request
from pathlib import Path

from syncplay import constants
from syncplay.messages import getMessage
Expand All @@ -37,9 +39,28 @@ def isMacOS():
def isBSD():
return constants.OS_BSD in sys.platform or sys.platform.startswith(constants.OS_DRAGONFLY)


def isWindowsConsole():
return os.path.basename(sys.executable) == "SyncplayConsole.exe"


def getRuntimeDir():
cachedPath = getattr(getRuntimeDir, "cachedPath", None)
if cachedPath is not None:
return cachedPath

baseDir = None
if not isWindows() and not isMacOS():
baseDir = os.getenv("XDG_RUNTIME_DIR", None)

tmp = tempfile.TemporaryDirectory(prefix="syncplay-", dir=baseDir)
atexit.register(tmp.cleanup)

o = Path(tmp.name)
setattr(getRuntimeDir, "cachedPath", o)
return o


def retry(ExceptionToCheck, tries=4, delay=3, backoff=2, logger=None):
"""Retry calling the decorated function using an exponential backoff.

Expand Down
Loading