#!/usr/bin/perl

use strict;
use Shout;

$| = 1;

my $kbitrate = shift @ARGV;
my $mount = shift @ARGV || '/streambox';
my $desc = shift @ARGV || 'StreamBOX Live';
my $icecast_server = shift @ARGV || 'localhost';
my $icecast_port = shift @ARGV || '8000';
my $password = shift @ARGV || 'streambox';

unless ($kbitrate) {
	die ("ARGUMENTS: kilobitrate (required)  [mountpoint (default $mount)] [description (default $desc)] [server (default $icecast_server)] [port (default $icecast_port)] [password (default $password)]\n");
}

my $errors = 0;
my $timeout = 2;

my $conn = &make_conn($kbitrate)
	or die("\033[01;31mCan't establish connection\033[m\ \033[01;32m(Server running / Password correct?)\033[m\n");

my ($buff, $len);
my $chunksize = 4096;
my $fraction = '';
my $i = 1;
my $starttime = time;
print '[00:00] ';

CHUNK: while ($len = read STDIN, $buff, $chunksize) {

	if ($errors > $timeout) {
		warn("\033[01;31mToo many connection errors,\033[m\ \033[01;32mtrying to re-establish connection\033[m\n");
		$errors = 0;
		$conn->disconnect;
		
		$conn = &make_conn($kbitrate)
			or die("\033[01;31mCan't re-establish connection\033[m\n");
	}

	print ".";
	$buff = $fraction . $buff
		if $fraction;
	if ($len < $chunksize) {
		warn("\033[01;31mIncoming buffer underfilled;\033[m\ \033[01;32msleeping 1 sec\033[m\n");
		sleep 1;
		$chunksize -= $len;
		$fraction = $buff;
		next CHUNK;
	}
	$fraction = '';
	$chunksize = 4096;
	unless ($conn->sendData($buff)) {
		my $error = $conn->error;
		warn("\033[01;31mCould not send data: $error\033[m\n");
		$errors++;
		next CHUNK;
	} else { $errors = 0; $i++; }

	if ($i % 40 == 0) {
		print "\n";
		my $now = time;
		my $timediff = $now - $starttime;
		my $mins = int($timediff / 60);
		my $secs = $timediff % 60;
		$mins = '0'.$mins if $mins < 10;
		$secs = '0'.$secs if $secs < 10;
		print "[$mins:$secs] ";
	}

	
	$conn->sleep;
} # end CHUNK loop

warn("\033[01;31mNo more incoming data, disconnecting\033[m\n");

$conn->disconnect;

exit;

sub make_conn {
        my $br = shift;

        my $streamname = "StreamBOX Live";
        warn ("\033[01;33mStarting up stream to Icecast server\033[m\n");
        my $connt = new Shout
                ip              => $icecast_server,
                port            => $icecast_port,
                mount           => $mount,
                password        => $password,
                icy_compat      => 0,
                dumpfile        => undef,
                name            => $desc,
                url             => 'http://www.egocity.net/',
                genre           => 'mixed',
                description     => $desc,
                bitrate         => $br,
                ispublic        => 0;

        $connt->connect
		or do {
			warn ("\033[01;31:mFailed to connect:\033[m ", $connt->error);
			return undef;
		};

        return $connt;
}



