From dd8c864d98fcc74b7a08083b1ab951bbc8b5f706 Mon Sep 17 00:00:00 2001 From: Etoh Date: Sun, 20 Sep 2020 13:45:23 +0100 Subject: [PATCH] Use Twisted for VLC communication (#353) * Port VLCPlayer from asyncore/asynchat to Twisted Rationale: asyncore/asynchat are deprecated since Python 3.6 and are going to be removed from the standard library from Python 3.10. It is unclear if these libraries will be picked up by maintainers and independently published on PyPI. At the moment, we are working on replacing them, in this commit with Twisted LineReceiver. Known issues: does not work with GUI. There is a conflict with qt5reactor -> "QSocketNotifier: Can only be used with threads started with QThread". * Fix QSocketNotifier issue with qt5reactor Sending the call to transport.write wrapped in a self.reactor.callFromThread instead of directly does the trick. Include also fixes to allow correct quit of VLC and Syncplay when either one is closed. Known issues: there is a noticeable lag (~ 1 second) between the start of Syncplay MainWindow and the start of VLC. * Re-add try/except to VLC * Bring back missing try Co-authored-by: Alberto Sottile --- syncplay/players/vlc.py | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/syncplay/players/vlc.py b/syncplay/players/vlc.py index 097f54b..3dfcbc1 100755 --- a/syncplay/players/vlc.py +++ b/syncplay/players/vlc.py @@ -32,13 +32,13 @@ class VLCProtocol(LineReceiver): if not self.factory.requestedVLCVersion: self.factory.requestedVLCVersion = True self.sendLine("get-vlc-version") - # try: - lineToSend = line.encode('utf-8') + self.delimiter - self.transport.write(lineToSend) - if self.factory._playerController._client and self.factory._playerController._client.ui: - self.factory._playerController._client.ui.showDebugMessage("player >> {}".format(line)) - # except: - # pass + try: + lineToSend = line.encode('utf-8') + self.delimiter + self.transport.write(lineToSend) + if self.factory._playerController._client and self.factory._playerController._client.ui: + self.factory._playerController._client.ui.showDebugMessage("player >> {}".format(line)) + except: + pass def connectionMade(self): self.factory.connected = True @@ -82,10 +82,10 @@ class VLCClientFactory(ClientFactory): self._playerController._vlcclosed.set() if not self.connected and not self.timeVLCLaunched: # For circumstances where Syncplay is not connected to VLC and is not reconnecting - #try: - self._process.terminate() - #except: # When VLC is already closed - # pass + try: + self._process.terminate() + except: # When VLC is already closed + pass class VlcPlayer(BasePlayer): @@ -139,12 +139,14 @@ class VlcPlayer(BasePlayer): return def initWhenConnected(self): - self._client.ui.showErrorMessage(getMessage("vlc-initial-warning")) - if not self._vlcready.wait(constants.VLC_OPEN_MAX_WAIT_TIME): - self._vlcready.set() - self._client.ui.showErrorMessage(getMessage("vlc-failed-connection"), True) - self.reactor.callFromThread(self._client.stop, True,) - self.reactor.callFromThread(self._client.initPlayer, self,) + try: + if not self._vlcready.wait(constants.VLC_OPEN_MAX_WAIT_TIME): + self._vlcready.set() + self._client.ui.showErrorMessage(getMessage("vlc-failed-connection"), True) + self.reactor.callFromThread(self._client.stop, True,) + self.reactor.callFromThread(self._client.initPlayer, self,) + except: + pass def _fileUpdateClearEvents(self): self._durationAsk.clear() @@ -514,4 +516,4 @@ class VlcPlayer(BasePlayer): out.close() def sendLine(self, line): - self.reactor.callFromThread(self._factory.protocol.sendLine, line) \ No newline at end of file + self.reactor.callFromThread(self._factory.protocol.sendLine, line)