Created
September 9, 2014 23:04
-
-
Save miggyb/d02f718645a2007fd49f to your computer and use it in GitHub Desktop.
ponysauce.py - mpd streamer for demovibes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ponysauce.py - mpd streamer for demovibes | |
# Released under the WTFPL license: | |
# http://www.wtfpl.net/txt/copying/ | |
import logging | |
import queuefetcher | |
#from django.core.management import setup_environ | |
#import settings | |
from mpd import MPDClient | |
import os.path | |
import time | |
# Set up logging | |
Log = logging.getLogger('ponysauce') | |
if __name__ == '__main__': | |
logging.basicConfig(level=logging.INFO) | |
Log.setLevel(logging.INFO) | |
# Magic Demovibes song fetcher | |
player = queuefetcher.song_finder() | |
# The mpd hostname and port, should be left alone | |
# unless you know you've set it to something | |
# different | |
host = 'localhost' | |
port = 6600 | |
# Path of music files, which should also be root of | |
# the mpd library. Set this in mpd.conf | |
path = '/path/goes/here' | |
# Buffer before the end of the currently playing song | |
# to make sure there is enough time for queueing, | |
# processing and crossfading. Lower is better, but | |
# don't kill the stream or queue too late for | |
# crossfading! | |
buffer = 10 | |
# Make this something under the default client timeout | |
# for mpd. If the connection_timeout value in mpd.conf | |
# is 60, make this 50 or something like that. | |
timeout = 50 | |
class ponysauce: | |
def __init__(self, host="localhost", port=6600): | |
self.running = True | |
self.mpd = MPDClient() | |
try: | |
self.mpd.connect(host, port) | |
Log.info("Connected to mpd using host %s, port %s" % (host, port)) | |
except: | |
Log.error("Couldn't connect to mpd! Is it running on %s, port %s?" % (host, port)) | |
return | |
self.loop() | |
def loop(self): | |
while self.running: | |
# Asking mpd for 'time' will give you the elapsed | |
# and total time of a song, separated by a colon. | |
# For example, a 5 minute song will output "0:300" | |
# when it starts playing and "300:300" at the end. | |
try: | |
songTime = self.mpd.status()['time'] | |
songTime = songTime.split(':') | |
songTime = [int(songTime[0]), int(songTime[1])] | |
except: | |
songTime = [0, 0] | |
timeRemaining = songTime[1] - songTime[0] | |
# If you try to get the next song when mpd is already | |
# at the last song, mpd throws an error. | |
try: | |
next = self.mpd.status()['nextsong'] | |
except: | |
next = None | |
# Add a song to the queue if we're at the end of the | |
# buffer time and there's nothing else queued already | |
if (timeRemaining < buffer) and next is None: | |
self.add(player.get_next_song()) | |
# The longest we can sleep before reaching the buffer | |
sleepTime = timeRemaining - buffer | |
# Handling 0 and possibly(?) negative sleepTime | |
if sleepTime < 1: | |
sleepTime = 1 | |
# If you add a 24 hour long song, you probably | |
# don't want the script to stay at a "sleep" for | |
# 24 hours straight :) | |
if sleepTime > timeout: | |
sleepTime = timeout | |
# Sleep this script and the client connection, then | |
# start the loop again | |
self.mpd.send_idle() | |
time.sleep(sleepTime) | |
self.mpd.noidle() | |
def die(self): | |
self.mpd.close() | |
self.mpd.disconnect() | |
self.running = False | |
return "Quitting!" | |
def add(self, fullpath): | |
file = os.path.relpath(fullpath, path) | |
# Since mpd uses a database to organize artists and | |
# albums and it's impossible to turn it off, let's | |
# try queueing the song first, and if that fails, | |
# add it to the database first then try adding it | |
# again. | |
try: | |
Log.info("Queueing file %s" % file) | |
self.mpd.add(file) | |
except: | |
Log.info("Adding new file %s to mpd database" % file) | |
self.mpd.update(file) | |
self.mpd.idle('database') | |
Log.info("Queueing file %s" % file) | |
self.mpd.add(file) | |
# Make mpd start playing the song it if it's paused | |
# or stopped | |
if self.mpd.status()['state'] is not 'play': | |
self.mpd.play() | |
# Start 'er up! | |
p = ponysauce(host, port) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment