[xiph-commits] r8704 - in icecast/trunk/ices0: . conf doc src src/playlist

brendan at motherfish-iii.xiph.org brendan at motherfish-iii.xiph.org
Sun Jan 9 15:10:33 PST 2005


Author: brendan
Date: 2005-01-09 15:10:32 -0800 (Sun, 09 Jan 2005)
New Revision: 8704

Added:
   icecast/trunk/ices0/conf/ices.sh.dist
   icecast/trunk/ices0/src/playlist/pm_script.c
   icecast/trunk/ices0/src/playlist/pm_script.h
Modified:
   icecast/trunk/ices0/NEWS
   icecast/trunk/ices0/README
   icecast/trunk/ices0/README.playlist
   icecast/trunk/ices0/conf/Makefile.am
   icecast/trunk/ices0/conf/ices.conf.dist.in
   icecast/trunk/ices0/doc/ices.1.in
   icecast/trunk/ices0/doc/icesmanual.html
   icecast/trunk/ices0/src/ices_config.c
   icecast/trunk/ices0/src/icestypes.h
   icecast/trunk/ices0/src/playlist/Makefile.am
   icecast/trunk/ices0/src/playlist/playlist.c
   icecast/trunk/ices0/src/playlist/playlist.h
   icecast/trunk/ices0/src/setup.c
Log:
Script playlist module, ported from ices 2 by Ville Koskinen
(plus docs, and an adjustment to search in the module directory instead
of the shell path)


Modified: icecast/trunk/ices0/NEWS
===================================================================
--- icecast/trunk/ices0/NEWS	2005-01-09 09:53:20 UTC (rev 8703)
+++ icecast/trunk/ices0/NEWS	2005-01-09 23:10:32 UTC (rev 8704)
@@ -1,3 +1,4 @@
+        * script module ported from ices 2 by Ville Koskinen.
 0.4     2004-08-28
 	* FLAC transcoding support.
 	* MP4 transcoding support added via libfaad.

Modified: icecast/trunk/ices0/README
===================================================================
--- icecast/trunk/ices0/README	2005-01-09 09:53:20 UTC (rev 8703)
+++ icecast/trunk/ices0/README	2005-01-09 23:10:32 UTC (rev 8704)
@@ -89,11 +89,13 @@
             could possibly modify the playlist. This was rather ugly, but
             did the trick. In ices, we take this a step further an
             include scripting support inside the program. You can write
-            your own playlist handler in perl or python, whatever you
-            prefer. Your script module has to define 5 functions; test,
+            your own playlist handler in shell, perl or python, whatever you
+            prefer. Your script module may define 5 functions: test,
             init, shutdown, get_next, and get_current_lineno. I suggest
             you take a look in the distributed module files and just
-            expand on that.
+            expand on that. Shell scripts should return two lines - the
+            first is a path to a file, and the second is an optional
+            metadata string.
 	 5. Vorbis, FLAC and MP4 transcoding
             If compiled with the appropriate libraries, ices can transcode
             Ogg Vorbis, FLAC and MP4 (AAC) audio files to MP3 on the fly. Keep
@@ -128,7 +130,7 @@
                o -P <password>
                o -r (randomize playlist)
                o -s (private stream)
-               o -S <perl|python|builtin>
+               o -S <script|perl|python|builtin>
                o -u <stream url>
                o -N <Reencoded number of channels>
                o -H <Reencoded sample rate>
@@ -291,7 +293,7 @@
                  This option is passed to the playlist handler, and tells
                  it to randomize the playlist.
                o Playlist Type
-                 Command line option: -S <perl|python|builtin>
+                 Command line option: -S <script|perl|python|builtin>
                  Config file tag: Playlist/Type
                  By default, ices using a builtin playlist handler. It
                  handles randomization and not much more. Most people
@@ -300,8 +302,8 @@
                  handles embedded python and embedded perl, so now you
                  can write your own modules, without modifying ices, that
                  does just about anything. Use this option to change the
-                 playlist handler type from builtin (default), to python
-                 or perl.
+                 playlist handler type from builtin (default), to python,
+                 perl or script.
                o Playlist Module
                  Command line option: -M <module>
                  Config file tag: Playlist/Module

