Example #1
0
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
Example #2
0
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
Example #3
0
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
Example #4
0
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
Example #5
0
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()