async def main(): print('Jukebox Pi') signal.signal(signal.SIGINT, signal_handler) client = MPDClient() atexit.register(client.disconnect) lcd = LCD(make_callback(client)) lcd.turn_on() atexit.register(lcd.stop) clock = Clock(lcd) atexit.register(clock.stop) try: await client.connect('localhost', 6600) except Exception as e: print('Connection to MPD failed:', e) return print('Connected to MPD version ', client.mpd_version) current_status = await get_status(client) show_track(lcd, clock, {}, current_status) async for _ in client.idle(['player']): status = await get_status(client) print(status) show_track(lcd, clock, current_status, status) current_status = status
async def main(): print("Create MPD client") client = MPDClient() # Not necessary, but should not cause any trouble either client.disconnect() try: await client.connect('localhost', 6600) except Exception as e: print("Connection failed:", e) return print("Connected to MPD version", client.mpd_version) try: status = await client.status() except Exception as e: print("Status error:", e) return else: print("Status success:", status) print(list(await client.commands())) import time start = time.time() for x in await client.listall(): print("sync:", x) print("Time to first sync:", time.time() - start) break start = time.time() async for x in client.listall(): print("async:", x) print("Time to first async:", time.time() - start) break try: await client.addid() except Exception as e: print("An erroneous command, as expected, raised:", e) try: async for x in client.plchangesposid(): print("Why does this work?") except Exception as e: print( "An erroneous asynchronously looped command, as expected, raised:", e) i = 0 async for subsystem in client.idle(): print("Idle change in", subsystem) i += 1 if i > 5: print("Enough changes, quitting") break
class MPDConnection: def __init__(self, host, port): self.host = host self.port = port self.mpd = MPDClient() self._playlist_empty = asyncio.Event() self._adding_song = False async def start(self): await self.mpd.connect(self.host, self.port) asyncio.ensure_future(self._event_loop()) async def wait_for_song(self): '''Returns when the playlist is empty''' await self._playlist_empty.wait() def is_ready(self): '''Immediately returns true if the playlist is empty, false otherwise.''' return self._playlist_empty.is_set() async def add_to_playlist(self, url): if self._adding_song: raise Exception self._adding_song = True self._playlist_empty.clear() print() print(url) print() try: await self.mpd.add(url) await self.mpd.play() except mpd.CommandError: pass self._adding_song = False async def skip(self): await self.mpd.clear() async def _event_loop(self): while True: status = await self.mpd.status() if status['playlistlength'] == '0': if not self._adding_song: self._playlist_empty.set() else: self._playlist_empty.clear() async for subsystems in self.mpd.idle(): if 'playlist' in subsystems or 'player' in subsystems: break
async def main(): print("Create MPD client") client = MPDClient() try: await client.connect('localhost', 6600) except Exception as e: print("Connection failed:", e) return print("Connected to MPD version", client.mpd_version) try: status = await client.status() except Exception as e: print("Status error:", e) return else: print("Status success:", status) print(list(await client.commands())) import time start = time.time() for x in await client.listall(): print("sync:", x) print("Time to first sync:", time.time() - start) break start = time.time() async for x in client.listall(): print("async:", x) print("Time to first async:", time.time() - start) break try: await client.addid() except Exception as e: print("An erroneous command, as expected, raised:", e) try: async for x in client.plchangesposid(): print("Why does this work?") except Exception as e: print("An erroneous asynchronously looped command, as expected, raised:", e) i = 0 async for subsystem in client.idle(): print("Idle change in", subsystem) i += 1 if i > 5: print("Enough changes, quitting") break
class MpdSnapcastSyncer: def __init__(self, loop): self._logger = logging.getLogger(self.__class__.__name__) self._loop = loop self.mpd_outputs = {} async def setup(self, snapcast_server: str, mpd_server: str) -> None: snapcast_task = asyncio.create_task(self.setup_snapcast(snapcast_server)) mpd_task = asyncio.create_task(self.setup_mpd(mpd_server)) await snapcast_task await mpd_task def snapcast_client_changed(self, client: snapcast.control.client.Snapclient) -> None: self._loop.create_task(self.async_snapcast_client_changed(client)) async def async_snapcast_client_changed(self, client: snapcast.control.client.Snapclient) -> None: name = client.friendly_name try: output = self.mpd_outputs[name] except KeyError: # there is no output named like this Snapcast client, ignore event self._logger.debug('Ignoring change of snapcast client %s: No matching MPD output' % name) return if output.enabled != client.muted: # If the output is not enabled and the client is muted (or vice # versa), everything is fine. return self._logger.info('Turning %s MPD output %s' % ( 'off' if client.muted else 'on', name )) # determine which method to call actor = self.mpd.disableoutput if client.muted else self.mpd.enableoutput # fake stored state of the output to avoid calling # mpd_output_changed() from mpd_outputs_changed() when MPD notifies us # about our own change self.mpd_outputs[name].enabled = not self.mpd_outputs[name].enabled # call actual actor method await actor(output.id) async def mpd_outputs_changed(self) -> None: async for output in self.mpd.outputs(): output = MPDOutput(output) try: # find stored data about this output old_output = self.mpd_outputs[output.name] except KeyError: # the output didn't exist before, don't trigger any action pass else: if output.enabled != old_output.enabled: # the output's enabled state changed await self.mpd_output_changed(output) # update our stored copy of output data self.mpd_outputs[output.name] = output async def mpd_output_changed(self, output: dict) -> None: for client in self.snapcast.clients: if client.friendly_name != output.name: continue self._logger.info('%s snapcast client %s (%s)' % ( 'Unmuting' if output.enabled else 'Muting', output.name, client.identifier )) await client.set_muted(not output.enabled) return else: self._logger.debug('Ignoring change of MPD output %s: No matching snapcast client' % output.name) async def setup_snapcast(self, snapcast_server: str) -> None: self.snapcast = await snapcast.control.create_server( self._loop, snapcast_server, ) for client in self.snapcast.clients: client.set_callback(self.snapcast_client_changed) self._logger.debug('Set callback for snapcast client %s' % client.friendly_name) async def setup_mpd(self, mpd_server: str) -> None: self.mpd = MPDClient() await self.mpd.connect(mpd_server) # get initial state of outputs async for output in self.mpd.outputs(): output = MPDOutput(output) self.mpd_outputs[output.name] = output # add idle command to to event loop self._loop.create_task(self.listen_mpd()) async def listen_mpd(self) -> None: async for event in self.mpd.idle(['output']): await self.mpd_outputs_changed()