#!/usr/bin/ruby -w # Simple web interface to music player daemon in Ruby. # More information on mpd can be found at http://www.musicpd.org/ # require 'librmpd' # librmpd is incomprehensibly bad. playlistinfo takes 30 damned seconds and isn't actually fucking named playlistinfo. require 'mpd' # Whereas here, playlistinfo takes one second and is fucking named playlistinfo. $VERBOSE = nil # mpd.rb is a bit noisy about versions, though. require 'cgi' cgi = CGI.new m = MPD.new def output_info(m) currentsong = m.currentsong status = m.status stats = m.stats playlistinfo = m.playlistinfo position = currentsong['pos'].to_i times = status['time'].split(':') listeners = 0 File.open('/proc/net/tcp', 'r').each do |line| if /^.{6}[0-9A-F]{8}:1F40 (?!00000000:0000)/ =~ line #255.255.255.255:4369 not LISTENing listeners += 1 end end print 'Content-type: text/html; charset=utf-8 Refresh: 30; URL=', ENV['REQUEST_URI'].sub(/\?.+/,''), '
Playing ' format_songinfo(currentsong) print ' for ', listeners, ' listeners.
This song is ', times[0].to_i*100/times[1].to_i, '% complete (', times[0], ' of ', times[1], ' seconds played).
This is song ', position+1, ' of ', status['playlistlength'], ' total in the library. Next!
', stats['playtime'].to_i/864/100.0, ' days into playlist length of ', stats['db_playtime'].to_i/864/100.0, ' days.
Here are the proximal songs:
'
min = 0
if position >= 10
min = position-10
end
max = position+10
if max > status['playlistlength'].to_i
max = status['playlistlength'].to_i
end
playlistinfo[min,max].each do |songinfo|
if songinfo['pos'] == position
print ''
end
print 'Queue ' , songinfo['pos'], ' '
format_songinfo(songinfo)
if songinfo['pos'] == position
print ''
end
print '
'
end
print '
'
end
def output_stopped()
print 'Content-type: text/html; charset=utf-8
MPD is stopped.
' end def output_playlist(m) print 'Content-type: text/html; charset=utf-8Return to main
Load pre-existing playlist: ' m.lsplaylists.each do |playlist| print '', playlist, ' '; end print'
'
m.playlistinfo.each do |songinfo| # One giant object
print '', songinfo['pos'], ' '
format_songinfo(songinfo)
print '
'
end
print'
'
end
def format_songinfo(songinfo)
if songinfo['artist'] && songinfo['title']
print CGI.escapeHTML( songinfo['artist'] + ' - ' + songinfo['title'] )
elsif songinfo['title']
print CGI.escapeHTML( songinfo['title'] )
else
print CGI.escapeHTML( songinfo['file'] )
end
end
def queue(m,songpos)
curpos = m.currentsong['pos'].to_i
if songpos <= curpos # mpd is a little screwy about how it handles playlist reordering
m.move(songpos, curpos)
elsif songpos > curpos
m.move(songpos, curpos+1)
end
end
if cgi.params['ajaxqueue'][0] =~ /^\d+$/ # ?ajaxqueue=55385
songinfo = m.playlistid(cgi.params['ajaxqueue'][0])
queue(m, songinfo['pos'].to_i)
print 'Content-type: application/xhtml+xml; charset=utf-8
'
format_songinfo(songinfo)
print ' has been requeued.'
elsif cgi.params['queue'][0] =~ /^\d+$/ # ?queue=55385
queue(m, m.playlistid(cgi.params['queue'][0])['pos'].to_i)
output_info(m)
elsif cgi.params['playlist'][0] =~ /.+/ # ?playlist=something
m.crop
m.load(cgi.params['playlist'][0])
m.shuffle
output_info(m)
elsif cgi.params.has_key? 'playlist' # ?playlist
output_playlist(m)
elsif m.status['state'] == 'play' # mpd playing?
if cgi.params.has_key? 'change' # ?change
m.next
end
output_info(m)
else # mpd not playing
if cgi.params.has_key? 'start'# ?start
m.play
output_info(m)
else # stopped display
output_stopped()
end
end