diff --git a/pyproject.toml b/pyproject.toml index b09a5b0..1466162 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "vlcsync" -version = "0.1.5" +version = "0.1.6" description = "Utility for synchronize multiple instances of VLC. Supports seek, play and pause. " authors = ["mrkeuz "] license = "MIT" diff --git a/vlcsync/vlc_conn.py b/vlcsync/vlc_conn.py index f621758..e6eb4dc 100644 --- a/vlcsync/vlc_conn.py +++ b/vlcsync/vlc_conn.py @@ -17,6 +17,7 @@ def __init__(self, host, port, pid=None): self.host = host logger.trace("Connect {0}", port) self.sock = socket.create_connection((host, self.port)) + self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) self._recv_answer() def cmd(self, command: str) -> str: @@ -35,7 +36,7 @@ def _recv_answer(self): except ConnectionAbortedError: raise VlcConnectionError(f"Socket lost connection", self.pid) - except (socket.timeout, TimeoutError): + except (socket.timeout, TimeoutError, OSError): logger.trace(f"Data when timeout {data}") raise VlcConnectionError(f"Socket receive answer native timeout.", self.pid) diff --git a/vlcsync/vlc_util.py b/vlcsync/vlc_util.py index 3dcc7da..6156acc 100644 --- a/vlcsync/vlc_util.py +++ b/vlcsync/vlc_util.py @@ -1,6 +1,7 @@ from __future__ import annotations import socket +import threading import time from cached_property import cached_property_with_ttl @@ -94,28 +95,36 @@ def close(self): class VlcProcs: def __init__(self): + self.closed = False self._vlc_instances: dict[int, Vlc] = {} self.vlcFinder = VlcFinder() + self.vlc_finder_thread = threading.Thread(target=self.refresh_vlc_list_periodically, daemon=True) + self.vlc_finder_thread.start() - @cached_property_with_ttl(ttl=5) - def all_vlc(self) -> dict[int, Vlc]: - start = time.time() + def refresh_vlc_list_periodically(self): + while not self.closed: + start = time.time() + + vlc_in_system = self.vlcFinder.find_vlc(VLC_IFACE_IP) + logger.debug(vlc_in_system) - vlc_in_system = self.vlcFinder.find_vlc(VLC_IFACE_IP) + # Remove missed + for missed_pid in (self._vlc_instances.keys() - vlc_in_system.keys()): + self.dereg(missed_pid) - # Remove missed - for missed_pid in (self._vlc_instances.keys() - vlc_in_system.keys()): - self.dereg(missed_pid) + # Populate if not exists + for pid, port in vlc_in_system.items(): + if pid not in self._vlc_instances.keys(): + vlc = Vlc(pid, port) + print(f"Found instance with pid {pid} and port {VLC_IFACE_IP}:{port} {vlc.cur_state()}") + self._vlc_instances[pid] = vlc - # Populate if not exists - for pid, port in vlc_in_system.items(): - if pid not in self._vlc_instances.keys(): - vlc = Vlc(pid, port) - print(f"Found instance with pid {pid} and port {VLC_IFACE_IP}:{port} {vlc.cur_state()}") - self._vlc_instances[pid] = vlc + logger.debug(f"Compute all_vlc (took {time.time() - start:.3f})...") + time.sleep(5) - logger.debug(f"Compute all_vlc (took {time.time() - start:.3f})...") - return self._vlc_instances + @property + def all_vlc(self) -> dict[int, Vlc]: + return self._vlc_instances.copy() # For thread safe def sync_all(self, state: State, source: Vlc): logger.debug(">" * 60) @@ -145,6 +154,7 @@ def close(self): for vlc in self._vlc_instances.values(): vlc.close() + self.closed = True self._vlc_instances.clear() def __del__(self):