Modified: icecast/trunk/ices0/README.playlist
===================================================================
--- icecast/trunk/ices0/README.playlist	2005-01-09 09:53:20 UTC (rev 8703)
+++ icecast/trunk/ices0/README.playlist	2005-01-09 23:10:32 UTC (rev 8704)
@@ -11,6 +11,10 @@
 respectively) included in the ices distribution. Others should keep
 reading.
 
+Shell scripts are somewhat simpler: At each invocation, the shell script
+must return the path to an audio file as its first line of output.
+Optionally it may return the metadata on the second line.
+
 The following methods may be defined:
 
 ices_get_next

Modified: icecast/trunk/ices0/conf/Makefile.am
===================================================================
--- icecast/trunk/ices0/conf/Makefile.am	2005-01-09 09:53:20 UTC (rev 8703)
+++ icecast/trunk/ices0/conf/Makefile.am	2005-01-09 23:10:32 UTC (rev 8704)
@@ -3,6 +3,6 @@
 AUTOMAKE_OPTIONS = foreign
 
 sysconf_DATA = ices.conf.dist
-mod_DATA = ices.py.dist ices.pm.dist
+mod_DATA = ices.py.dist ices.pm.dist ices.sh.dist
 
 EXTRA_DIST = $(sysconf_DATA) $(mod_DATA)

Modified: icecast/trunk/ices0/conf/ices.conf.dist.in
===================================================================
--- icecast/trunk/ices0/conf/ices.conf.dist.in	2005-01-09 09:53:20 UTC (rev 8703)
+++ icecast/trunk/ices0/conf/ices.conf.dist.in	2005-01-09 23:10:32 UTC (rev 8704)
@@ -7,10 +7,10 @@
     <!-- Set this to 0 if you don't want to randomize your playlist, and to
 	 1 if you do. -->
     <Randomize>1</Randomize>
-    <!-- One of builtin, perl, or python. -->
+    <!-- One of builtin, script, perl, or python. -->
     <Type>builtin</Type>
-    <!-- Module name to pass to the playlist handler if using  perl or python.
-	 If you use the builtin playlist handler then this is ignored -->
+    <!-- Module name to pass to the playlist handler if using a script,
+         perl, or python. Ignored for builtin -->
     <Module>ices</Module>
     <!-- Set this to the number of seconds to crossfade between tracks.
          Leave out or set to zero to disable crossfading (the default).

Added: icecast/trunk/ices0/conf/ices.sh.dist
===================================================================
--- icecast/trunk/ices0/conf/ices.sh.dist	2005-01-09 09:53:20 UTC (rev 8703)
+++ icecast/trunk/ices0/conf/ices.sh.dist	2005-01-09 23:10:32 UTC (rev 8704)
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+# The first line should be a path to an audio file
+echo "/mp3s/arcadefire2.mp3"
+
+# The next line is optional
+echo "The Arcade Fire - Neighbourhood #2 (Laika)"

