initial import START
authorivan <ivan>
Mon, 16 Jun 2003 11:38:34 +0000 (11:38 +0000)
committerivan <ivan>
Mon, 16 Jun 2003 11:38:34 +0000 (11:38 +0000)
README [new file with mode: 0644]
TODO [new file with mode: 0644]
create-Pg.sql [new file with mode: 0644]
create-mysql.sql [new file with mode: 0644]
doc/REFERENCE [new file with mode: 0644]
iceplex.conf [new file with mode: 0644]
iceplexd [new file with mode: 0644]
plex.pls [new file with mode: 0644]
yashout [new file with mode: 0644]

diff --git a/README b/README
new file mode 100644 (file)
index 0000000..8c6d3ba
--- /dev/null
+++ b/README
@@ -0,0 +1,65 @@
+iceplex
+
+Copyright (c) 2003 Ivan Kohler
+All rights reserved.
+This program is free software; you can redistribute it and/or modify it under
+the same terms as Perl itself.
+
+ivan-iceplex@420.am
+
+iceplex is a system for multiplexing on-demand broadcasts to multiple
+backend icecast servers.
+
+To use:
+
+Database configuration:
+
+  - Create the "iceplex_servers" table in your database
+    (see create-mysql.sql or create-Pg.sql)
+  - Populate the "iceplex_servers" table with your icecast server names.
+
+On the central multiplexing server:
+
+  - Copy the example iceplex.conf to /etc/iceplex.conf and modify the settings
+    as appropriate:
+    - Database location/user/pass
+    - Path to mp3 file storage on the icecast servers.
+    - Icecast Port number
+  - Run iceplexd and configure your init scripts to start it upon boot.
+  - Create an "iceplex" user.
+  - Run "ssh-keygen -t dsa" as the "iceplex" user to genarate SSH keys.
+    Use a blank passphrase.  (Press return when prompted for a passphrase)
+  - Install Net::SSH from CPAN or <http://search.cpan.org/author/IVAN/Net-SSH/>
+  - Install DBI from CPAN or <http://search.cpan.org/author/TIMB/DBI/>
+  - Install the DBD for your database
+    - MySQL: DBD::mysql from CPAN or
+      <http://search.cpan.org/author/JWIED/DBD-mysql/>
+    - PostgreSQL: DBD::Pg from CPAN or
+      <http://search.cpan.org/author/DWHEELER/DBD-Pg/>
+  - Install plex.pls in /cgi-bin/ on the central multiplexing server or main
+    webserver.  This file can be installed as or linked to as "plex.m3u" if
+    desired.
+
+On each icecast server:
+
+  - Create an "iceplex" user.
+  - Copy "/home/iceplex/.ssh/id_dsa.pub" from the central multiplexing server
+    to "/home/iceplex/.ssh/authorized_keys".
+  - Verify that the 
+  - Install libshout C library 1.0.9 and Shout perl interface:
+    <http://developer.icecast.org/libshout/>
+  - Install yashout from this archive in /usr/local/bin
+
+On end-user webpages:
+
+  - Link to:
+      <http://multi.plexing.server/cgi-bin/plex.pls?customer=XXXXXX;user=YYYY>
+
+Optional, improves stream start latency:
+
+  - Install fsh <http://www.lysator.liu.se/fsh/> on the central multiplexing
+    server and each icecast server.
+  - Uncomment 
+      $Net::SSH:ssh = 'fsh';
+    in /etc/iceplex.conf
+
diff --git a/TODO b/TODO
new file mode 100644 (file)
index 0000000..396760c
--- /dev/null
+++ b/TODO
@@ -0,0 +1 @@
+- mp3 file storage should be in hashed directories for scalability
diff --git a/create-Pg.sql b/create-Pg.sql
new file mode 100644 (file)
index 0000000..57f92dc
--- /dev/null
@@ -0,0 +1,7 @@
+create table iceplex_servers (
+  servernum serial primary key,
+  servername varchar(255)
+  listeners int,
+  status varchar(255),
+);
+
diff --git a/create-mysql.sql b/create-mysql.sql
new file mode 100644 (file)
index 0000000..a759a72
--- /dev/null
@@ -0,0 +1,7 @@
+create table iceplex_servers (
+  servernum int primary key auto_increment,
+  servername varchar(255),
+  listeners int,
+  status varchar(255),
+);
+
diff --git a/doc/REFERENCE b/doc/REFERENCE
new file mode 100644 (file)
index 0000000..aaad5e0
--- /dev/null
@@ -0,0 +1,12 @@
+
+Playlist file extensions and MIME types:
+http://www.dnalounge.com/audio/faq.html#configuration
+
+.pls file looks like:
+[playlist]
+NumberOfEntries=1
+File1=http://server:port/mountpoint
+
+.m3u file is even simpler:
+http://server:port/mountpoint
+
diff --git a/iceplex.conf b/iceplex.conf
new file mode 100644 (file)
index 0000000..9018c84
--- /dev/null
@@ -0,0 +1,47 @@
+# iceplex configuration file - /etc/iceplex.conf
+
+###
+# normal configuration
+###
+
+#database connection info
+$dsn = 'DBI:mysql:imedia';
+$user = 'imedia';
+$pass = 'imedia';
+
+#path to mp3 files on icecast servers
+$mp3path = '/home/ivan/plexmp3';
+
+#icecast port number
+$port = 8000;
+
+#(optional) file number override query
+# the first ? is replaced with the customer and second ? with the user
+#
+#$override_query = "SELECT filenumber FROM overrides ".
+#                  "WHERE customer = ? AND user = ?";
+
+#normal file number query
+# (used if the override query is not specified or does not return a value)
+# the first ? is replaced with the customer and second ? with the user
+#
+#$fileno_query = "SELECT MAX(filenumber) FROM files ".
+#                "WHERE customer = ? AND user = ?";
+
+#(if the normal query is not specified, file number defaults to '000')
+
+###
+# advanced options
+###
+
+#install fsh on both ends and uncomment this for better stream start latency
+#$Net::SSH::ssh = 'fsh';
+
+#mime types
+%extension2type = (
+  'pls' => 'audio/x-scpls',
+  'm3u' => 'audio/x-mpegurl',
+  #'m3u' => 'audio/mpegurl',
+);
+
+
diff --git a/iceplexd b/iceplexd
new file mode 100644 (file)
index 0000000..1f1c293
--- /dev/null
+++ b/iceplexd
@@ -0,0 +1 @@
+#!/usr/bin/perl
diff --git a/plex.pls b/plex.pls
new file mode 100644 (file)
index 0000000..a1bd1cc
--- /dev/null
+++ b/plex.pls
@@ -0,0 +1,90 @@
+#!/usr/bin/perl -w
+#
+# iceplex
+#
+# Copyright (c) 2003 Ivan Kohler
+# All rights reserved.
+# This program is free software; you can redistribute it and/or modify it under
+# the same terms as Perl itself.
+
+use strict;
+use subs qw(pick_server);
+use CGI;
+use CGI::Carp qw(fatalsToBrowser);
+use Digest::MD5;
+use Net::SSH qw(ssh);
+
+# pull in configuration
+use vars qw($dsn $user $pass $mp3path $port);
+use vars qw($override_query $fileno_query);
+use vars qw(%extension2type);
+require "/etc/iceplex.conf";
+
+#detect .pls or .m3u filetype
+$0 =~ /\.(pls|m3u)$/i or die "must be named with .pls or .m3u extension";
+my $extension = lc($1);
+
+#connect to database
+my $dbh = DBI->connect($dsn, $user, $pass) or die $DBI::errstr;
+
+#pick a server
+my $server = pick_server();
+
+#get customer & user from client browser
+my $cgi = new CGI;
+$cgi->param('customer') =~ /^(\d{1,10})$/ or die 'illegal customer numer';
+my $customer = sprintf("%6d", $1); #!! how many digits in customer #?
+$cgi->param('user') =~ /^(\d{1,10})$/ or die 'illegal user numer';
+my $user = sprintf("%4d", $1); #!! how many digits in user #?
+
+#get file number
+my $fileno = '';
+if ( $override_query ) {
+  my $sth = $dbh->prepare( $override_query ) or die $dbh->errstr;
+  $sth->execute($customer, $user) or die $sth->errstr;
+  my $row = $sth->fetchrow_arrayref;
+  $fileno = $row->[0] if $row;
+}
+if ( !length($fileno) && $fileno_query ) {
+  my $sth = $dbh->prepare( $fileno_query ) or die $dbh->errstr;
+  $sth->execute($customer, $user) or die $sth->errstr;
+  my $row = $sth->fetchrow_arrayref;
+  die "No files for user $user of customer $customer" unless $row;
+  $fileno = $row->[0];
+}
+$fileno = '000' unless length($fileno); #default
+
+#genarate filename
+my $filename = "$mp3path/$customer-$user-$fileno.mp3";
+
+#disconnect from database
+$dbh->disconnect;
+
+#generate a mountpoint
+my $mountpoint = md5_hex($cgi->remote_host. $$. time. int(rand(4294967296)));
+
+#signal encoder to start streaming to mountpoint & wait for confirmation
+ssh($server, 'yashout', $filename, $mountpoint );
+
+#send file back to client browser
+
+print $cgi->header( -type => $extension2type{$extension} );
+print "[playlist]\nNumberOfEntries=1\n" if $extension eq 'pls';
+print "http://$server:$port/$mountpoint\n";
+
+###
+# subroutiens
+###
+
+sub pick_server {
+  my $sth = $dbh->prepare(
+    "SELECT servername FROM iceplex_servers ".
+    "WHERE status = 'online' ".
+    "ORDER BY listeners ASC LIMIT 1"
+  ) or die $dbh->errstr;
+  $sth->execute() or die $sth->errstr;
+  my $row = $sth->fetchrow_arrayref;
+  die "No servers online!" unless $row;
+  $row->[0];
+}
+
diff --git a/yashout b/yashout
new file mode 100644 (file)
index 0000000..6bad0f0
--- /dev/null
+++ b/yashout
@@ -0,0 +1,11 @@
+#!/usr/bin/perl
+#
+# yashout
+#   Usage: yashout filename mountpoint
+#
+# Copyright (c) 2003 Ivan Kohler
+# All rights reserved.
+# This program is free software; you can redistribute it and/or modify it under
+# the same terms as Perl itself.
+
+use Shout;