def connect(self,port): global client connection = False retry = 2 while retry > 0: client = MPDClient() # Create the MPD client try: client.timeout = 10 client.idletimeout = None client.connect("localhost", port) log.message("Connected to MPD port " + str(port), log.INFO) connection = True retry = 0 except: log.message("Failed to connect to MPD on port " + str(port), log.ERROR) time.sleep(0.5) # Wait for interrupt in the case of a shutdown log.message("Restarting MPD",log.DEBUG) if retry < 2: self.execCommand("service mpd restart") else: self.execCommand("service mpd start") time.sleep(2) # Give MPD time to restart retry -= 1 return connection
def __enter__(self): client = MPDClient(use_unicode=True) self.client = client client.timeout = 1 client.idletimeout = None client.connect("131.urlab.be", 6600) return client
def connect_to_mpd(self): client=MPDClient() try: client.connect(MPDHost, MPDPort) return client except SocketError: print "Unable to connect to MPD on %s on port %s" % (MPDHost, MPDPort)
def yoinkMPD(cod): mpd = MPDClient(use_unicode=True) mpd.timeout = None mpd.idletimeout = None mpd.connect(cod.config["mpd"]["host"], cod.config["mpd"]["port"]) return mpd
def play_id(play_id): client = MPDClient() client.connect(app.config['MPD']['host'], app.config['MPD']['port']) client.timeout = None client.idletimeout = None client.playid(play_id) return redirect(url_for('player'))
def run(): if not request.form['url']: flash('Please provide an URL') return redirect(url_for('welcome')) # do stuff try: p = subprocess.check_output(['/usr/bin/python', 'youtube-dl', '-t', '--no-progress', '--extract-audio', '--max-quality=18', '--audio-format=mp3', '--', request.form['url']]) except: flash("Nice try.") return redirect(url_for('welcome')) m = re.search("\[ffmpeg\] Destination: (.+?)\s", p) myfile = m.group(1) shutil.move(myfile, "static/%s" % myfile) try: mpd = MPDClient() try: mpd.connect(host="trillian", port="6600") mpd.add("http://toolbox.labor.koeln.ccc.de/static/%s" % myfile) except: raise except: flash('mpd failure') return redirect(url_for('welcome')) flash('your song has been added to the playlist') return redirect(url_for('welcome'))
def connect(host): ''' Connect to mpd. ''' logger.info("Connecting to mpd on " + host) # Parse the host address url = urlparse('//' + host) hostname = url.hostname port = url.port # Default to localhost port 6600 if hostname == None: hostname = 'localhost' if port == None: port = 6600 logger.debug('Hostname: ' + hostname) logger.debug('Port: ' + str(port)) try: mpdc = MPDClient() mpdc.connect(hostname, port) logger.debug('Connection succeeded') logger.debug('MPD status: ' + str(mpdc.status())) except OSError as exception: logger.info('Can not connect to mpdd on ' + host) logger.debug('Exception: ' + str(exception.errno)) logger.debug('Message: ' + exception.strerror) sys.exit(1) return(mpdc)
class IndiMPDClient(object): def __init__(self): self.config = IndiMPCConfiguration() self.setup_dbus() self.setup_client() self.oldstatus = "" self.oldsongdata = "" pynotify.init("indimpc") self.notification = pynotify.Notification("indiMPC started") self.notification.set_hint("action-icons", True) gobject.timeout_add(500, self.status_loop) if self.config.general_grab_keys: self.grab_mmkeys() def setup_dbus(self): dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) self.bus = dbus.Bus(dbus.Bus.TYPE_SESSION) def setup_client(self): global MPD try: self.mpdclient = MPDClient() self.mpdclient.connect(self.config.mpd_host, self.config.mpd_port) if self.config.mpd_password not in ("", None): self.mpdclient.password(self.config.mpd_password) self.oldstatus = self.mpdclient.status()["state"] except socket.error, e: sys.stderr.write("[FATAL] indimpc: can't connect to mpd. please check if it's running corectly") sys.exit()
def fav_song(request): c = MPDClient() c.connect("localhost", 6600) form = FavSongForm(request.POST or None) if not form.is_valid(): for error in form.errors: messages.add_message( request, messages.ERROR, "Error: {0}".format(form.errors[error][0]) ) else: filename = form.cleaned_data['filename'] track = get_track(filename, in_playlist=False) if not track: messages.add_message( request, messages.ERROR, "Error: Cannot find song." ) else: messages.add_message( request, messages.INFO, "Faved: {artist} - {title}".format( artist=track['artist'], title=track['title']) ) song_obj = get_song(filename, track['artist'], track['title']) SongFav(song=song_obj).save() return redirect(request.GET.get("from", "/"))
def delegateInput(self, texts): """A wrapper for querying brain.""" # check if input is meant to start the music module for text in texts: if any(x in text.upper() for x in ["SPOTIFY", "MUSIC"]): self._logger.debug("Preparing to start music module") # check if mpd client is running try: client = MPDClient() client.timeout = None client.idletimeout = None client.connect("localhost", 6600) except: self._logger.critical("Can't connect to mpd client, cannot start music mode.", exc_info=True) self.mic.say( "I'm sorry. It seems that Spotify is not enabled. Please read the documentation to learn how to configure Spotify.") return self.mic.say("Please give me a moment, I'm loading your Spotify playlists.") self._logger.debug("Starting music mode") music_mode = MusicMode(self.persona, self.mic) music_mode.handleForever() self._logger.debug("Exiting music mode") return self.brain.query(texts)
def delegateInput(self, text): """A wrapper for querying brain.""" got_hit = False # check if input is meant to start the music module if any(x in text.upper() for x in ["SPOTIFY", "MUSIC"]): # check if mpd client is running try: client = MPDClient() client.timeout = None client.idletimeout = None client.connect("localhost", 6600) except: self.logger.warning("Failed to init MPDClient") self.mic.say("Wybacz, ale najwyraźniej usługa Spotify nie działa") return self.logger.info("waiting for Spotify playlist") self.mic.say("Poczekaj chwilę, wczytuję listę utworów Spotify") music_mode = MusicMode(self.persona, self.mic, self.logger) music_mode.handleForever() return else: if " następnie " in lowerUTF8(text): l_text = text.split(" następnie ") for text in l_text: new_got_hit = self.brain.query(text) got_hit = got_hit or new_got_hit else: got_hit = self.brain.query(text) return got_hit
def request_song(request): c = MPDClient() c.connect("localhost", 6600) form = RequestSongForm(request.POST or None) if not form.is_valid(): for error in form.errors: messages.add_message( request, messages.ERROR, "Error: {0}".format(form.errors[error][0]) ) else: filename = form.cleaned_data['filename'] track = get_track(filename, in_playlist=False) if not track: messages.add_message( request, messages.ERROR, "Error: Cannot find song." ) else: messages.add_message( request, messages.INFO, "Requested: {artist} - {title}".format( artist=track['artist'], title=track['title']) ) song_obj = get_song(filename, track['artist'], track['title']) sr, created = SongRequest.objects.get_or_create( song=song_obj, ) sr.save() # safe SongRequest anyway to update timestamp SongRequestVote(songrequest=sr, value=+1).save() return redirect(request.GET.get("from", "/"))
def currentTrack(self, i3status_output_json, i3status_config): try: c = MPDClient() c.connect(host=HOST, port=PORT) if PASSWORD: c.password(PASSWORD) status = c.status() song = int(status.get("song", 0)) next_song = int(status.get("nextsong", 0)) if (status["state"] == "pause" and HIDE_WHEN_PAUSED) or (status["state"] == "stop" and HIDE_WHEN_STOPPED): text = "" else: try: song = c.playlistinfo()[song] song["time"] = "{0:.2f}".format(int(song.get("time", 1)) / 60) except IndexError: song = {} try: next_song = c.playlistinfo()[next_song] except IndexError: next_song = {} format_args = song format_args["state"] = STATE_CHARACTERS.get(status.get("state", None)) for k, v in next_song.items(): format_args["next_{}".format(k)] = v text = STRFORMAT for k, v in format_args.items(): text = text.replace("{" + k + "}", v) for sub in re.findall(r"{\S+?}", text): text = text.replace(sub, "") except SocketError: text = "Failed to connect to mpd!" except CommandError: text = "Failed to authenticate to mpd!" c.disconnect() if len(text) > MAX_WIDTH: text = text[-MAX_WIDTH-3:] + "..." if self.text != text: transformed = True self.text = text else: transformed = False response = { 'cached_until': time() + CACHE_TIMEOUT, 'full_text': self.text, 'name': 'scratchpad-count', 'transformed': transformed } return (POSITION, response)
class MPDPoller(object): def __init__(self, host='localhost', port='6600', password=None): self._host = host self._port = port self._password = password self._client = MPDClient() def connect(self): try: self._client.connect(self._host, self._port) except IOError as strerror: raise PollerError("Could not connect to '%s': %s" % (self._host, strerror)) except mpd.MPDError as e: raise PollerError("Could not connect to '%s': %s" % (self._host, e)) if self._password: try: self._client.password(self._password) # Catch errors with the password command (e.g., wrong password) except mpd.CommandError as e: raise PollerError("Could not connect to '%s': " "password commmand failed: %s" % (self._host, e)) # Catch all other possible errors except (mpd.MPDError, IOError) as e: raise PollerError("Could not connect to '%s': " "error with password command: %s" % (self._host, e)) def disconnect(self): try: self._client.close() except (mpd.MPDError, IOError): pass try: self._client.disconnect() except (mpd.MPDError, IOError): self._client = mpd.MPDClient() def poll(self): try: song = self._client.currentsong() except (mpd.MPDError, IOError): self.disconnect() try: self.connect() except PollerError as e: raise PollerError("Reconnecting failed: %s" % e) try: song = self._client.currentsong() except (mpd.MPDError, IOError) as e: raise PollerError("Couldn't retrieve current song: %s" % e) print(song)
class Observer(QThread): """MPD Observer thread.""" def __init__(self): self._config = ServiceLocator.getGlobalServiceInstance(ServiceNames.Configuration) self.client = MPDClient() return QThread.__init__(self) def __del__(self): self.wait() def mpdConnect(self): self.client.timeout = 10 self.client.idletimeout = None self.client.connect(self._config.mpdserver, self._config.mpdport) if len(self._config.mpdpassword) > 0: self.client.password(self._config.mpdpassword) self.client.update() def run(self): try: self.mpdConnect() while True: info = self.client.idle() print("info:{0}".format(info)) if 'update' in info: # Update all self.updatePlaylist() self.updatePlayer() self.updateMixer() if 'playlist' in info: self.updatePlaylist() if 'player' in info: self.updatePlayer() self.updateMixer() if 'mixer' in info: self.updateMixer() self.sleep(2) except: self.emit(SIGNAL(ObserverSignals.ConnectionError)) pass def updatePlaylist(self): playlist = self.client.playlistinfo() self.emit(SIGNAL(ObserverSignals.PlaylistChanged), playlist) pass def updateMixer(self): status = self.client.status() self.emit(SIGNAL(ObserverSignals.MixerChanged), status) pass def updatePlayer(self): currentSong = self.client.currentsong() self.emit(SIGNAL(ObserverSignals.PlayerChanged), currentSong) pass
def mpd_status(room): if not room in mpd_room_to_port: return jsonify({'error': 'unkown room'}) from mpd import MPDClient client = MPDClient() client.connect('mpd.shack', mpd_room_to_port[room]) state = client.status()['state'] return jsonify({'status': state})
def initialize_mpd(config): """ Return a MPD client connection """ client = MPDClient() client.connect(config.mpd.host, config.mpd.port) return client
def _mopidy_idle(self): client_idle = MPDClient() client_idle.connect(MOPIDY_HOST, MOPIDY_PORT) while client_idle.status()['state'] != "stop": client_idle.idle() client_idle.close() client_idle.disconnect()
def connect(self, timeout=None): try: MPDClient.connect(self, host = self.__host, port = self.__port, timeout = self.__timeout) self.is_connected = True except SocketError: log.critical('Could not connect to MPD server') self.is_connected = False return self.is_connected
def connectMPD(): """ Connect MPD service on port 6600 """ client = MPDClient() # create client object client.timeout = 10 # network timeout in seconds (floats allowed), default: None client.idletimeout = None # timeout for fetching the result of the idle command is handled seperately, default: None try: client.connect("localhost", 6600) # connect to localhost:6600 except Exception : print "Can Connect to MPD..."
def __init__(self, host, port, password, datadir=None): MPDClient.__init__(self) if not self.connection(host, port, password): self.disconnect() raise NameError("Mauvais hôte ou mot de passe MPD") if not datadir: self.datadir = None else: self.datadir = datadir
def stop_radio(): client = MPDClient() client.timeout = MPD_TIMEOUT client.connect(MPD_SERVER, 6600) client.stop() client.close() client.disconnect() return ""
def __init__(self, **kwargs): c = MPDClient() c.connect('localhost', 6600) menu_items = \ [self.itm('All artists', True, None)] + \ [self.itm(a['playlist'], True, None) for a in c.listplaylists()] super().__init__(title="Browsing artists", menu_items=menu_items, **kwargs)
def startClient(): client = MPDClient() # create client object # network timeout in seconds (floats allowed), default: None client.timeout = 10 # timeout for fetching the result of the idle command is handled # seperately, default: None client.idletimeout = None client.connect("localhost", 6600) # connect to localhost:6600 return client
def client(): remote = environ['MPD_HOST'] host = remote.split(':')[0] port = remote.split(':')[1] client = MPDClient() client.timeout = 10 client.idletimeout = None client.connect(host, port) return client
class client(object): def __enter__(self): self.client = MPDClient() if mpd_connect(self.client, CON_ID): return self.client else: return None def __exit__(self, *args, **kwargs): self.client.disconnect()
def get_mpd_info(): client = MPDClient() client.connect("localhost", 6600) np = client.currentsong() pause = "%{A:mpc pause:} \uf3a7 %{A}" play = "%{A:mpc play:} \uf3aa %{A}" if "name" in np: return np["name"] + " " + pause + play else: return np["title"] + " " + pause + play
def __init__(self, **kwargs): c = MPDClient() c.connect('localhost', 6600) playlists = [x['playlist'] for x in c.listplaylists()] playlists.sort(key=str.lower) items = [self.itm(x, True, PlaylistViewer, playlist_name=x) for x in playlists] super().__init__(title="Artists", menu_items=items, **kwargs)
def __init__(self, use_unicode=False): self.__host = self.config.get("mpd","host") self.__port = self.config.get("mpd","port") self.__timeout = 10 #MPDClient.__init__(self, *a, **k) MPDClient.__init__(self,use_unicode = use_unicode) self.use_unicode = use_unicode self._lock = Lock()
def __init__(self): self._cache = {} MPDClientBase.__init__(self) if hasattr(MPDClientBase, '_writecommand'): self._commands.update({'rescan': self._getitem ,'single': self._getnone ,'consume': self._getnone ,'idle': self._getlist ,'noidle': None })
def __init__(self): logging.debug("RaspDac_Display Initializing") self.tempreadexpired = 0 self.diskreadexpired = 0 self.ratereadexpired = 0 # used with Redis to try to figure out how long the song has been playing self.timesongstarted = 0 self.currentsong = "" self.currentelapsed = 0 self.tempc = 0.0 self.tempf = 0.0 self.avail = 0 self.availp = 0 self.rate = 0 # Initilize the connections to the music Daemons. Currently supporting # MPD and SPOP (for Spotify) ATTEMPTS=3 # Will try to connect multiple times global RUNE_ENABLED if RUNE_ENABLED: # This tries to pull in the redis module which is only used right now for RuneAudio. # If it is not present, REDIS will be disabled try: import redis for i in range (1,ATTEMPTS): try: # Try to connect to REDIS service self.redisclient = redis.Redis(REDIS_SERVER, REDIS_PORT, REDIS_PASSWORD) break except: time.sleep(2) else: # After the alloted number of attempts did not succeed in connecting logging.warning("Unable to connect to REDIS service on startup") except ImportError: logging.warning("Redis requested but module not found.") RUNE_ENABLED = False if MPD_ENABLED: for i in range (1,ATTEMPTS): self.client = MPDClient(use_unicode=True) try: # Connect to the MPD daemon self.client.connect(MPD_SERVER, MPD_PORT) break except: time.sleep(2) else: # After the alloted number of attempts did not succeed in connecting logging.warning("Unable to connect to MPD service on startup") if SPOP_ENABLED: # Now attempting to connect to the Spotify daemon # This may fail if Spotify is not configured. That's ok! for i in range (1,ATTEMPTS): try: self.spotclient = telnetlib.Telnet(SPOP_SERVER,SPOP_PORT) self.spotclient.read_until("\n") break except: time.sleep(2) else: # After the alloted number of attempts did not succeed in connecting logging.warning("Unable to connect to Spotify service on startup") if LMS_ENABLED: for i in range (1,ATTEMPTS): try: # Connect to the LMS daemon self.lmsserver = pylms.server.Server(LMS_SERVER, LMS_PORT, LMS_USER, LMS_PASSWORD) self.lmsserver.connect() # Find correct player players = self.lmsserver.get_players() for p in players: ### Need to find out how to get the MAC address from player if p.get_ref() == LMS_PLAYER: self.lmsplayer = p break if self.lmsplayer is None: self.lmsplayer = self.lmsserver.get_players()[0] if self.lmsplayer is None: raise Exception('Could not find any LMS player') break except (socket_error, AttributeError, IndexError): logging.debug("Connect attempt {0} to LMS server failed".format(i)) time.sleep(2) else: # After the alloted number of attempts did not succeed in connecting logging.warning("Unable to connect to LMS service on startup") global STATUSLOGGING if STATUSLOGGING: try: self.statusfile = open(STATUSLOGFILE, 'a') except: logging.warning("Status data logging requested but could not open {0}".format(STATUSLOGFILE)) STATUSLOGGING = False
class SoundManager(object): def __init__(self): self.client = MPDClient() self.client.connect("localhost", 6600) self.client.random(1) self.client.setvol(50) self.client.single(1) print('current playlist') print(self.client.playlist()) # print('add song playlist') # self.client.add('music/t.mp3') self.client.playlistadd('t', './music/') # self.client.play() def status(self): return self.client.status() def pause(self): self.client.pause() def setVolume(self, volume): self.client.setvol(volume) def nextRandomSong(self): self.client.next()
cad.lcd.set_cursor(4, 1) cad.lcd.write_custom_bitmap(3) cad.lcd.write(playlist) # Retrieve volume level from mpc and display def display_volume(): playerstatus = client.status() volume = (playerstatus['volume']) cad.lcd.set_cursor(12, 1) cad.lcd.write(volume) cad = pifacecad.PiFaceCAD() # creating Pifacecad object cad.lcd.backlight_on() # put the lcd backlight on client = MPDClient() # create MPD client object client.timeout = 1000 # setting network timeout in seconds client.idletimeout = None # setting timeout timeout for fetching results client.connect("localhost", 6600) # connect to localhost:6600 client.play() # starts playing custom_bitmaps() # defines simple char bitmaps to be shown on the display init_display() # initialise the display display_channel() # shows current radio station on display listener = pifacecad.SwitchEventListener(chip=cad) # listens to button pressed for i in range(8): listener.register(i, pifacecad.IODIR_FALLING_EDGE, update_pin_text) listener.activate()
def __init__(self): self.client = MPDClient() self.client = MPDClient() self.client.timeout = 10 self.client.idletimeout = None self.client.connect("127.0.0.1", 9009)
# -*- coding: utf-8 -*- from mpd import MPDClient from config import MPD_SRV srv = MPDClient() volume = 76 def conn(func): def wrapper(*args): srv.connect(MPD_SRV['host'], MPD_SRV['port']) srv.password(MPD_SRV['passwd']) func(*args) srv.disconnect() return wrapper @conn def init(): global volume srv.repeat(1) srv.setvol(volume) @conn def dec_vol(): global volume if volume > 50: volume -= 2 srv.setvol(volume)
if str.startswith(payload, "stop"): mpdclient1.stop() if str.startswith(payload, "incvol"): volume = int(mpdclient1.status()['volume']) if volume < 100: mpdclient1.setvol(volume + 1) if str.startswith(payload, "decvol"): volume = int(mpdclient1.status()['volume']) if volume > 0: mpdclient1.setvol(volume - 1) client = mqtt.Client() client.on_connect = on_connect client.on_message = on_message client.connect("dc.home.castle", 1883, 60) client.loop_start() mpdclient0 = MPDClient() mpdclient0.connect("127.0.0.1", iMPDPort0) mpdclient1 = MPDClient() mpdclient1.connect("127.0.0.1", iMPDPort1) while True: time.sleep(10) client.publish(sOrt1 + "/audio/status", str(mpdclient1.status())) client.publish(sOrt1 + "/audio/currentsong", str(mpdclient1.currentsong())) client.publish(sOrt0 + "/audio/status", str(mpdclient0.status())) client.publish(sOrt0 + "/audio/currentsong", str(mpdclient0.currentsong()))
class OBABP(object): ''' classdocs ''' def __init__(self,): ''' Constructor ''' self.setPort('6600'); self.setHost('localhost'); self.client = MPDClient(); def setLed(self, _led): self.led = _led; def setButton(self, _button): self.button = _button; def setPort(self, _port): self.port = _port; def setHost(self, _host): self.host = _host; def setDriveName(self, _driveName): self.driveName = _driveName; def setMountPoint(self, _mountPoint): self.mountPoint = _mountPoint; def setMusicDir(self, _musicDir): self.musicDir = _musicDir; def setMpdTagCasche(self, _mpdTagCasche): self.mpdTagCasche = _mpdTagCasche; def connectMPD(self): try: con_id = {'host':self.host, 'port':self.port} self.client.connect(**con_id) except SocketError: print "connection: error"; return False print "connection: ok"; return True def satupGPIO(self, mode): # GPIO.cleanup(); GPIO.setmode(mode); GPIO.setup(self.led, GPIO.OUT); GPIO.setup(self.button, GPIO.IN, pull_up_down=GPIO.PUD_UP) def flashLED(self, speed, time): for x in range(0, time): GPIO.output(self.led, GPIO.LOW) sleep(speed) GPIO.output(self.led, GPIO.HIGH) sleep(speed) def loadMusic(self, device): os.system("mount "+device+" "+self.mountPoint); os.system("/etc/init.d/mpd stop"); os.system("rm -rf "+self.musicDir+"*"); os.system("cp "+self.mountPoint+"* "+self.musicDir); os.system("umount "+self.mountPoint); os.system("rm "+self.mpdTagCasche); os.system("/etc/init.d/mpd start") os.system("mpc clear") os.system("mpc ls | mpc add") os.system("/etc/init.d/mpd restart") def updateLED(self): # adjust LED to actual state if self.client.status()["state"] == "play": GPIO.output(self.led, GPIO.LOW) else: GPIO.output(self.led, GPIO.HIGH) def checkForUSBDevice(self): res = "" context = pyudev.Context() for device in context.list_devices(subsystem='block', DEVTYPE='partition'): if device.get('ID_FS_LABEL') == self.driveName: res = device.device_node return res def buttonDown(self): if GPIO.input(self.button) == False: return True; else: return False; def playPause(self): print "play/pause" if self.client.status()["state"] == "stop": self.client.play(); else: self.client.pause(); def go(self): self.connectMPD() print self.client.status(); timebuttonisstillpressed = 0 self.flashLED(0.1, 10); self.updateLED(); print "setup ok" while True: pendrive = self.checkForUSBDevice(); self.updateLED(); if pendrive != "": print "new music detected" self.flashLED(0.1, 5); self.client.disconnect(); self.loadMusic(pendrive); self.connectMPD(); print self.client.status(); self.flashLED(0.05, 10) while self.checkForUSBDevice() == pendrive: self.flashLED(0.1, 1); sleep(0.1); print "new music added" self.flashLED(0.1, 5); if self.buttonDown(): if timebuttonisstillpressed == 0: self.playPause(); sleep(0.1) self.updateLED(); if timebuttonisstillpressed > 4: print "prev" self.client.previous(); self.flashLED(0.1, 5); timebuttonisstillpressed = 0; timebuttonisstillpressed = timebuttonisstillpressed + 0.1; else: timebuttonisstillpressed = 0; sleep(0.1) return 1;
def main(): parser = argparse.ArgumentParser(add_help=False) parser.add_argument('-h', '--host', default='localhost', dest='host') parser.add_argument('-p', '--port', default=6600, type=int, dest='port') parser.add_argument('-i', '--irc', action='store_const', const=True, default=False, dest='irc') parser.add_argument('-u', '--uncolored', action='store_const', const=True, default=False, dest='uncolored') parser.add_argument('-v', '--verbose', action='store_const', const=True, default=False, dest='verbose') parser.add_argument('--help', action='help') args = parser.parse_args() xhost = args.host xport = args.port xirc = args.irc xuncolored = args.uncolored xverbose = args.verbose client = MPDClient() client.timeout = 10 client.idletimeout = None shost = xhost.split('@', 1) nhost, passw = None, None if len(shost) != 2: nhost = xhost else: nhost, passw = shost[1], shost[0] try: client.connect(nhost, xport) if passw: client.password(passw) except socket.timeout: if xverbose: eprint("err: socket.timeout") sys.exit(1) except socket.gaierror: if xverbose: eprint("err: socket.gaierror") sys.exit(1) except socket.error: if xverbose: eprint("err: socket.error") sys.exit(1) csong = client.currentsong() if xverbose: eprint(csong) if len(csong) <= 0: # nothing playing right now sys.exit(0) # fill in style vars depending on output st = Style() if xuncolored: # plain ASCII st.f_s, st.f_e = '', '' st.hl_s, st.hl_e = '', '' st.und_s, st.und_e = '"', '"' elif not xirc: # ANSI st.f_s, st.f_e = "\033[0;36m", "\033[0m" st.hl_s, st.hl_e = "\033[0m", "\033[36m" st.und_s, st.und_e = "\033[0;4m", "\033[0;36m" else: # IRC st.f_s, st.f_e = "\00310", "" st.hl_s, st.hl_e = "\017", "\00310" st.und_s, st.und_e = "\017\037", "\017\00310" #fsong = st.f_s + "♪⟪ " fsong = st.f_s + "♪ " if 'title' in csong: fsong += '"%s%s%s"' % (st.hl_s, csong['title'], st.hl_e) if 'album' in csong: if ('artist' in csong) and (('albumartist' not in csong) or (csong['artist'] != csong['albumartist'])): fsong += " by %s" % prettyartist(st, csong['artist']) fsong += " on %s%s%s" % (st.und_s, csong['album'], st.und_e) if 'date' in csong: fsong += " %s" % prettydate(st, csong['date']) if 'albumartist' in csong: fsong += " by %s" % prettyartist(st, csong['albumartist']) else: if 'date' in csong: fsong += " %s" % prettydate(st, csong['date']) if 'artist' in csong: fsong += " by %s" % prettyartist(st, csong['artist']) else: fname = csong['file'] sindex = fname.rfind('/') fsong += st.hl_s if sindex >= 0: fsong += fname[sindex + 1:] else: fsong += fname fsong += st.hl_e #fsong += " ⟫" + st.f_e fsong += st.f_e print(fsong)
from mpd import MPDClient, CommandError client = MPDClient() client.timeout = 1 client.connect('localhost', 6600) client.password('B7WtKLYaAw7wVf4p')
def main(): ## MPD object instance client = MPDClient() mpdConnect(client, CON_ID) status = client.status() print status timebuttonisstillpressed = 0 flashLED(0.1, 5) updateLED(client) while True: device = checkForUSBDevice(USBNAME) if device != "": # USB thumb drive has been inserted, new music will be copied flashLED(0.1, 5) client.disconnect() loadMusic(client, CON_ID, device) mpdConnect(client, CON_ID) print client.status() flashLED(0.1, 5) # wait until thumb drive is umplugged again while checkForUSBDevice(USBNAME) == device: sleep(1.0) flashLED(0.1, 5) if GPIO.input(BUTTON) == True: if timebuttonisstillpressed == 0: # button has been pressed, pause or unpause now if client.status()["state"] == "stop": client.play() else: client.pause() updateLED(client) elif timebuttonisstillpressed > 4: # go back one track if button is pressed > 4 secs client.previous() flashLED(0.1, 5) timebuttonisstillpressed = 0 timebuttonisstillpressed = timebuttonisstillpressed + 0.1 else: timebuttonisstillpressed = 0 sleep(0.1)
def __init__(self, host="localhost", port="6600"): self.client = MPDClient() self.client.timeout = 1 self.client.idletimeout = None self.client.connect(host, port)
class MPC: """MPD Client for all actions in views.py. Connect to music player daemon and send/receive data. Connects on init, so no need to call reconnect() yourself. NOTE: some methods might throw, but this is not too bad for use in django, just reload page. """ def __init__(self): """Create MPDClient and connect.""" logger = PbLogger('PROFILE MPD') self.connected = False self.error = False self.client = MPDClient() self.client.timeout = 10 self.reconnect() self.truncated = 0 # set to the truncate value if truncated (search, list, ...) logger.print('__init__') def __del__(self): """Disconect if deleted by middleware and print debug""" print_debug('MPD DEL') def reconnect(self): """Try connect 5 times, if not successful self.connected will be False.""" logger = PbLogger('PROFILE MPD') self.connected = False self.error = False try: self.client.disconnect() except (ConnectionError, BrokenPipeError, ValueError): pass for i in range(5): try: self.client.connect('localhost', 6600) self.connected = True except (ConnectionError, BrokenPipeError, ValueError): time.sleep(0.1) if self.connected: logger.print('reconnect()') return True self.error = True logger.print('reconnect() [FAIL!]') return False def get_stats(self): """Displays statistics. :return: { artists: number of artists albums: number of albums songs: number of songs uptime: daemon uptime in seconds db_playtime: sum of all song times in the db db_update: last db update in UNIX time playtime: time length of music played free: bytes available in upload folder (if PB_UPLOAD_DIR set)} """ self.ensure_connected() stats = self.client.stats() if settings.PB_UPLOAD_DIR is not None: s = os.statvfs(settings.PB_UPLOAD_DIR) free = s.f_bavail * s.f_frsize stats['free'] = free return stats def get_status(self): """Get status dict from mpd. If connection error occurred, try to reconnect max 5 times. :return: {'audio': '44100:24:2', 'bitrate': '320', 'consume': '0', 'elapsed': '10.203', 'mixrampdb': '0.000000', 'mixrampdelay': 'nan', 'nextsong': '55', 'nextsongid': '55', 'playlist': '2', 'playlistlength': '123', 'random': '1', 'repeat': '1', 'single': '0', 'song': '58', 'songid': '58', 'state': 'pause', 'time': '10:191', 'volume': '40', 'xfade': '0'} :return: MPDClient.status() """ res = {'error_str': self.error} for i in range(5): try: res = self.client.status() except (ConnectionError, CommandError, ProtocolError, BrokenPipeError, ValueError): print_debug('MPD RECONNECT') self.reconnect() res['error_str'] = self.error return res def get_status_int(self, key, dflt=0): """Fetch value from mpd status dict as int, fallback to dflt if no such key. NOTE: Won't catch failed conversions. """ stat = self.get_status() if key in stat: return int(stat[key]) return dflt def ensure_connected(self): """Make sure we are connected.""" # Abuse get_status() method which tries to connect up to 5 times. self.get_status() def get_currentsong(self): """Fetch current song dict from mpd. Force reconnect if failed. :return: {'album': 'Litany', 'albumartist': 'Vader', 'artist': 'Vader', 'date': '2000', 'file': 'local/Extreme_Metal/Vader - Litany - 01 - Wings.mp3', 'genre': 'Death Metal', 'id': '58', 'last-modified': '2014-12-10T20:00:58Z', 'pos': '58', 'time': '191', 'title': 'Wings', 'track': '1'} """ self.ensure_connected() res = self.client.currentsong() if len(res) == 0: res = { 'album': '', 'artist': '', 'title': 'Not Playing!', 'time': 0, 'file': '' } return res def get_status_data(self): """Combined currentsong / status data for AJAX GET or POST on index page :return: see generate_status_data() """ status = self.get_status() current = self.get_currentsong() return self.generate_status_data(status, current) @staticmethod def generate_status_data(status, current): """Combined currentsong / status data :return: {title: xxx time: seconds album: xxx artist: xxx date: yyyy id: N elapsed: seconds random: bool repeat: bool volume: percentage state: ['playing', 'stopped', 'paused'] playlist: VERSION-NUMBER playlistlength: N file: local/Mp3/...../file.mp3 } """ data = {} if len(current) == 0: current = { 'album': '', 'artist': '', 'title': 'Not Playing!', 'time': 0, 'file': '' } data['title'] = save_item(current, 'title') data['time'] = current['time'] if 'time' in current else 0 for key in ['album', 'artist', 'date', 'id', 'file']: data[key] = save_item(current, key) for key in [ 'elapsed', 'random', 'repeat', 'volume', 'state', 'playlist', 'playlistlength' ]: data[key] = status[key] if key in status else '0' data['rating'] = Rating.get_rating(current['file']) return data def volume(self): """Current volume as int in [0,100]""" return self.get_status_int('volume') def change_volume(self, amount): """Add amount to current volume int [-100, +100]""" self.set_volume(self.volume() + amount) def set_volume(self, setvol): """Set current volume as int in [0,100]""" self.ensure_connected() vol = setvol if vol < 0: vol = 0 if vol > 100: vol = 100 try: self.client.setvol(vol) except CommandError: pass return self.volume() def update_database(self): """Trigger mpd update command (!= rescan). Idler will get notified when scan is done. """ self.ensure_connected() self.client.update() def playlistinfo(self, start, end): """Get playlist items in interval [start, end) :param start: start index in playlist (start = 0) :param end: end index in playlist (excluded) :return: {version=N, length=N, data=[[pos, title, artist, album, length, id, file, rating]]} """ logger = PbLogger('PROFILE MPD') pl_len = self.get_status_int('playlistlength') pl_ver = self.get_status_int('playlist') result = {'version': pl_ver, 'data': [], 'length': pl_len} if end == -1: end = pl_len if end < start: return result if start >= pl_len: return result raise_mpd_led() items = self.client.playlistinfo("%d:%d" % (start, end)) logger.print_step('items') # make sure we only do 1 SQL query for all ratings. raise_sql_led() files = [x['file'] for x in items] q = Rating.objects.filter(Q(path__in=files)).values('path', 'rating').all() rat_d = dict([(x['path'], x['rating']) for x in q]) logger.print_step('sql') clear_sql_led() data = [] for item in items: file = item['file'] if 'file' in item else '' res = list([item['pos']]) res.append(save_title(item)) res.append(save_item(item, 'artist')) res.append(save_item(item, 'album')) length = time.strftime( "%M:%S", time.gmtime(int(item['time']) if 'time' in item else 0)) res.append(length) res.append(item['id']) res.append(file) res.append(rat_d[file] if file in rat_d else 0) data.append(res) result['data'] = data clear_mpd_led() logger.print('playlistinfo() done.') return result def playlistinfo_by_name(self, plname): """Get condensed playlist info. Used for playlist edit mode. :param plname: name of playlist :return: [[file, artist - title, pos]] """ self.ensure_connected() try: info = self.client.listplaylistinfo(plname) except CommandError: return [] # no such playlist result = [] pos = 0 for item in info: title = save_artist_title(item) result.append([item['file'], title, pos]) pos += 1 return result def playlistinfo_full(self, id): """Return full playlistinfo for song with id. :param id: song id from playlist :return: MPDClient.playlistid(id) """ self.ensure_connected() return self.client.playlistid(id) def file_info(self, file): """Return full info for file. :param file :return: [{'last-modified': '2016-02-29T18:03:53Z', 'time': '313', 'album': 'Master Of Puppets', 'artist': 'Metallica', 'file': 'Mp3/M/......mp3', 'title': 'Battery', 'date': '1986', 'track': '01/08', 'albumartist': 'Metallica', 'genre': 'Thrash Metal', 'in_playlists': [list of playlists], 'in_paths': [list of paths] }] """ self.ensure_connected() res = self.client.find('file', file) for item in res: if 'genre' in item: m = re.match(r"^\((\d+)", save_item(item, 'genre')) if m: item['genre'] = translate_genre(int(m.group(1))) item['rating'] = Rating.get_rating(item['file']) for check in ['title', 'artist', 'album']: item[check] = save_item(item, check) item['in_playlists'] = [ x['playlist'] for x in self.client.listplaylists() if sum([ 1 for x2 in self.client.listplaylist(x['playlist']) if file in x2 ]) > 0 ] item['in_paths'] = [ os.path.dirname(x['file']) for x in self.client.search('file', os.path.basename(file)) ] return res def playlist_changes(self, version): """Get changes in playlist since version. NOTE: if new playlist is shorter, use playlistlength to truncate old playlist view. :param version: diff version of playlist. :return: {version: new version changes: [[pos, title, artist, album, length, id, file, rating]] length: new playlist length} """ pl_len = self.get_status_int('playlistlength') pl_ver = self.get_status_int('playlist') changes = self.client.plchanges(version) # make fast query for all ratings files = [x['file'] for x in changes] q = Rating.objects.filter(Q(path__in=files)).values('path', 'rating').all() rat_d = dict([(x['path'], x['rating']) for x in q]) result = [] for change in changes: item = self.client.playlistinfo(change['pos'])[0] file = item['file'] if 'file' in item else '' res = list([item['pos']]) res.append(save_title(item)) res.append(save_item(item, 'artist')) res.append(save_item(item, 'album')) length = time.strftime( "%M:%S", time.gmtime(int(item['time']) if time in item else 0)) res.append(length) res.append(item['id']) res.append(file) res.append(rat_d[file] if file in rat_d else 0) result.append(res) return {'version': pl_ver, 'changes': result, 'length': pl_len} def exec_command(self, cmd): """Execute command for music player daemon. :param cmd: ['back', 'playpause', 'stop', 'next', 'decvol', 'incvol', 'random', 'repeat', 'seekcur SEC'] """ success = True self.ensure_connected() try: if cmd == 'back': flash_mpd_led() self.client.previous() elif cmd == 'playpause': flash_mpd_led() status = self.get_status() if status['state'] == 'play': self.client.pause() else: self.client.play() elif cmd == 'stop': flash_mpd_led() self.client.stop() elif cmd == 'next': flash_mpd_led() self.client.next() elif cmd == 'decvol': flash_mpd_led() self.change_volume(-3) elif cmd == 'incvol': flash_mpd_led() self.change_volume(3) elif cmd == 'random': flash_mpd_led() rand = self.get_status_int('random') self.client.random(1 if rand == 0 else 0) elif cmd == 'repeat': flash_mpd_led() rep = self.get_status_int('repeat') self.client.repeat(1 if rep == 0 else 0) elif cmd.startswith('seekcur'): flash_mpd_led() pct = float(cmd.split()[1]) cur = self.get_currentsong() jump = 0.0 if 'time' in cur: jump = float(cur['time']) * pct / 100.0 self.client.seekcur(jump) else: success = False except CommandError: success = False except ConnectionError: success = False data = self.get_status_data() data['cmd'] = cmd data['success'] = success return data def browse(self, path): """Browse files in files view. :param path: Directory to list. :return: Array of ['1', title, '', '', '', directory] for dirs Array of ['2', title, artist, album, length, file, ext, date, rating] for audio files """ logger = PbLogger('PROFILE MPD') if path is None: return None self.ensure_connected() result = [] raise_mpd_led() try: lsdir = self.client.lsinfo(path) except CommandError: clear_mpd_led() return None # check if we have differing artists in directory mixed_artists = False last_artist = None for item in lsdir: if 'file' in item: if 'artist' in item: if last_artist is None: last_artist = save_item(item, 'artist') elif last_artist != save_item(item, 'artist'): mixed_artists = True break logger.print_step('browse mpd done') # query all ratings at once raise_sql_led() files = [x['file'] for x in lsdir if 'file' in x] q = Rating.objects.filter(Q(path__in=files)).values('path', 'rating').all() rat_d = dict([(x['path'], x['rating']) for x in q]) clear_sql_led() logger.print_step('browse sql done') for item in lsdir: if 'directory' in item: title = os.path.basename(item['directory']) result.append(['1', title, '', '', '', item['directory']]) # need to check for file item -- may not scan 'playlist' items. elif 'file' in item: res = ['2'] if 'title' in item: if mixed_artists and 'artist' in item: res.append(save_artist_title(item)) else: res.append(save_title(item)) else: no_ext = os.path.splitext(item['file'])[0] res.append(os.path.basename(no_ext).replace('_', ' ')) res.append(save_item(item, 'artist')) res.append(save_item(item, 'album')) length = time.strftime( "%M:%S", time.gmtime(int(item['time']) if 'time' in item else 0)) res.append(length) res.append(item['file']) # add extension as result for files --> matches image png in static/img ext = os.path.splitext(item['file'])[1][1:].lower() if ext not in ['mp3', 'wma', 'ogg', 'wav', 'flac', 'mp4']: ext = 'audio' res.append(ext) res.append(item['date'] if 'date' in item else '') res.append(rat_d[item['file']] if item['file'] in rat_d else 0) result.append(res) clear_mpd_led() logger.print('browse() done') return result def playlist_action(self, cmd, plname, items): """Perform action on playlist. :param cmd: ['append', 'insert', 'clear', 'deleteid(s)?', 'playid', 'playid(s)?next', 'moveid', 'moveid(s)?end' :param plname: playlist name -- '' for current playlist :param items: payload array for command :return: status string """ self.ensure_connected() if (cmd == 'append') or (cmd == 'insert' and 'pos' not in self.get_currentsong()): # append at end if command is append or insert and not playing raise_mpd_led() for item in items: try: if len(plname): self.client.playlistadd(plname, item) else: self.client.add(item) except CommandError: clear_mpd_led() return 'Add error' clear_mpd_led() return '%d' % len(items) + ' items appended to playlist ' + plname elif cmd == 'clear': # clear playlist try: self.client.clear() except CommandError: return 'Clear error' flash_mpd_led() return 'Playlist cleared.' elif cmd == 'deleteallbutcur': flash_mpd_led() now_pos = self.get_status_int('song', -1) now_len = self.get_status_int('playlistlength', -1) if now_pos == -1: self.client.clear() else: self.client.delete((0, now_pos)) self.client.delete((1, )) new_len = self.get_status_int('playlistlength', -1) clear_mpd_led() return 'Deleted {} items from playlist.'.format(now_len - new_len) elif cmd == 'deleteid' or cmd == 'deleteids': # Remove items from playlist for i in sorted([int(x) for x in items], reverse=True): try: self.client.deleteid(i) except CommandError: return 'Delete error' flash_mpd_led() return '%d items removed from playlist' % len(items) elif cmd == 'insert': # insert (list of) song(s) after current song pos = int(self.get_currentsong()['pos']) + 1 for item in reversed(items): try: self.client.addid(item, pos) except CommandError: return 'Add error' flash_mpd_led() return '%d' % len( items) + ' items inserted into playlist ' + plname elif cmd == 'playid': # Play song with #id now. self.client.playid(int(items[0])) title = self.get_status_data()['title'] flash_mpd_led() return 'Playing ' + title elif cmd == 'playidnext': # Move song with #id after current song try: self.client.moveid(int(items[0]), -1) except CommandError: return 'Move error' flash_mpd_led() return 'Moved 1 song after current song' elif cmd == 'playidsnext': # Move songs with [#id] after current song for item in reversed(items): try: self.client.moveid(int(item), -1) except CommandError: return 'Move error' flash_mpd_led() return 'Moved %d songs after current song' % len(items) elif cmd == 'moveid': # move song(s) with id(s) to end try: self.client.moveid(items[0], items[1]) except CommandError: return 'Move error' flash_mpd_led() return 'Moved song to position %d' % (int(items[1]) + 1) elif cmd == 'moveidend' or cmd == 'moveidsend': # move song(s) with id(s) to end move_to = self.get_status_int('playlistlength') - 1 for i in [int(x) for x in items][::-1]: try: self.client.moveid(i, move_to) except CommandError: return 'Move error' flash_mpd_led() return 'Moved %d songs to end' % len(items) elif cmd == 'randomize': # clear playlist try: self.client.shuffle() except CommandError: return 'Shuffle error' flash_mpd_led() return 'Playlist randomized.' elif cmd == 'randomize-rest': # clear playlist try: song_pos = self.get_status_int('song') + 1 pl_len = self.get_status_int('playlistlength') - 1 self.client.shuffle("%d:%d" % (song_pos, pl_len)) except CommandError: return 'Shuffle error' flash_mpd_led() return 'Playlist randomized after current song.' elif cmd == 'seed': raise_mpd_led() n = int(items[0]) random.seed() db_files = self.client.list('file') filter_dirs = items[1] if filter_dirs != '': db_files = [i for i in db_files if i.startswith(filter_dirs)] if len(db_files) == 0: return 'No items to seed in dir %s' % filter_dirs add = [] for i in range(n): add.append(db_files[random.randrange(0, len(db_files))]) clear_mpd_led() return self.playlist_action('append', plname, add) return 'Unknown command ' + cmd def search_file(self, arg, limit=500): """ Search in MPD data base using 'any' and 'file' tag. :param arg: search pattern :param limit: max amount of results :return: {status: '', error: '', result: [title, artist, album, length, '', filename, rating]} Dummy element added at position #4 to have filename at position #5 """ logger = PbLogger('PROFILE MPD') if arg is None or len(arg) < 3: return { 'error_str': 'Search pattern must contain at least 3 characters!' } self.ensure_connected() result = [] # Search for first word and filter results later. # MPD search does not support AND for multiple words. first_arg = arg.split(' ')[0] other_args = [s.lower() for s in arg.split(' ')[1:] if len(s)] try: raise_mpd_led() search = self.client.search('any', first_arg) search += self.client.search('file', first_arg) clear_mpd_led() except CommandError as e: return {'error_str': 'Command error in search: %s' % e} logger.print_step('search init done.') has_files = [] for item in search: if 'file' not in item: continue if item['file'] in has_files: continue has_files.append(item['file']) # Filter for remaining args. if len(other_args): # Generate string of all values in search item to check for search terms. match_list = [value for key, value in item.items()] try: match = ''.join(match_list).lower() except TypeError: # There are arrays inside the results.... Bad thing! match_list = [i for sublist in match_list for i in sublist] match = ''.join(match_list).lower() # Check remaining patterns valid = True for check in other_args: if check not in match: valid = False if not valid: continue res = [] res.append(save_title(item)) res.append(save_item(item, 'artist')) res.append(save_item(item, 'album')) length = time.strftime( "%M:%S", time.gmtime(int(item['time']) if 'time' in item else 0)) res.append(length) res.append('') # dummy to push file to pos #5 res.append(item['file']) res.append(0) # ratings placeholder result.append(res) logger.print_step('search items filtered.') # truncate to N results trunc_res = result[:limit] self.truncated = 0 if len(result) > limit: self.truncated = len(result) - limit trunc_str = '(truncated)' if self.truncated else '' # query all ratings at once raise_sql_led() files = sorted(set([x[5] for x in trunc_res])) q = Rating.objects.filter(Q(path__in=files)).values('path', 'rating').all() rat_d = dict([(x['path'], x['rating']) for x in q]) clear_sql_led() for item in trunc_res: item[6] = rat_d[item[5]] if item[5] in rat_d else 0 logger.print_step('search SQL done.') logger.print('search() done.') return { 'status_str': '%d items found %s' % (len(result), trunc_str), 'search': trunc_res, 'truncated': self.truncated } def playlists_action(self, cmd, plname, payload): """Perform actions on list of playlists. :param cmd: [clear, delete, list, moveend, new, load,rename, saveas, info] :param plname: name of playlist :param payload: array of payload data for command :return: dict including error or status message. """ self.ensure_connected() if cmd == 'clear': self.client.playlistclear(plname) flash_mpd_led() return {'status_str': 'Playlist %s cleared' % plname} if cmd == 'delete': positions = sorted([int(i) for i in payload], reverse=True) for pos in positions: self.client.playlistdelete(plname, pos) flash_mpd_led() return { 'status_str': '%d items removed from playlist %s' % (len(positions), plname) } if cmd == 'list': pls = sorted([ i['playlist'] for i in self.client.listplaylists() if 'playlist' in i ]) return {'pls': pls} if cmd == 'moveend': pl_len = len(self.client.listplaylist(plname)) positions = sorted([int(i) for i in payload], reverse=True) for pos in positions: self.client.playlistmove(plname, pos, pl_len - 1) flash_mpd_led() return { 'status_str': '%d items moved to end in playlist %s' % (len(positions), plname) } if cmd == 'new': if plname in [ i['playlist'] for i in self.client.listplaylists() if 'playlist' in i ]: return { 'error_str': 'Playlist %s exists' % plname, 'plname': '' } self.client.save(plname) self.client.playlistclear(plname) flash_mpd_led() return { 'status_str': 'Playlist %s created' % plname, 'plname': plname } if cmd == 'load': self.client.load(plname) flash_mpd_led() return {'status_str': 'Playlist %s added to playlist' % plname} if cmd == 'rename': plname_old = payload[0] if plname in [ i['playlist'] for i in self.client.listplaylists() if 'playlist' in i ]: return {'error_str': 'Playlist %s already exists.' % plname} self.client.rename(plname_old, plname) flash_mpd_led() return { 'status_str': 'Playlist %s renamed to %s' % (plname_old, plname) } if cmd == 'rm': self.client.rm(plname) flash_mpd_led() return {'status_str': 'Playlist %s removed' % plname} if cmd == 'saveas': if plname in [ i['playlist'] for i in self.client.listplaylists() if 'playlist' in i ]: return {'error_str': 'Playlist %s already exists.' % plname} self.client.save(plname) flash_mpd_led() return {'status_str': 'Current playlist saved to %s.' % plname} if cmd == 'info': return self.get_playlist_info(plname) return {'error_str': 'No such command: %s' % cmd} def get_playlist_info(self, plname): """Fetch full byte size and length in seconds for specific playlist form Ratings table. :param plname: name of playlist in MPD database :return: {itmes: N, time: SECONDS, bytes: BYTES} """ res = dict(items=0, time=0, bytes=0, misses=list()) self.ensure_connected() try: if plname == '': info = self.client.playlistinfo() else: info = self.client.listplaylistinfo(plname) except CommandError: return res pl_files = [x['file'] for x in info] q = Rating.objects.filter(Q(path__in=pl_files)).values( 'length', 'filesize', 'path').all() times = 0 bytes = 0 for x in q: times += x['length'] bytes += x['filesize'] db_files = [x['path'] for x in q] miss = [x for x in pl_files if x not in db_files] return dict(items=len(q), time=times, bytes=bytes, mpd_items=len(info), misses=miss) def list_by(self, what, in_ratings, in_dates, in_genres, in_artists, in_albums, file_mode=False): """Create content data for browse view. :param what: category of results [date, genre, artist, album, song] :param in_ratings: list of ratings for filter ['All'] for all ratings :param in_dates: list of dates for filter ['All'] for all dates :param in_genres: list of genres for filter ['All'] for all :param in_artists: list of artists for filter ['All'] for all :param in_albums: list of albums for filter ['All'] for all :param file_mode: return result as file-list (required for seed_by()) :return: List of results for browse view for next category: if what == 'genre' results will be artists and so on. """ logger = PbLogger('PROFILE MPD') self.ensure_connected() seek = 'file' if file_mode or what == 'song' else what ratings_avail = { 'All': [0, 1, 2, 3, 4, 5], '5': [5], 'at least 4': [4, 5], 'at least 3': [3, 4, 5], 'at least 2': [2, 3, 4, 5], 'at least 1': [1, 2, 3, 4, 5], 'exactly 4': [4], 'exactly 3': [3], 'exactly 2': [2], 'exactly 1': [1], 'unrated': [0] } if what == 'rating': if seek != 'file': return [ 'All', '5', 'at least 4', 'at least 3', 'at least 2', 'at least 1', 'exactly 4', 'exactly 3', 'exactly 2', 'exactly 1', 'unrated' ] else: return self.client.list(seek) # unroll ratings ratings = [] if len(in_ratings) > 0 and in_ratings[0] != 'All': for rating in in_ratings: ratings += ratings_avail[rating] ratings = sorted(set(ratings)) # Unroll special dates (decades like '1971-1980' or '2010-today') dates = [] if len(in_dates) > 0 and in_dates[0] != 'All': for date in in_dates: if '-' in date: m = re.match(r'(\d+)-(\d+)', date.replace('today', '2020')) if m: for y in range(int(m.group(1)), int(m.group(2)) + 1): dates.append(y) else: dates.append(int(date)) raise_sql_led() q = Rating.objects.all().order_by('path') logger.print_step('list_by: SQL select all') if len(ratings) > 0: q = q.filter(rating__in=ratings) logger.print_step('list_by: ratings filtered') if what in ['genre', 'artist', 'album', 'song'] and len(dates) > 0: q = q.filter(date__in=dates) logger.print_step('list_by: dates filtered') if what in ['artist', 'album', 'song' ] and len(in_genres) > 0 and in_genres[0] != 'All': q = q.filter(genre__in=in_genres) logger.print_step('list_by: genres filtered') if what in ['album', 'song' ] and len(in_artists) > 0 and in_artists[0] != 'All': q = q.filter(artist__in=in_artists) logger.print_step('list_by: artists filtered') if what in ['song'] and len(in_albums) > 0 and in_albums[0] != 'All': q = q.filter(album__in=in_albums) logger.print_step('list_by: albums filtered') clear_sql_led() res = [] if file_mode: res = [x.path for x in q] if what == 'date': q2 = q.order_by('date').distinct('date') res = [x.date for x in q2] if what == 'genre': q2 = q.order_by('genre').distinct('genre') res = [x.genre for x in q2] if what == 'artist': q2 = q.order_by('artist').distinct('artist') res = [x.artist for x in q2] if what == 'album': q2 = q.order_by('album').distinct('album') res = [x.album for x in q2] if what == 'song': for x in q: if x.artist != '': res.append([x.path, x.artist + ' - ' + x.title, x.rating]) else: res.append([x.path, x.title, x.rating]) logger.print('list_by() done.') return res def seed_by(self, count, plname, what, ratings, dates, genres, artists, albums): """Random add items to playlist from browse view. :param count: number of items to add :param plname: playlist name ('' for current) :param what: [date, genre, artist, album, song] :param ratings: see list_by() :param dates: see list_by() :param genres: see list_by() :param artists: see list_by() :param albums: see list_by() :return: status string. """ files = self.list_by(what, ratings, dates, genres, artists, albums, file_mode=True) if len(files) == 0: return 'Zero results, nothing added.' if len(files) < count: return self.playlist_action('append', plname, files) random.seed() add = [] for i in range(count): add.append(files[random.randrange(0, len(files))]) return self.playlist_action('append', plname, add) def get_m3u(self, source, name): """Return list uris to save as m3u file :param source: one of [current, saved, history] :param name: name of saved playlist or date for history :return: ['/path/to/mp31.mp3', '/path/to/next.ogg', ...] """ res = [] client = MPDClient() client.timeout = 10 try: client.connect(settings.PB_MPD_SOCKET, 0) path_prefix = client.config() except ConnectionError: print("ERROR: CONNECT SOCKET") return dict(error_str='Failed to connect to MPD socket!', data=[]) except CommandError: print("ERROR: COMMAND SOCKET") return dict(error_str='Failed to connect to MPD socket!', data=[]) self.ensure_connected() if source == 'current': items = self.client.playlistinfo() res = [os.path.join(path_prefix, x['file']) for x in items] elif source == 'saved': try: items = self.client.listplaylistinfo(name) res = [os.path.join(path_prefix, x['file']) for x in items] except CommandError: return dict(error_str='Playlist not found: ' + name, data=[]) elif source == 'history': items = History.get_history(name) res = [os.path.join(path_prefix, x[5]) for x in items] return dict(status_str='Downloading %s playlist with %d items' % (source, len(res)), data=res, prefix=path_prefix)
def play_MPD(path): """ Joue MPD avec comme argument le chemin du fichier à jouer """ client = MPDClient() # create client object client.timeout = 10 # network timeout in seconds (floats allowed), default: None client.idletimeout = None client.connect("localhost", 6600) # connect to localhost:6600 MPDClient.add(path) client.play(0) print MPDClient.playlistinfo()
def playsong(id): client.stop() client.clear() #print(id) #print(thisdict) #if id does not exist, then music playback stops if id in thisdict: trackid = thisdict[id] track = "spotify:track:" + trackid print(track) client.add(track) client.play() client = MPDClient() # create client object client.timeout = 10 # network timeout in seconds (floats allowed), default: None client.idletimeout = None # timeout for fetching the result of the idle command is handled seperately, default: None client.connect("192.168.1.242", 6600) # connect to localhost:6600 print(client.mpd_version) # print the MPD version print(client.find( "any", "spillebillen")) # print result of the command "find any house" client.clear() client.setvol(20) playing = True while playing == True: time.sleep(0.1) try: id, text = reader.read()
def main(): global oMpdClient print('[MPD] Initializing MPD client') oMpdClient = MPDClient() oMpdClient.timeout = None # network timeout in seconds (floats allowed), default: None oMpdClient.idletimeout = None # timeout for fetching the result of the idle command is handled seperately, default: None oMpdClient.connect("localhost", 6600) # connect to localhost:6600 print(oMpdClient.mpd_version) # print the MPD version #Now handled via udisks dbus: #print('[MPD-DBUS] Subscribing to channel: media_ready') #oMpdClient.subscribe("media_ready") #Now handled via udisks dbus: #print('[MPD-DBUS] Subscribing to channel: media_removed') #oMpdClient.subscribe("media_removed") #Workaround for not having NetworkManager: # post-up script defined in /etc/network/interface print('[MPD] Subscribing to channel: ifup') oMpdClient.subscribe("ifup") #Workaround for not having NetworkManager: # post-down script defined in /etc/network/interface print('[MPD] Subscribing to channel: ifdown') oMpdClient.subscribe("ifdown") print('[MPD] send_idle()') oMpdClient.send_idle() while True: canRead = select([oMpdClient], [], [], 0)[0] if canRead: # fetch change(s) changes = oMpdClient.fetch_idle() # handle/parse the change(s) mpd_handle_change(changes) # don't pass on the changes (datatype seems too complicated for dbus) #mpd_control(changes) # continue idling oMpdClient.send_idle() # required????? time.sleep(0.1)
import RPi.GPIO as GPIO import time import mpd from mpd import MPDClient import serial import os import sys # Open port to LCD terminal (fixme: need to specify or discover) lcd = serial.Serial('/dev/ttyUSB0', 9600) time.sleep(2) lcd.write("\fRadioPi starting ...") # Open connection to mpd mpdc = MPDClient() mpdc.timeout = 10 mpdc.idletimeout = None mpdc.connect("localhost", 6600) mpdConnected = True mpdLock = False # Initialise GPIO for the rotary encoder encoderA = 23 # BCM no. of Encoder 'A' encoderB = 24 # BCM no. of Encoder 'B' encoderD = 25 # BCM no. of Encoder 'D' (switch) GPIO.setmode(GPIO.BCM) GPIO.setup(encoderA, GPIO.IN, pull_up_down=GPIO.PUD_UP) GPIO.setup(encoderB, GPIO.IN, pull_up_down=GPIO.PUD_UP)
def conToMpd(): con = MPDClient() con.timeout = 10 con.idletimeout = None con.connect("localhost", 6600) return con
def __init__(self, host, port, password=None, use_unicode=True): self.host = host self.port = port self.password = password self.use_unicode = use_unicode self.client = MPDClient(use_unicode)
def main(): global rtspClient global playlistUpdater global logger triggered = False last_triggered = time.time() logger.setLevel(logging.DEBUG) console_handler = logging.StreamHandler() logger.addHandler(console_handler) logger.debug("Kitchenmusique -- starting...") playlistUpdater.register_providers_from_config() playlistThread.start() neural_net = detect.PersonDetector() rtspClient = detect.RtspClient() rtspClient.connect(config.CONFIG_RTSP_URL) while True: try: image = rtspClient.get_image() if image is None: time.sleep(0.3) continue descriptions = neural_net.process(image, False) except Exception: continue matches = list( filter(lambda x: x.classid in config.CONFIG_YOLO_TRIGGER_CLASSES, descriptions)) accepted = list( filter( lambda x: x.confidence > config. CONFIG_YOLO_CONFIDENCE_THRESHOLD, matches)) if len(accepted) > 0: logger.info("Trigger class presence detected!") last_triggered = time.time() if not triggered: triggered = True client = MPDClient() client.timeout = 10 client.idletimeout = None logger.debug("Connecting to MPD at {0}:{1}".format( config.CONFIG_MPD_HOST, config.CONFIG_MPD_PORT)) # connect to MPD try: client.connect(config.CONFIG_MPD_HOST, config.CONFIG_MPD_PORT) except SocketError: logger.error("MPD connection failed") # authenticate if we have password enabled if config.CONFIG_MPD_USE_PASSWORD: try: client.password(config.CONFIG_MPD_PASSWORD) except CommandError: logger.error( "MPD password authentication failed, exiting") # finally, play music if client.status()['state'] != 'play': client.play() elif triggered and time.time( ) - last_triggered > config.CONFIG_DEACTIVATION_TIME: triggered = False client = MPDClient() client.timeout = 10 client.idletimeout = None logger.debug("Connecting to MPD at {0}:{1}".format( config.CONFIG_MPD_HOST, config.CONFIG_MPD_PORT)) # connect to MPD try: client.connect(config.CONFIG_MPD_HOST, config.CONFIG_MPD_PORT) except SocketError: logger.error("MPD connection failed") # authenticate if we have password enabled if config.CONFIG_MPD_USE_PASSWORD: try: client.password(config.CONFIG_MPD_PASSWORD) except CommandError: logger.error("MPD password authentication failed, exiting") if client.status()['state'] == 'play': client.stop() logger.info("Kitchenmusique -- exiting successfully") exit_handler() return True
class MPDConnection: def __init__(self, host, port, password=None, use_unicode=True): self.host = host self.port = port self.password = password self.use_unicode = use_unicode self.client = MPDClient(use_unicode) def connect(self): try: self.client.connect(self.host, self.port) except IOError as err: errno, errstr = err raise ArtgetError("Could not connect to '%s' : %s" % (self.host, errstr)) except MPDError as e: raise ArtgetError("Could not connect to '%s' : %s" % (self.host, e)) if self.password: try: self.client.password(self.password) except CommandError as e: raise ArtgetError("Could not connect to '%s' : " "password command failed: %s" % (self.host, e)) except (MPDError, IOError) as e: raise ArtgetError("Could not connect to '%s' : " "password command failed: %s" % (self.host, e)) def disconnect(self): try: self.client.close() except (MPDError, IOError): # Don't worry, just ignore it, disconnect pass try: self.client.disconnect() except (MPDError, IOError): # Now this is serious. This should never happen. # The client object should not be trusted to be re-used. self.client = MPDClient(self.use_unicode) def current_song(self): try: song = self.client.currentsong() except (MPDError, IOError): # Try reconnecting and retrying self.disconnect() try: self.connect() except ArtgetError as e: raise ArtgetError("Reconnecting failed: %s" % e) try: song = self.client.currentsong() except (MPDError, IOError) as e: # Failed again, just give up. raise ArtgetError("Couldn't retrieve current song: %s" % e) if song == {}: raise ArtgetError("No song is playing on MPD") self.song = song def procedure(self): self.connect() self.current_song() self.disconnect()
class TakayamaMpdClient: def __init__(self): self.client = MPDClient() self.client = MPDClient() self.client.timeout = 10 self.client.idletimeout = None self.client.connect("127.0.0.1", 9009) def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): self.client.close() self.client.disconnect() def clear_playlist(self): self.client.clear() def add_tracks_by_artist(self, artist, track_name): artist = re.sub(r'^The ', '', artist) artist = TakayamaMpdClient.mpd_quote(artist) track_name = TakayamaMpdClient.mpd_quote(track_name) search_string = '((artist =~ \".*' + artist + '.*\") AND (title =~ \".*' + track_name + '.*\"))' count = len(self.client.search(search_string)) if count == 0: print('No ' + artist + ' - ' + track_name + ' in library!') return if count > 2: print('WTF request with ' + str(count) + ' results => ' + search_string) self.client.searchadd(search_string) @staticmethod def mpd_quote(s): return s\ .replace('(', r'.')\ .replace(')', '.')\ .replace(':', '.')\ .replace('/', '.')\ .replace('[', '.')\ .replace(']', '.')\ .replace("'", '.')
#!/usr/bin/env python # -*- coding: utf-8 -*- from mpd import (MPDClient) def cleanup(): client.stop() # stop playing client.clear() # clear queue client.disconnect() # disconnect from mpd # use_unicode will enable the utf-8 mode for python2 # see http://pythonhosted.org/python-mpd2/topics/advanced.html#unicode-handling client = MPDClient(use_unicode=True) client.connect("localhost", 6600) print "mpd connected!" client.clear() # clear queue # print client.commands() # list der Kommandos auf die wir zugriff haben songId = client.addid( 'Captain Future/Originalmusik aus der TV-Serie von Christian Bruhn/01_Captain Future.mp3', 0) print "Song ID: {}".format(songId) print "Playlist: {}".format(client.playlist()) client.play() try: raw_input("Press Enter to Stop") except KeyboardInterrupt:
#Set colour of background BACKGROUND_COLOUR = (31, 16, 0) # Fonts and media FONTLCD = '/usr/share/fonts/truetype/digital7/digital-7.ttf' FONTLCDITALIC = '/usr/share/fonts/truetype/digital7/digital-7 (italic).ttf' FONTDROID = '/usr/share/fonts/truetype/droid/DroidSans.ttf' FONTFUTURA = '/usr/share/fonts/truetype/futura/Futura-Medium.ttf' FONTFUTURAITALIC = '/usr/share/fonts/truetype/futura/Futura-MediumItalic.ttf' MEDIA_FILES = '/home/pi/tutorials/pygamelcd/' # ---- MPD CLIENT SETUP ----# client = MPDClient() # create client object client.timeout = 10 # network timeout in seconds (floats allowed) client.idletimeout = None # timeout for fetching client.connect("localhost", 6600) # connect to localhost:6600 # --- STATIC IMAGES ---# # Progress bar progress_bar = pygame.image.load(os.path.join(MEDIA_FILES, 'progress_bar.png')) progress_bar_rect = progress_bar.get_rect() progress_bar_rect.x = 16 progress_bar_rect.y = 210 # ---- FUNCTIONS ----#
from mpd import MPDClient client = MPDClient() # create client object client.timeout = 10 # network timeout in seconds (floats allowed), default: None client.idletimeout = None # timeout for fetching the result of the idle command is handled seperately, default: None client.connect("localhost", 6600) # connect to localhost:6600 print(client.mpd_version) # print the MPD version print(client.listallinfo()) # print result of the command "find any house" client.close() # send the close command client.disconnect()
from mpd import MPDClient client = MPDClient() client.connect("localhost", 6600) song = client.currentsong() status = client.status() state_to_icon = {"play": " ", "pause": " ", "stop": " "} if status["state"] != "stop": status_line = state_to_icon[status["state"]] + song["title"] status_line_long = status_line else: status_line = state_to_icon[status["state"]] status_line_long = status_line print(status_line_long) print(status_line) print("")
class RaspDac_Display: def __init__(self): logging.debug("RaspDac_Display Initializing") self.tempreadexpired = 0 self.diskreadexpired = 0 self.ratereadexpired = 0 # used with Redis to try to figure out how long the song has been playing self.timesongstarted = 0 self.currentsong = "" self.currentelapsed = 0 self.tempc = 0.0 self.tempf = 0.0 self.avail = 0 self.availp = 0 self.rate = 0 # Initilize the connections to the music Daemons. Currently supporting # MPD and SPOP (for Spotify) ATTEMPTS=3 # Will try to connect multiple times global RUNE_ENABLED if RUNE_ENABLED: # This tries to pull in the redis module which is only used right now for RuneAudio. # If it is not present, REDIS will be disabled try: import redis for i in range (1,ATTEMPTS): try: # Try to connect to REDIS service self.redisclient = redis.Redis(REDIS_SERVER, REDIS_PORT, REDIS_PASSWORD) break except: time.sleep(2) else: # After the alloted number of attempts did not succeed in connecting logging.warning("Unable to connect to REDIS service on startup") except ImportError: logging.warning("Redis requested but module not found.") RUNE_ENABLED = False if MPD_ENABLED: for i in range (1,ATTEMPTS): self.client = MPDClient(use_unicode=True) try: # Connect to the MPD daemon self.client.connect(MPD_SERVER, MPD_PORT) break except: time.sleep(2) else: # After the alloted number of attempts did not succeed in connecting logging.warning("Unable to connect to MPD service on startup") if SPOP_ENABLED: # Now attempting to connect to the Spotify daemon # This may fail if Spotify is not configured. That's ok! for i in range (1,ATTEMPTS): try: self.spotclient = telnetlib.Telnet(SPOP_SERVER,SPOP_PORT) self.spotclient.read_until("\n") break except: time.sleep(2) else: # After the alloted number of attempts did not succeed in connecting logging.warning("Unable to connect to Spotify service on startup") if LMS_ENABLED: for i in range (1,ATTEMPTS): try: # Connect to the LMS daemon self.lmsserver = pylms.server.Server(LMS_SERVER, LMS_PORT, LMS_USER, LMS_PASSWORD) self.lmsserver.connect() # Find correct player players = self.lmsserver.get_players() for p in players: ### Need to find out how to get the MAC address from player if p.get_ref() == LMS_PLAYER: self.lmsplayer = p break if self.lmsplayer is None: self.lmsplayer = self.lmsserver.get_players()[0] if self.lmsplayer is None: raise Exception('Could not find any LMS player') break except (socket_error, AttributeError, IndexError): logging.debug("Connect attempt {0} to LMS server failed".format(i)) time.sleep(2) else: # After the alloted number of attempts did not succeed in connecting logging.warning("Unable to connect to LMS service on startup") global STATUSLOGGING if STATUSLOGGING: try: self.statusfile = open(STATUSLOGFILE, 'a') except: logging.warning("Status data logging requested but could not open {0}".format(STATUSLOGFILE)) STATUSLOGGING = False def status_redis(self): # Try to get status from MPD daemon try: r_status = json.loads(self.redisclient.get('act_player_info')) except: # Attempt to reestablish connection to daemon try: self.redisclient = redis.Redis(REDIS_SERVER, REDIS_PORT, REDIS_PASSWORD) r_status = json.loads(self.redisclient.get('act_player_info')) except: logging.debug("Could not get status from REDIS daemon") return { 'state':u"stop", 'artist':u"", 'title':u"", 'album':u"", 'current':0, 'remaining':u"", 'duration':0, 'position':u"", 'volume':0, 'playlist_display':u"", 'playlist_position':0, 'playlist_count':0, 'bitrate':u"", 'type':u"" } state = r_status.get('state') if state == "play": artist = r_status.get('currentartist') title = r_status.get('currentsong') album = r_status.get('currentalbum') volume = int(r_status.get('volume')) actPlayer = r_status.get('actPlayer') duration = int(r_status.get('time')) # if transitioning state from stopped to playing if self.timesongstarted == 0: self.currentelapsed = int(r_status['elapsed']) current = self.currentelapsed self.timesongstarted = time.time() - current self.currentsong = title else: # Are we still playing the same title? if self.currentsong == title: # Did elapsed change? This can happen if someone fast forwards the song, etc. if self.currentelapsed != int(r_status['elapsed']): self.currentelapsed = int(r_status['elapsed']) current = self.currentelapsed self.timesongstarted = time.time() - current else: # if not continue to estimate current = int(time.time() - self.timesongstarted) else: self.currentelapsed = int(r_status['elapsed']) current = self.currentelapsed self.timesongstarted = time.time() - current self.currentsong = title if actPlayer == 'Spotify': bitrate = "320 kbps" playlist_position = int(r_status.get('song'))+1 playlist_count = int(r_status.get('playlistlength')) playlist_display = "{0}/{1}".format(playlist_position, playlist_count) tracktype = "Spotify" elif actPlayer == 'MPD': playlist_position = int(r_status.get('song'))+1 playlist_count = int(r_status.get('playlistlength')) bitrate = "{0} kbps".format(r_status.get('bitrate')) # if radioname is None then this is coming from a playlist (e.g. not streaming) if r_status['radioname'] == None: playlist_display = "{0}/{1}".format(playlist_position, playlist_count) else: playlist_display = "Streaming" # if artist is empty, place radioname in artist field if artist is None: artist = r_status['radioname'] try: audio = r_status['audio'].split(':') if len(audio) == 3: sample = round(float(audio[0])/1000,1) bits = audio[1] if audio[2] == '1': channels = 'Mono' elif audio[2] == '2': channels = 'Stereo' elif int(audio[2]) > 2: channels = 'Multi' else: channels = u"" if channels == u"": tracktype = "{0} bit, {1} kHz".format(bits, sample) else: tracktype = "{0}, {1} bit, {2} kHz".format(channels, bits, sample) else: # If audio information not available just send that MPD is the source tracktype = u"MPD" except KeyError: tracktype = u"MPD" elif actPlayer == 'Airplay': playlist_position = 1 playlist_count = 1 bitrate = "" tracktype = u"Airplay" playlist_display = "Streaming" else: # Unexpected player type logging.debug("Unexpected player type {0} discovered".format(actPlayer)) playlist_position = 1 playlist_count = 1 bitrate = "" tracktype = actPlayer playlist_display = "Streaming" # since we are returning the info as a JSON formatted return, convert # any None's into reasonable values if artist is None: artist = u"" if title is None: title = u"" if album is None: album = u"" if current is None: current = 0 if volume is None: volume = 0 if bitrate is None: bitrate = u"" if tracktype is None: tracktype = u"" if duration is None: duration = 0 # if duration is not available, then suppress its display if int(duration) > 0: timepos = time.strftime("%M:%S", time.gmtime(int(current))) + "/" + time.strftime("%M:%S", time.gmtime(int(duration))) remaining = time.strftime("%M:%S", time.gmtime( int(duration) - int(current) ) ) else: timepos = time.strftime("%M:%S", time.gmtime(int(current))) remaining = timepos return { 'state':u"play", 'artist':artist, 'title':title, 'album':album, 'remaining':remaining, 'current':current, 'duration':duration, 'position':timepos, 'volume':volume, 'playlist_display':playlist_display, 'playlist_position':playlist_position, 'playlist_count':playlist_count, 'bitrate':bitrate, 'type':tracktype } else: self.timesongstarted = 0 return { 'state':u"stop", 'artist':u"", 'title':u"", 'album':u"", 'remaining':u"", 'current':0, 'duration':0, 'position':u"", 'volume':0, 'playlist_display':u"", 'playlist_position':u"", 'playlist_count':0, 'bitrate':u"", 'type':u""} def status_mpd(self): # Try to get status from MPD daemon try: m_status = self.client.status() m_currentsong = self.client.currentsong() playlist_info = self.client.playlistinfo() except: # Attempt to reestablish connection to daemon try: self.client.connect(MPD_SERVER, MPD_PORT) m_status=self.client.status() m_currentsong = self.client.currentsong() playlist_info = self.client.playlistinfo() except: logging.debug("Could not get status from MPD daemon") return { 'state':u"stop", 'artist':u"", 'title':u"", 'album':u"", 'current':0, 'remaining':u"", 'duration':0, 'position':u"", 'volume':0, 'playlist_display':u"", 'playlist_position':0, 'playlist_count':0, 'bitrate':u"", 'type':u"" } state = m_status.get('state') if state == "play": artist = m_currentsong.get('artist') name = m_currentsong.get('name') # Trying to have something to display. If artist is empty, try the # name field instead. if artist is None: artist = name title = m_currentsong.get('title') album = m_currentsong.get('album') playlist_position = int(m_status.get('song'))+1 playlist_count = int(m_status.get('playlistlength')) volume = int(m_status.get('volume')) # MPDs rate data changes continuously. # To prevent the screen from unnecessarily refreshing limit updates to every 20 seconds if self.ratereadexpired < time.time(): self.ratereadexpired = time.time() + 20 self.bitrate = "{0} kbps".format(m_status.get('bitrate')) try: audio = m_status['audio'].split(':') if len(audio) == 3: sample = round(float(audio[0])/1000,1) bits = audio[1] if audio[2] == '1': channels = 'Mono' elif audio[2] == '2': channels = 'Stereo' elif int(audio[2]) > 2: channels = 'Multi' else: channels = u"" if channels == u"": tracktype = "{0} bit, {1} kHz".format(bits, sample) else: tracktype = "{0}, {1} bit, {2} kHz".format(channels, bits, sample) else: # If audio information not available just send that MPD is the source tracktype = u"MPD" except KeyError: tracktype = u"" (current, duration) = (m_status.get('time').split(":")) # since we are returning the info as a JSON formatted return, convert # any None's into reasonable values if artist is None: artist = u"" if title is None: title = u"" if album is None: album = u"" if current is None: current = 0 if volume is None: volume = 0 if self.bitrate is None: self.bitrate = u"" if tracktype is None: tracktype = u"" if duration is None: duration = 0 # if duration is not available, then suppress its display if int(duration) > 0: timepos = time.strftime("%M:%S", time.gmtime(int(current))) + "/" + time.strftime("%M:%S", time.gmtime(int(duration))) remaining = time.strftime("%M:%S", time.gmtime( int(duration) - int(current) ) ) else: timepos = time.strftime("%M:%S", time.gmtime(int(current))) remaining = timepos # If playlist is length 1 and the song playing is from an http source it is streaming if playlist_count == 1: if playlist_info[0]['file'][:4] == "http": playlist_display = "Streaming" else: playlist_display = "{0}/{1}".format(playlist_position, playlist_count) else: playlist_display = "{0}/{1}".format(playlist_position, playlist_count) return { 'state':u"play", 'artist':artist, 'title':title, 'album':album, 'remaining':remaining, 'current':current, 'duration':duration, 'position':timepos, 'volume':volume, 'playlist_display':playlist_display, 'playlist_position':playlist_position, 'playlist_count':playlist_count, 'bitrate':self.bitrate, 'type':tracktype } else: return { 'state':u"stop", 'artist':u"", 'title':u"", 'album':u"", 'remaining':u"", 'current':0, 'duration':0, 'position':u"", 'volume':0, 'playlist_display':u"", 'playlist_position':u"", 'playlist_count':0, 'bitrate':u"", 'type':u""} def status_spop(self): # Try to get status from SPOP daemon try: self.spotclient.write("status\n") spot_status_string = self.spotclient.read_until("\n").strip() except: # Try to reestablish connection to daemon try: self.spotclient = telnetlib.Telnet(SPOP_SERVER,SPOP_PORT) self.spotclient.read_until("\n") self.spotclient.write("status\n") spot_status_string = self.spotclient.read_until("\n").strip() except: logging.debug("Could not get status from SPOP daemon") return { 'state':u"stop", 'artist':u"", 'title':u"", 'album':u"", 'current':0, 'remaining':u"", 'duration':0, 'position':u"", 'volume':0, 'playlist_display':u"", 'playlist_position':0, 'playlist_count':0, 'bitrate':u"", 'type':u""} spot_status = json.loads(spot_status_string) if spot_status.get('status') == "playing": artist = spot_status.get('artist') title = spot_status.get('title') album = spot_status.get('album') current = spot_status.get('position') duration = spot_status.get('duration') playlist_position = spot_status.get('current_track') playlist_count = spot_status.get('total_tracks') # SPOP doesn't seem to have bitrate, track type, or volume available bitrate = u"" tracktype = u"" volume = 0 # since we are returning the info as a JSON formatted return, convert # any None's into reasonable values if artist is None: artist = u"" if title is None: title = u"" if album is None: album = u"" if current is None: current = 0 if volume is None: volume = 0 if bitrate is None: bitrate = u"" if tracktype is None: tracktype = u"" if duration is None: duration = 0 else: # The spotify client returns time in 1000's of a second # Need to adjust to seconds to be consistent with MPD duration = duration / 1000 # if duration is not available, then suppress its display if int(duration) > 0: timepos = time.strftime("%M:%S", time.gmtime(int(current))) + "/" + time.strftime("%M:%S", time.gmtime(int(duration))) remaining = time.strftime("%M:%S", time.gmtime(int(duration) - int(current) ) ) else: timepos = time.strftime("%M:%S", time.gmtime(int(current))) remaining = timepos playlist_display = "{0}/{1}".format(playlist_position, playlist_count) return { 'state':u"play", 'artist':artist, 'title':title, 'album':album, 'remaining':remaining, 'current':current, 'duration':duration, 'position':timepos, 'volume':volume, 'playlist_display':playlist_display, 'playlist_position':playlist_position, 'playlist_count':playlist_count, 'bitrate':bitrate, 'type':tracktype } else: return { 'state':u"stop", 'artist':u"", 'title':u"", 'album':u"", 'remaining':u"", 'current':0, 'duration':0, 'position':u"", 'volume':0, 'playlist_display':u"", 'playlist_position':0, 'playlist_count':0, 'bitrate':u"", 'type':u""} def status_lms(self): # Try to get status from LMS daemon try: lms_status = self.lmsplayer.get_mode() except: # Try to reestablish connection to daemon try: self.lmsserver = pylms.server.Server(LMS_SERVER, LMS_PORT, LMS_USER, LMS_PASSWORD) self.lmsserver.connect() # Find correct player players = self.lmsserver.get_players() for p in players: ### Need to find out how to get the MAC address from player if p.get_ref() == LMS_PLAYER: self.lmsplayer = p break if self.lmsplayer is None: self.lmsplayer = self.lmsserver.get_players()[0] if self.lmsplayer is None: raise Exception('Could not find any LMS player') lms_status = self.lmsplayer.get_mode() except (socket_error, AttributeError, IndexError): logging.debug("Could not get status from LMS daemon") return { 'state':u"stop", 'artist':u"", 'title':u"", 'album':u"", 'remaining':u"", 'current':0, 'duration':0, 'position':u"", 'volume':0, 'playlist_display':u"", 'playlist_position':0, 'playlist_count':0, 'bitrate':u"", 'type':u"", 'current_time':u""} if lms_status == "play": import urllib artist = urllib.unquote(str(self.lmsplayer.request("artist ?", True))).decode('utf-8') title = urllib.unquote(str(self.lmsplayer.request("title ?", True))).decode('utf-8') album = urllib.unquote(str(self.lmsplayer.request("album ?", True))).decode('utf-8') playlist_position = int(self.lmsplayer.request("playlist index ?"))+1 playlist_count = self.lmsplayer.playlist_track_count() volume = self.lmsplayer.get_volume() current = self.lmsplayer.get_time_elapsed() duration = self.lmsplayer.get_track_duration() url = self.lmsplayer.get_track_path() # Get bitrate and tracktype if they are available. Try blocks used to prevent array out of bounds exception if values are not found try: bitrate = urllib.unquote(str(self.lmsplayer.request("songinfo 2 1 url:"+url+" tags:r", True))).decode('utf-8').split("bitrate:", 1)[1] except: bitrate = u"" try: tracktype = urllib.unquote(str(self.lmsplayer.request("songinfo 2 1 url:"+url+" tags:o", True))).decode('utf-8').split("type:",1)[1] except: tracktype = u"" playlist_display = "{0}/{1}".format(playlist_position, playlist_count) # If the track count is greater than 1, we are playing from a playlist and can display track position and track count if self.lmsplayer.playlist_track_count() > 1: playlist_display = "{0}/{1}".format(playlist_position, playlist_count) # if the track count is exactly 1, this is either a short playlist or it is streaming elif self.lmsplayer.playlist_track_count() == 1: try: # if streaming if self.lmsplayer.playlist_get_info()[0]['duration'] == 0.0: playlist_display = "Streaming" # it really is a short playlist else: playlist_display = "{0}/{1}".format(playlist_position, playlist_count) except KeyError: logging.debug("In LMS couldn't get valid track information") playlist_display = u"" else: logging.debug("In LMS track length is <= 0") playlist_display = u"" # since we are returning the info as a JSON formatted return, convert # any None's into reasonable values if artist is None: artist = u"" if title is None: title = u"" if album is None: album = u"" if current is None: current = 0 if volume is None: volume = 0 if bitrate is None: bitrate = u"" if tracktype is None: tracktype = u"" if duration is None: duration = 0 # if duration is not available, then suppress its display if int(duration) > 0: timepos = time.strftime("%M:%S", time.gmtime(int(current))) + "/" + time.strftime("%M:%S", time.gmtime(int(duration))) remaining = time.strftime("%M:%S", time.gmtime(int(duration) - int(current) ) ) else: timepos = time.strftime("%M:%S", time.gmtime(int(current))) remaining = timepos return { 'state':u"play", 'artist':artist, 'title':title, 'album':album, 'remaining':remaining, 'current':current, 'duration':duration, 'position':timepos, 'volume':volume, 'playlist_display':playlist_display,'playlist_position':playlist_position, 'playlist_count':playlist_count, 'bitrate':bitrate, 'type':tracktype } else: return { 'state':u"stop", 'artist':u"", 'title':u"", 'album':u"", 'remaining':u"", 'current':0, 'duration':0, 'position':u"", 'volume':0, 'playlist_display':u"", 'playlist_position':0, 'playlist_count':0, 'bitrate':u"", 'type':u""} def status(self): # If you are using Rune if RUNE_ENABLED: status = self.status_redis() elif MPD_ENABLED or SPOP_ENABLED or LMS_ENABLED: if MPD_ENABLED: # Try MPD daemon status = self.status_mpd() else: status = { 'state':u"stop", 'artist':u"", 'title':u"", 'album':u"", 'remaining':u"", 'current':0, 'duration':0, 'position':u"", 'volume':0, 'playlist_display':u"", 'playlist_position':0, 'playlist_count':0, 'bitrate':u"", 'type':u"" } # If MPD is stopped if status.get('state') != "play": # Try SPOP if SPOP_ENABLED: status = self.status_spop() else: status = { 'state':u"stop", 'artist':u"", 'title':u"", 'album':u"", 'remaining':u"", 'current':0, 'duration':0, 'position':u"", 'volume':0, 'playlist_display':u"", 'playlist_position':0, 'playlist_count':0, 'bitrate':u"", 'type':u""} # If SPOP is stopped if status.get('state') != "play": # Try LMS if LMS_ENABLED: status = self.status_lms() else: status = { 'state':u"stop", 'artist':u"", 'title':u"", 'album':u"", 'remaining':u"", 'current':0, 'duration':0, 'position':u"", 'volume':0, 'playlist_display':u"", 'playlist_position':0, 'playlist_count':0, 'bitrate':u"", 'type':u""} else: status = { 'state':u"stop", 'artist':u"", 'title':u"", 'album':u"", 'remaining':u"", 'current':0, 'duration':0, 'position':u"", 'volume':0, 'playlist_display':u"", 'playlist_position':0, 'playlist_count':0, 'bitrate':u"", 'type':u""} # Add system variables try: if TIME24HOUR == True: current_time = moment.utcnow().timezone(TIMEZONE).strftime("%H:%M").strip() current_time_sec = moment.utcnow().timezone(TIMEZONE).strftime("%H:%M:%S").strip() else: current_time = moment.utcnow().timezone(TIMEZONE).strftime("%-I:%M %p").strip() current_time_sec = moment.utcnow().timezone(TIMEZONE).strftime("%-I:%M:%S %p").strip() except ValueError: # Don't know why but on exit, the moment code is occasionally throwing a ValueError current_time = "00:00" current_time_sec = "00:00:00" current_ip = commands.getoutput("ip -4 route get 1 | head -1 | cut -d' ' -f8 | tr -d '\n'").strip() # Read Temperature from Pi's on-board temperature sensor once every 20 seconds if self.tempreadexpired < time.time(): self.tempreadexpired = time.time()+20 try: file = open("/sys/class/thermal/thermal_zone0/temp") self.tempc = int(file.read()) # Convert value to float and correct decimal place self.tempc = round(float(self.tempc) / 1000,1) # convert to fahrenheit self.tempf = round(self.tempc*9/5+32,1) file.close() except IOError: self.tempc = 0.0 self.tempf = 0.0 except AttributeError: file.close() self.tempc = 0.0 self.tempf = 0.0 # Read available disk space remaining every 20 seconds if self.diskreadexpired < time.time(): self.diskreadexpired = time.time() + 20 try: # Check if running on OSX. If yes, adjust df command if sys.platform == "darwin": p = os.popen("df /") line = p.readline() line = p.readline() va = line.split() line = "{0} {1}".format(va[3], va[4]) else: # assume running on Raspberry linux p = os.popen("df --output='avail','pcent' /") line = p.readline() line = p.readline().strip() va = line.split() self.avail = va[0] self.availp = va[1] # remove % sign self.availp = self.availp[0:len(self.availp)-1] self.avail = int(self.avail) self.availp = int(self.availp) p.close() except IOError: self.avail = 0 self.availp = 0 except AttributeError: p.close() self.avail = 0 self.availp = 0 status['current_tempc'] = self.tempc status['current_tempf'] = self.tempf status['disk_avail'] = self.avail status['disk_availp'] = self.availp status['current_time'] = current_time status['current_time_sec'] = current_time status['current_ip'] = current_ip # if logging of the status data has been requested record the current status if STATUSLOGGING: self.statusfile.write(str(status)+'\n') self.statusfile.flush() return status
def currentTrack(self, i3status_output_json, i3status_config): try: c = MPDClient() c.connect(host=HOST, port=PORT) if PASSWORD: c.password(PASSWORD) status = c.status() song = int(status.get("song", 0)) next_song = int(status.get("nextsong", 0)) if (status["state"] == "pause" and HIDE_WHEN_PAUSED) or (status["state"] == "stop" and HIDE_WHEN_STOPPED): text = "" else: try: song = c.playlistinfo()[song] song["time"] = "{0:.2f}".format( int(song.get("time", 1)) / 60) except IndexError: song = {} try: next_song = c.playlistinfo()[next_song] except IndexError: next_song = {} format_args = song format_args["state"] = STATE_CHARACTERS.get( status.get("state", None)) for k, v in next_song.items(): format_args["next_{}".format(k)] = v text = STRFORMAT for k, v in format_args.items(): text = text.replace("{" + k + "}", v) for sub in re.findall(r"{\S+?}", text): text = text.replace(sub, "") except SocketError: text = "Failed to connect to mpd!" except CommandError: text = "Failed to authenticate to mpd!" c.disconnect() if len(text) > MAX_WIDTH: text = text[-MAX_WIDTH - 3:] + "..." if self.text != text: transformed = True self.text = text else: transformed = False response = { 'cached_until': time() + CACHE_TIMEOUT, 'full_text': self.text, 'name': 'scratchpad-count', 'transformed': transformed } return (POSITION, response)
client.add(transition) client.findadd("album", album) for t in tracks: client.add(t) # Delete up to the current track, minus 10 tracks (for the web # playlist) status = client.status() if "song" in status: client.delete((0, max(0, int(status["song"]) - 10))) if __name__ == "__main__": args = docopt(__doc__) try: args["PORT"] = int(args["PORT"]) except ValueError: print("PORT must be an integer") exit(1) try: client = MPDClient() client.connect(args["--host"], args["PORT"]) except Exception as e: print(f"could not connect to MPD: {e.args[0]}") exit(2) client.update() schedule_radio(client)
class MPDPlaybackController: """ Handles all playback control """ def __init__(self): self.client = MPDClient() self.client.timeout = 20 self.client.idletimeout = None self.playback_action_mapping = { "000000": self.play, "000001": self.pause, "000002": self.next_song, "000003": self.previous_song, "000004": self.increase_vol, "000005": self.decrease_vol, "000006": self.stop_playback, "000007": self.clear_playlist, "000008": self.shuffle_playlist } @contextmanager def connection(self): try: self.client.connect('localhost', 6600) yield finally: self.client.close() self.client.disconnect() def handle_action(self, command_code): """ Takes in command passed from barcode, and either modifies playback settings or plays/queues the music at the URI that maps to the barcode code """ if (command_code[0] == "0"): self.playback_action_mapping[command_code[1:]]() elif (command_code[0] == "1"): self.handle_playlist_queue(command_code[0]) def handle_playlist_queue(self, command_code): """ Based on state, either plays or queues music """ with self.connection(): try: self.client.clear() self.client.stop() self.client.add("spotify:track:2Gy7qnDwt8Z3MNxqat4CsK") except: pass def play(self): """ Invokes 'PLAY' function of MPD client """ with self.connection(): try: self.client.pause(0) except: pass # TODO: Except an actual error def pause(self): """ Invokes 'PAUSE' function of MPD client """ with self.connection(): try: self.client.pause(1) except: pass # TODO: Except an actual error def next_song(self): """ Invokes 'NEXT' function of MPD client """ with self.connection(): try: self.client.next() except: pass # TODO: Except an actual error def previous_song(self): """ Invokes 'PREVIOUS' function of MPD client """ with self.connection(): try: self.client.previous() except: pass # TODO: Except an actual error def increase_vol(self): """ Increases volume by 10% of MPD client """ with self.connection(): try: self.client.setvol(self.client.status().volume + 10) except: pass # TODO: Except an actual error def decrease_vol(self): """ Decrease volume by 10% of MPD client """ with self.connection(): try: self.client.setvol(self.client.status().volume - 10) except: pass # TODO: Except an actual error def stop_playback(self): """ Invokes 'STOP' function of MPD client """ with self.connection(): try: self.client.stop() except: pass # TODO: Except an actual error def clear_playlist(self): """ Invokes 'CLEAR' function of MPD client """ with self.connection(): try: self.client.clear() except: pass # TODO: Except an actual error def shuffle_playlist(self): """ Invokes 'SHUFFLE' function of MPD client """ with self.connection(): try: self.client.shuffle() except: pass
# -*- coding: utf-8 -*- # IMPORTS from mpd import (MPDClient, CommandError) from random import choice from socket import error as SocketError from sys import exit ## SETTINGS ## HOST = 'localhost' PORT = '6600' PASSWORD = False ### client = MPDClient() try: client.connect(host=HOST, port=PORT) except SocketError: exit(1) if PASSWORD: try: client.password(PASSWORD) except CommandError: exit(1) client.add(choice(client.list('file'))) client.disconnect()