]> git.0d.be Git - django-panik-nonstop.git/commitdiff
stamina: add option to use mpv ipc server
authorFrédéric Péters <fpeters@0d.be>
Wed, 19 Aug 2020 12:56:15 +0000 (14:56 +0200)
committerFrédéric Péters <fpeters@0d.be>
Wed, 19 Aug 2020 13:00:24 +0000 (15:00 +0200)
nonstop/app_settings.py
nonstop/management/commands/stamina.py

index 51316ad80376407770f85ab12116a26b1f21554f..df6f886932463a7871a6ad772e9ad90a7c39b9c3 100644 (file)
@@ -26,6 +26,10 @@ class AppSettings:
     def PLAYER_ARGS(self):
         return self.get_setting('PLAYER_ARGS', [])
 
+    @property
+    def PLAYER_IPC_PATH(self):
+        return self.get_setting('PLAYER_IPC_PATH', '')
+
     @property
     def ON_AIR_SWITCH_URL(self):
         return self.get_setting('ON_AIR_SWITCH_URL', None)
index 3c80df0662dd251832395beacf3c2216329dad9f..be67fad08dbdf45166b0514ab61b2929a2570dc6 100644 (file)
@@ -187,6 +187,8 @@ class Command(BaseCommand):
         log_line.save()
 
     async def player_process(self, item, timeout=None):
+        if app_settings.PLAYER_IPC_PATH:
+            return await self.player_process_ipc(item, timeout=timeout)
         cmd = [app_settings.PLAYER_COMMAND] + app_settings.PLAYER_ARGS
         if hasattr(item, 'is_stream') and item.is_stream():
             cmd.append(item.stream.url)
@@ -208,6 +210,51 @@ class Command(BaseCommand):
                 self.player.kill()
         self.player = None
 
+    async def player_process_ipc(self, item, timeout=None):
+        starting = False
+        while True:
+            try:
+                reader, writer = await asyncio.open_unix_connection(
+                            app_settings.PLAYER_IPC_PATH)
+                break
+            except (FileNotFoundError, ConnectionRefusedError):
+                if not starting:
+                    cmd = [app_settings.PLAYER_COMMAND] + app_settings.PLAYER_ARGS
+                    cmd += ['--input-ipc-server=%s' % app_settings.PLAYER_IPC_PATH, '--idle']
+                    self.player = await asyncio.create_subprocess_exec(
+                            *cmd,
+                            stdout=asyncio.subprocess.DEVNULL,
+                            stderr=asyncio.subprocess.DEVNULL)
+                    starting = True
+                await asyncio.sleep(0.1)
+
+        if hasattr(item, 'is_stream') and item.is_stream():
+            file_path = item.stream.url
+            logger.info('Play stream: %s', item.stream.url)
+        else:
+            file_path = item.file_path()
+            logger.info('Play file: %s', item.file_path())
+
+        writer.write(json.dumps({'command': ['loadfile', file_path]}).encode() + b'\n')
+        try:
+            await writer.drain()
+        except ConnectionResetError:  # connection lost
+            return
+        try:
+            await asyncio.wait_for(self.player_ipc_idle(reader, writer), timeout=timeout)
+        except asyncio.TimeoutError:
+            pass
+        writer.close()
+        await writer.wait_closed()
+
+    async def player_ipc_idle(self, reader, writer):
+        while True:
+            data = await reader.readline()
+            if not data:
+                break
+            if json.loads(data) == {'event': 'idle'}:
+                break
+
     async def play(self, slot):
         now = datetime.datetime.now()
         if isinstance(slot, Nonstop):