Modified: icecast/trunk/ices0/doc/ices.1.in
===================================================================
--- icecast/trunk/ices0/doc/ices.1.in	2005-01-09 09:53:20 UTC (rev 8703)
+++ icecast/trunk/ices0/doc/ices.1.in	2005-01-09 23:10:32 UTC (rev 8704)
@@ -15,7 +15,7 @@
 .RB [\| \-F
 .IR playlist \|]
 .RB [\| \-r \|]\|]\||[\| \-S
-.BR python \|| perl
+.BR script \|| python \|| perl
 .RB [\| \-M
 .IR module \|]\|]
 .RB [\| \-C
@@ -56,7 +56,7 @@
 ices is a small but powerful and flexible encoder for icecast
 servers. Its features include:
 .IP \(bu
-A scripting interface to its playlist engine, using either python or
+A scripting interface to its playlist engine, using shell, python or
 perl as you prefer, in addition to a builtin static file server.
 Fetch your tracks from a database or update a webpage at each track
 change in a simple and robust way.
@@ -108,7 +108,7 @@
 .BI \-S \ interpreter
 Chooses which playlist interpreter ices will use to find source audio
 files for streaming. May be one of
-.BR builtin , \ python ,\ or \ perl .
+.BR builtin , \ script , \ python ,\ or \ perl .
 The default is
 .BR builtin .
 .TP
@@ -130,7 +130,7 @@
 .TP
 .BI \-M \ module
 If using the
-.BR perl \ or \ python
+.BR script , \ perl \ or \ python
 playlist modules, load the module named
 .I module
 instead of the default, 
@@ -237,9 +237,15 @@
 
 .SH "PLAYLIST SCRIPTING"
 In addition to its simple builtin playlist handler, ices can
-optionally call out to either a python or perl module for track
-information. Your module may define the following functions:
+optionally call out to a shell script or a python or perl module for track
+information. 
 
+Shell scripts should return the path to the next audio file as the first
+line of their output. They may optionally return the metadata for title
+streaming as their second line.
+
+Your python or perl module may define the following functions:
+
 .TP
 .B ices_init
 This function is called once when ices starts up, giving your module a

Modified: icecast/trunk/ices0/doc/icesmanual.html
===================================================================
--- icecast/trunk/ices0/doc/icesmanual.html	2005-01-09 09:53:20 UTC (rev 8703)
+++ icecast/trunk/ices0/doc/icesmanual.html	2005-01-09 23:10:32 UTC (rev 8704)
@@ -161,9 +161,12 @@
 each song, and that could possibly modify the playlist.
 This was rather ugly, but did the trick.
 In ices, we take this a step further and include scripting support inside the
-program. You can write your own playlist handler in perl or python, whatever
-you prefer.
-<br>
+program. You can write your own playlist handler in shell, perl or python,
+whatever you prefer.
+<p>
+Shell scripts simply return the path to a file as their first line of
+output, and may optionally return metadata as their second line.
+</p>
 Your script module has to define at least a function named
 <tt>ices_get_next</tt>, which should return a path to a file or FIFO
 containing MP3 data.

Modified: icecast/trunk/ices0/src/ices_config.c
===================================================================
--- icecast/trunk/ices0/src/ices_config.c	2005-01-09 09:53:20 UTC (rev 8703)
+++ icecast/trunk/ices0/src/ices_config.c	2005-01-09 23:10:32 UTC (rev 8704)
@@ -268,6 +268,8 @@
 	ices_config->pm.playlist_type = ices_playlist_python_e;
       else if (str && (strcmp (str, "perl") == 0))
 	ices_config->pm.playlist_type = ices_playlist_perl_e;
+      else if (str && (strcmp (str, "script") == 0))
+	ices_config->pm.playlist_type = ices_playlist_script_e;
       else
 	ices_config->pm.playlist_type = ices_playlist_builtin_e;
     } else if (strcmp (cur->name, "File") == 0) {

Modified: icecast/trunk/ices0/src/icestypes.h
===================================================================
--- icecast/trunk/ices0/src/icestypes.h	2005-01-09 09:53:20 UTC (rev 8703)
+++ icecast/trunk/ices0/src/icestypes.h	2005-01-09 23:10:32 UTC (rev 8704)
@@ -30,6 +30,7 @@
 
 typedef enum {
   ices_playlist_builtin_e,
+  ices_playlist_script_e,
   ices_playlist_python_e,
   ices_playlist_perl_e
 } playlist_type_t;

Modified: icecast/trunk/ices0/src/playlist/Makefile.am
===================================================================
--- icecast/trunk/ices0/src/playlist/Makefile.am	2005-01-09 09:53:20 UTC (rev 8703)
+++ icecast/trunk/ices0/src/playlist/Makefile.am	2005-01-09 23:10:32 UTC (rev 8704)
@@ -3,9 +3,9 @@
 INCLUDES = -DICES_MODULEDIR=\"$(moddir)\" -I$(top_srcdir)/src
 
 noinst_LIBRARIES = libplaylist.a
-noinst_HEADERS = playlist.h pm_builtin.h rand.h
+noinst_HEADERS = playlist.h pm_builtin.h pm_script.h rand.h
 
-libplaylist_a_SOURCES = playlist.c pm_builtin.c rand.c
+libplaylist_a_SOURCES = playlist.c pm_builtin.c pm_script.c rand.c
 EXTRA_libplaylist_a_SOURCES = pm_python.c pm_perl.c
 
 libplaylist_a_LIBADD = $(PLAYLIST_OBJECTS)

Modified: icecast/trunk/ices0/src/playlist/playlist.c
===================================================================
--- icecast/trunk/ices0/src/playlist/playlist.c	2005-01-09 09:53:20 UTC (rev 8703)
+++ icecast/trunk/ices0/src/playlist/playlist.c	2005-01-09 23:10:32 UTC (rev 8704)
@@ -73,6 +73,9 @@
     case ices_playlist_builtin_e:
       rc = ices_playlist_builtin_initialize (&ices_config.pm);
       break;
+	case ices_playlist_script_e:
+	  rc = ices_playlist_script_initialize (&ices_config.pm);
+	  break;
     case ices_playlist_python_e:
 #ifdef HAVE_LIBPYTHON
       rc = ices_playlist_python_initialize (&ices_config.pm);

Modified: icecast/trunk/ices0/src/playlist/playlist.h
===================================================================
--- icecast/trunk/ices0/src/playlist/playlist.h	2005-01-09 09:53:20 UTC (rev 8703)
+++ icecast/trunk/ices0/src/playlist/playlist.h	2005-01-09 23:10:32 UTC (rev 8704)
@@ -31,6 +31,7 @@
 void ices_playlist_shutdown (void);
 
 int ices_playlist_builtin_initialize (playlist_module_t* pm);
+int ices_playlist_script_initialize (playlist_module_t* pm);
 #ifdef HAVE_LIBPYTHON
 int ices_playlist_python_initialize (playlist_module_t* pm);
 #endif

Added: icecast/trunk/ices0/src/playlist/pm_script.c
===================================================================
--- icecast/trunk/ices0/src/playlist/pm_script.c	2005-01-09 09:53:20 UTC (rev 8703)
+++ icecast/trunk/ices0/src/playlist/pm_script.c	2005-01-09 23:10:32 UTC (rev 8704)
@@ -0,0 +1,166 @@
+/* pm_script.c
+ * - playlist module for external scripts (á la IceS 2.0)
+ * - based on playlist_script.c from IceS 2.0 by 
+ * Copyright (c) 2001 Michael Smith <msmith at labyrinth.net.au>
+ *
+ * Copyright (C) 2005 Ville Koskinen <ville.koskinen at iki.fi> 
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+#include "definitions.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+#define STR_BUFFER 1024
+
+static char *playlist_metadata = NULL;
+static char *cmd = NULL;
+
+extern ices_config_t ices_config;
+
+/* Private function declarations */
+static char* playlist_script_get_next (void);
+static void playlist_script_shutdown (void);
+static char* playlist_script_get_metadata (void);
+
+/* Global function definitions */
+
+/* Initialize the script playlist handler */
+int
+ices_playlist_script_initialize (playlist_module_t* pm)
+{
+  ices_log_debug ("Initializing script playlist handler...");
+
+  if (!pm->module) {
+    ices_log_error ("No playlist script defined");
+    return 0;
+  }
+  
+  cmd = pm->module;
+  /* make path relative to module dir */
+  if (cmd[0] != '/' && 
+      !(cmd[0] == '.' && (cmd[1] == '/' || (cmd[1] == '.' && cmd[2] == '/'))))
+  {
+      cmd = malloc (strlen(pm->module) + strlen(ICES_MODULEDIR) + 2);
+      if (cmd)
+        sprintf (cmd, "%s/%s", ICES_MODULEDIR, pm->module);
+  } else
+    cmd = strdup(pm->module);
+    
+  if (!cmd) {
+    ices_log_error("Could not allocate memory for playlist path");
+    return 0;
+  }
+
+  pm->get_next = playlist_script_get_next;
+  pm->get_metadata = playlist_script_get_metadata;
+  pm->get_lineno = NULL;
+  pm->shutdown = playlist_script_shutdown;
+
+  return 1;
+}
+
+static char *
+playlist_script_get_next (void)
+{
+  char *filename = NULL, *metadata = NULL;
+  FILE *pipe;
+  int i = 0;
+
+  filename = malloc(STR_BUFFER);
+  metadata = malloc(STR_BUFFER);
+	
+  pipe = popen(cmd, "r");
+
+  if (!pipe) {
+	  ices_log_error ("Couldn't open pipe to program \"%s\"", cmd);
+	  return NULL;
+  }
+
+  if (fgets(filename, STR_BUFFER, pipe) == NULL) {
+	  ices_log_error ("Couldn't read filename from pipe to program \"%s\"", cmd);
+	  free(filename); filename = NULL;
+	  free(metadata); metadata = NULL;
+	  pclose(pipe);
+	  return NULL;
+  }
+
+  if (fgets(metadata, STR_BUFFER, pipe) == NULL) {
+	  /* This is non-fatal. */
+	  ices_log_debug ("No metadata received from pipe to program \"%s\"", cmd);
+	  free(metadata); metadata = NULL;
+  }
+	  
+  pclose(pipe);
+
+  if (filename[0] == '\n' || (filename[0] == '\r' && filename[1] == '\n')) {
+		ices_log_error ("Got newlines instead of filename from program \"%s\"", cmd);
+		free(filename); filename = NULL;
+		free(metadata); metadata = NULL;
+		pclose(pipe);
+		return NULL;
+  }
+
+  /* Remove linefeeds etc. */
+  i = 0;
+  while (filename[i]) {
+	  if (filename[i] == '\r' || filename[i] == '\n') {
+		  filename[i] = '\0';
+		  break;
+	  }
+	  i++;
+  }
+  i = 0;
+  while (metadata && metadata[i]) {
+	  if (metadata[i] == '\r' || metadata[i] == '\n') {
+		  metadata[i] = '\0';
+		  break;
+	  }
+	  i++;
+  }
+
+  if (playlist_metadata)
+	  free(playlist_metadata);
+  if (metadata) 
+	  playlist_metadata = metadata;
+  else
+	  playlist_metadata = NULL;
+  
+  ices_log_debug ("Script playlist handler serving: %s [%s]", ices_util_nullcheck (filename), ices_util_nullcheck(playlist_metadata));
+
+  return filename;
+}
+
+/* Return the file metadata. */
+static char*
+playlist_script_get_metadata (void) 
+{
+	if (playlist_metadata)
+		return playlist_metadata;
+	return NULL;
+}
+
+/* Shutdown the script playlist handler */
+static void
+playlist_script_shutdown (void)
+{
+  if (cmd)
+    free (cmd);
+  if (playlist_metadata)
+    free(playlist_metadata);
+}
+


Property changes on: icecast/trunk/ices0/src/playlist/pm_script.c
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: icecast/trunk/ices0/src/playlist/pm_script.h
===================================================================
--- icecast/trunk/ices0/src/playlist/pm_script.h	2005-01-09 09:53:20 UTC (rev 8703)
+++ icecast/trunk/ices0/src/playlist/pm_script.h	2005-01-09 23:10:32 UTC (rev 8704)
@@ -0,0 +1,22 @@
+/* pm_script.h
+ * - playlist module for external scripts (á la IceS 2.0)
+ * Copyright (C) 2005 Ville Koskinen <ville.koskinen at iki.fi> 
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+/* Public function declarations */
+int ices_playlist_script_initialize (playlist_module_t* pm);


Property changes on: icecast/trunk/ices0/src/playlist/pm_script.h
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Modified: icecast/trunk/ices0/src/setup.c
===================================================================
--- icecast/trunk/ices0/src/setup.c	2005-01-09 09:53:20 UTC (rev 8703)
+++ icecast/trunk/ices0/src/setup.c	2005-01-09 23:10:32 UTC (rev 8704)
@@ -441,6 +441,8 @@
 	    ices_config->pm.playlist_type = ices_playlist_python_e;
 	  else if (strcmp (argv[arg], "perl") == 0)
 	    ices_config->pm.playlist_type = ices_playlist_perl_e;
+	  else if (strcmp (argv[arg], "script") == 0)
+	    ices_config->pm.playlist_type = ices_playlist_script_e;
 	  else 
 	    ices_config->pm.playlist_type = ices_playlist_builtin_e;
 	  break;



More information about the commits mailing list