some cleanup
authorMarcel van der Veldt <m.vanderveldt@outlook.com>
Tue, 28 May 2019 19:58:14 +0000 (21:58 +0200)
committerMarcel van der Veldt <m.vanderveldt@outlook.com>
Tue, 28 May 2019 19:58:14 +0000 (21:58 +0200)
another attempt to make the chromecast not crashing

music_assistant/modules/http_streamer.py
music_assistant/modules/musicproviders/qobuz.py
music_assistant/modules/musicproviders/spotify.py
music_assistant/modules/player.py
music_assistant/modules/playerproviders/chromecast.py
music_assistant/modules/playerproviders/pylms.py
music_assistant/modules/web.py
music_assistant/utils.py

index 52fd01d3e22ca0521c953f96199099d95240ff06..4b6c4f699d5181b814e858c192b5387e9c8d372e 100755 (executable)
@@ -180,9 +180,10 @@ class HTTPStreamer():
         await buf.drain()
         buf.write_eof()
         fd.close()
-        # successfull completion, send tmpfile to be processed in the background in main loop
-        self.mass.event_loop.create_task(self.__analyze_audio(tmpfile, track_id, provider, content_type))
-        LOGGER.info("fill_audio_buffer complete for track %s" % track_id)
+        LOGGER.debug("fill_audio_buffer complete for track %s" % track_id)
+        # successfull completion, process temp file for analysis
+        self.mass.event_loop.create_task(
+                self.__analyze_audio(tmpfile, track_id, provider, content_type))
         return
 
     def __get_track_cache_filename(self, track_id, provider):
@@ -194,27 +195,28 @@ class HTTPStreamer():
     @run_periodic(3600)
     async def __cache_cleanup(self):
         ''' calculate size of cache folder and cleanup if needed '''
-        size_limit = self.mass.config['base']['http_streamer']['audio_cache_max_size_gb']
-        total_size_gb = get_folder_size(self._audio_cache_dir)
-        LOGGER.info("current size of cache folder is %s GB" % total_size_gb)
-        if size_limit and total_size_gb > size_limit:
-            LOGGER.info("Cache folder size exceeds threshold, start cleanup...")
-            from pathlib import Path
-            import time
-            days = 14
-            while total_size_gb > size_limit:
-                time_in_secs = time.time() - (days * 24 * 60 * 60)
-                for i in Path(self._audio_cache_dir).iterdir():
-                    if i.is_file():
-                        if i.stat().st_atime <= time_in_secs:
-                            total_size_gb -= i.stat().st_size/float(1<<30)
-                            i.unlink()
-                    if total_size_gb < size_limit:
-                        break
-                days -= 1
-            LOGGER.info("Cache folder size cleanup completed")
+        def cleanup():
+            size_limit = self.mass.config['base']['http_streamer']['audio_cache_max_size_gb']
+            total_size_gb = get_folder_size(self._audio_cache_dir)
+            LOGGER.info("current size of cache folder is %s GB" % total_size_gb)
+            if size_limit and total_size_gb > size_limit:
+                LOGGER.info("Cache folder size exceeds threshold, start cleanup...")
+                from pathlib import Path
+                import time
+                days = 14
+                while total_size_gb > size_limit:
+                    time_in_secs = time.time() - (days * 24 * 60 * 60)
+                    for i in Path(self._audio_cache_dir).iterdir():
+                        if i.is_file():
+                            if i.stat().st_atime <= time_in_secs:
+                                total_size_gb -= i.stat().st_size/float(1<<30)
+                                i.unlink()
+                        if total_size_gb < size_limit:
+                            break
+                    days -= 1
+                LOGGER.info("Cache folder size cleanup completed")
+        await self.mass.event_loop.run_in_executor(None, cleanup)
 
-    
     @staticmethod
     def __get_bs1770_binary():
         ''' get the path to the bs1770 binary for the current OS '''
index 1e0b9993530224bf19c9f5e840ac8acf0fb6d46d..5ad9689e6ed9dba280623cdaa54d6625288bd781 100644 (file)
@@ -272,7 +272,6 @@ class QobuzProvider(MusicProvider):
                     if not chunk:
                         break
                     yield chunk
-        LOGGER.info("end of stream for track_id %s" % track_id)
     
     async def __parse_artist(self, artist_obj):
         ''' parse spotify artist object to generic layout '''
index 6742a5e0ac5e53968b3f377f78cbbd4615485369..7fe22cbcb78c10652b1bdb6c4cf083d6e189176e 100644 (file)
@@ -258,7 +258,6 @@ class SpotifyProvider(MusicProvider):
                 break
             yield chunk
         await process.wait()
-        LOGGER.info("end of stream for track_id %s" % track_id)
         
     async def __parse_artist(self, artist_obj):
         ''' parse spotify artist object to generic layout '''
