Skip to content

Instantly share code, notes, and snippets.

@dtcooper
Last active February 17, 2017 22:25
Show Gist options
  • Save dtcooper/bb0dcac434a7842153d96a250dc195bc to your computer and use it in GitHub Desktop.
Save dtcooper/bb0dcac434a7842153d96a250dc195bc to your computer and use it in GitHub Desktop.
Checks what's playing on a sonos device. Useful to run in liquidsoap on a timer to figure out what the hell it's playing.
#!/bin/sh
"exec" "`dirname $0`/bin/python" "$0" "$@"
import sys
import argparse
import soco
class NowPlayingInfo(object):
def __init__(self, ip_address_or_speaker):
if isinstance(ip_address_or_speaker, basestring):
sonos = soco.SoCo(ip_address_or_speaker)
else:
sonos = ip_address_or_speaker
track_info = sonos.group.coordinator.get_current_track_info()
self.ip = sonos.ip_address
self.player_name = sonos.player_name
self.artist = track_info['artist'].replace('\n', ' ').strip().encode('utf-8')
self.title = track_info['title'].replace('\n', ' ').strip().encode('utf-8')
self.player_name = sonos.player_name
self.is_coordinator = sonos.is_coordinator
self.coordinator_name = self.coordinator_ip = None
if not self.is_coordinator:
self.coordinator_name = sonos.group.coordinator.player_name
self.coordinator_ip = sonos.group.coordinator.ip_address
def to_string(self, name_only=False):
s = u'%(player_name)s [%(ip)s]'
if not self.is_coordinator:
s += u' -- (coordinator: %(coordinator_name)s [%(coordinator_ip)s])'
if not name_only:
s += (u'\n * Artist: %(artist)s\n'
u' * Title: %(title)s')
s += '\n'
return s % self.__dict__
def main():
parser = argparse.ArgumentParser(
description='Get currently playing song from Sonos (if any)')
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('-i', '--ip-address', metavar='1.2.3.4', help='Sonos node IP address')
group.add_argument('-s', '--speaker', metavar='SpeakerName', help='Sonos speaker name')
group.add_argument('-l', '--list', action='store_true', help='List all Sonos nodes')
group.add_argument('-A', '--list-all', action='store_true', help="List all Sonos nodes and the tracks they're playing")
parser.add_argument('-v', '--verbose', action='store_true', help='Be verbose')
args = parser.parse_args()
if args.list or args.list_all:
speakers = sorted(soco.discover(), key=lambda s: s.player_name)
for speaker in speakers:
now_playing = NowPlayingInfo(speaker)
print now_playing.to_string(name_only=not args.list_all)
else:
if args.speaker:
search_speaker_name = args.speaker.lower().strip()
for speaker in soco.discover():
if search_speaker_name == speaker.player_name.lower().strip():
speaker = speaker.ip_address
break
else:
print 'Error! Speaker "%s" not found.' % args.speaker
sys.exit(1)
else:
speaker = args.ip_address
now_playing = NowPlayingInfo(speaker)
if args.verbose:
print now_playing.to_string().strip()
else:
if now_playing.artist:
print now_playing.artist
if now_playing.title:
print now_playing.title
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment