Technology
 

Hack:ices-client

From Music Player Daemon Community Wiki

#!/usr/bin/env perl
# File: mpdplaylist.pm
# Author: David Talmage (talmage@acm.org)
#
# This hack for ices uses mpd as a playlist manager.
# The mpd playlist is a queue of songs to play.
#
# SETUP:
#
# 1. Edit $mediaroot so that the path to your music collection is
# correct.  Be sure to put a slash at the end of the path.
#
# 2. Copy this file to wherever ices looks for modules.
#
# 3. Your ices.conf needs this Playlist section:
#
#  <Playlist>
#    <Type>perl</Type>
#    <Module>mpdplaylist</Module>
#    <Crossfade>5</Crossfade>
#  </Playlist>
#
#
# USAGE
#
# 1. Set your mpd to not play.  E.g. with mpc
#
#      mpc stop
#
# 2. Use an mpd client to add to the playlist.  This ought
# to work with any number of clients adding to the
# playlist.
#
# 3. Start ices
#
# HISTORY:
# 20060822 - Initial version
# 20060826 - Two bugs fixed: 
#            1. Correct behavior with leading and trailing spaces in the playlist.
#            2. ices_get_next() blocks when the playlist is empty.  This prevents
#               ices from terminating abnormally.
# 20060831 - New function ices_get_metadata returns artist, title, and
#            album ID3 tags.  Uses MP3::Info perl module.
#            Thanks to Jesse for the idea and original implementation.
# 20070206 - 1. Added fallback playlist option.
#            2. Changed sleep 5 so the fallback list plays before an icecast fallback mount. wgalway@hotmail.com
use strict;
use MP3::Info;

# Directory in which all music is stored.  Note final slash!
# mpd returns the paths to files relative to this directory.
#
# E.g. When the song at the head of the playlist is
#
# /usr/media/MUSICMP3/B.B._King-Completely_Well/01.So_Excited.mp3
#
# mpd returns 
#
# B.B._King-Completely_Well/01.So_Excited.mp3
#
my $mediaroot = "/usr/media/MUSICMP3/";
my $playlistdir = "/usr/share/mpd/";            #Playlist dir from mpd.conf
my $playlistname = "fallbackplaylist";          #Your fallback playlist name. 


my $ext = ".m3u"; #Do not touch
my $playlistfile = $playlistdir.$playlistname.$ext;

# Full path to the song file at the head of the playlist
my $audiofile;

sub ices_init {
    return 1;
}

#Function to remove any beginning and ending white spaces
sub trim {
   my($string)=@_;
   for ($string) {
       s/^\s+//;
       s/\s+$//;
   }
   return $string;
}

# Function called to shutdown your python enviroment.
# Return 1 if ok, 0 if something went wrong.
sub ices_shutdown {
    return 1;
}

# Function called to get the next filename to stream. 
# Should return a string.
sub ices_get_next {
    my $playlist = ""; 	# Relative path to the song file at the head of the playlist

    # Keep asking for the first entry in mpd's playlist until the
    # answer isn't an empty string.  A empty string indicates that
    # there isn't anything in the playlist.

while (1) {
        $playlist = `mpc --format %file% 'playlist' | head -1 |cut -d ")" -f 2`; 
        if (length($playlist) > 0) {
            last;
         } elsif ( -e $playlistfile) {
                 system("mpc load $playlistname");
         } else {
              sleep 5;
         }
}

    $playlist = trim($playlist);
    $audiofile = $mediaroot.$playlist;
    chomp($audiofile);

    # Pops the name off the head of the playlist
    system('mpc del 1');

    return $audiofile;
}

sub ices_get_metadata {
  my $tag = get_mp3tag($audiofile);
  my $album =  trim($tag->{ALBUM});
  my $artist = trim($tag->{ARTIST});
  my $title =  trim($tag->{TITLE});
  my $metadata = "$artist"." - "."$title";

  if (! $album eq ""){
      $metadata = $metadata." ("."$album".")";
  }

  return $metadata;
}

# Function used to put the current line number of
# the playlist in the cue file. If you don't care
# about cue files, just return any integer.
sub ices_get_lineno {
	return 1;
}

return 1;