index 0ca694c60dc7a9a019956642f9fcc5a9f9b856dd..fb70db9106567e5d442186ca010f636392e987a1 100755 (executable)
@@ -66,7 +66,7 @@ class Player():
                 cmd_args = 0
         if cmd == 'volume' and player.is_group and player.settings['apply_group_volume']:
             # group volume
-            return await self.__player_command_group_volume(player, cmd, cmd_args)
+            return await self.__player_command_group_volume(player, cmd_args)
         
         # redirect playlist related commands to parent player
         if player.group_parent and cmd not in ['power', 'volume', 'mute']:
@@ -115,7 +115,10 @@ class Player():
         cur_volume = player.volume_level
         new_volume = try_parse_int(new_volume)
         volume_dif = new_volume - cur_volume
-        volume_dif_percent = volume_dif/cur_volume
+        if cur_volume == 0:
+            volume_dif_percent = 1+(new_volume/100)
+        else:
+            volume_dif_percent = volume_dif/cur_volume
         player_childs = [item for item in self._players.values() if item.group_parent == player.player_id]
         for child_player in player_childs:
             if child_player.enabled and child_player.powered:
index 006eefa954a446eee624bd4a29f05598c3b75ac1..ac871066a03122f9b86de313be26b4a390985f0d 100644 (file)
@@ -106,11 +106,6 @@ class ChromecastProvider(PlayerProvider):
         ''' 
             play media on a player
         '''
-        count = 0
-        while self._chromecasts[player_id].is_busy and count < 10:
-            await asyncio.sleep(0.1)
-            count += 1
-        self._chromecasts[player_id].is_busy = True
         castplayer = self._chromecasts[player_id]
         cur_queue_index = await self.__get_cur_queue_index(player_id)
 
@@ -140,7 +135,6 @@ class ChromecastProvider(PlayerProvider):
             # add new items at end of queue
             self._player_queue[player_id] = self._player_queue[player_id] + media_items
             await self.__queue_insert(player_id, media_items)
-        self._chromecasts[player_id].is_busy = False
 
     ### Provider specific (helper) methods #####
 
@@ -246,13 +240,16 @@ class ChromecastProvider(PlayerProvider):
         '''send new data to the CC queue'''
         media_controller = castplayer.media_controller
         receiver_ctrl = media_controller._socket_client.receiver_controller
-        def app_launched_callback():
+        def send_queue():
                 """Plays media after chromecast has switched to requested app."""
                 queuedata['mediaSessionId'] = media_controller.status.media_session_id
                 media_controller.send_message(queuedata, inc_session_id=False)
                 castplayer.wait()
-        receiver_ctrl.launch_app(media_controller.app_id,
-                                callback_function=app_launched_callback)
+        if not media_controller.status.media_session_id:
+            receiver_ctrl.launch_app(media_controller.app_id, callback_function=send_queue)
+        else:
+            send_queue()
+        await asyncio.sleep(0.2)
 
     async def __handle_player_state(self, chromecast, caststatus=None, mediastatus=None):
         ''' handle a player state message from the socket '''
index 0e5dbc180aa81b80ba1ce6b07aae5d25e7835966..63fcd9493c10739700bea1e390b7b93f46afecd7 100644 (file)
@@ -119,7 +119,9 @@ class PyLMSServer(PlayerProvider):
 
     async def __queue_play(self, player_id, index, send_flush=False):
         ''' send play command to player '''
-        if not player_id in self._player_queue:
+        if not player_id in self._player_queue or not player_id in self._player_queue_index:
+            return
+        if not self._player_queue[player_id]:
             return
         if index == None:
             index = self._player_queue_index[player_id]
index 41686c69f333825076ce099852134798ab23f5c5..94e6da861890af40a8ba301b30f03ea5dcda4539 100755 (executable)
@@ -211,10 +211,11 @@ class Web():
 
     async def websocket_handler(self, request):
         ''' websockets handler '''
-        ws = web.WebSocketResponse()
-        await ws.prepare(request)
         cb_id = None
+        ws = None
         try:
+            ws = web.WebSocketResponse()
+            await ws.prepare(request)
             # register callback for internal events
             async def send_event(msg, msg_details):
                 ws_msg = {"message": msg, "message_details": msg_details }
index 32098437090f070b348c98006ac091bc45b671b2..2d84052ecc88d0a918bad742bb1ad88fc57414b6 100755 (executable)
@@ -33,6 +33,7 @@ def run_async_background_task(executor, corofn, *args):
     def run_task(corofn, *args):
         LOGGER.debug('running %s in background task' % corofn.__name__)
         new_loop = asyncio.new_event_loop()
+        asyncio.set_event_loop(new_loop)
         coro = corofn(*args)
         res = new_loop.run_until_complete(coro)
         new_loop.close()