added support for ShoutCast servers

This commit is contained in:
darkeye 2001-09-09 11:27:31 +00:00
parent 45abdd4c47
commit d8d71099e2
9 changed files with 773 additions and 136 deletions

View File

@ -56,27 +56,21 @@ static const char fileid[] = "$Id$";
void void
CastSink :: init ( TcpSocket * socket, CastSink :: init ( TcpSocket * socket,
const char * password, const char * password,
const char * mountPoint,
unsigned int bitRate, unsigned int bitRate,
const char * name, const char * name,
const char * description,
const char * url, const char * url,
const char * genre, const char * genre,
bool isPublic, bool isPublic,
const char * remoteDumpFile,
unsigned int bufferDuration ) unsigned int bufferDuration )
throw ( Exception ) throw ( Exception )
{ {
this->socket = socket; this->socket = socket;
this->password = Util::strDup( password); this->password = Util::strDup( password);
this->mountPoint = Util::strDup( mountPoint);
this->bitRate = bitRate; this->bitRate = bitRate;
this->name = name ? Util::strDup( name) : 0; this->name = name ? Util::strDup( name) : 0;
this->description = description ? Util::strDup( description) : 0;
this->url = url ? Util::strDup( url) : 0; this->url = url ? Util::strDup( url) : 0;
this->genre = genre ? Util::strDup( genre) : 0; this->genre = genre ? Util::strDup( genre) : 0;
this->isPublic = isPublic; this->isPublic = isPublic;
this->remoteDumpFile = remoteDumpFile ? Util::strDup( remoteDumpFile) : 0;
this->bufferDuration = bufferDuration; this->bufferDuration = bufferDuration;
bufferedSink = new BufferedSink( socket, bufferedSink = new BufferedSink( socket,
@ -96,22 +90,15 @@ CastSink :: strip ( void ) throw ( Exception )
} }
delete[] password; delete[] password;
delete[] mountPoint;
if ( name ) { if ( name ) {
delete[] name; delete[] name;
} }
if ( description ) {
delete[] description;
}
if ( url ) { if ( url ) {
delete[] url; delete[] url;
} }
if ( genre ) { if ( genre ) {
delete[] genre; delete[] genre;
} }
if ( remoteDumpFile ) {
delete[] remoteDumpFile;
}
} }
@ -144,6 +131,9 @@ CastSink :: open ( void ) throw ( Exception )
$Source$ $Source$
$Log$ $Log$
Revision 1.5 2001/09/09 11:27:31 darkeye
added support for ShoutCast servers
Revision 1.4 2001/08/29 21:08:30 darkeye Revision 1.4 2001/08/29 21:08:30 darkeye
made some description options in the darkice config file optional made some description options in the darkice config file optional

View File

@ -82,26 +82,11 @@ class CastSink : public Sink
*/ */
char * password; char * password;
/**
* Mount point of the stream on the server.
*/
char * mountPoint;
/**
* Remote dump file if any.
*/
char * remoteDumpFile;
/** /**
* Name of the stream. * Name of the stream.
*/ */
char * name; char * name;
/**
* Description of the stream.
*/
char * description;
/** /**
* URL associated with the stream. * URL associated with the stream.
*/ */
@ -127,10 +112,7 @@ class CastSink : public Sink
* *
* @param socket socket connection to the server. * @param socket socket connection to the server.
* @param password password to the server. * @param password password to the server.
* @param mountPoint mount point of the stream on the server.
* @param remoteDumpFile remote dump file (may be NULL).
* @param name name of the stream. * @param name name of the stream.
* @param description description of the stream.
* @param url URL associated with the stream. * @param url URL associated with the stream.
* @param genre genre of the stream. * @param genre genre of the stream.
* @param bitRate bitrate of the stream (e.g. mp3 bitrate). * @param bitRate bitrate of the stream (e.g. mp3 bitrate).
@ -142,14 +124,11 @@ class CastSink : public Sink
void void
init ( TcpSocket * socket, init ( TcpSocket * socket,
const char * password, const char * password,
const char * mountPoint,
unsigned int bitRate, unsigned int bitRate,
const char * name, const char * name,
const char * description,
const char * url, const char * url,
const char * genre, const char * genre,
bool isPublic, bool isPublic,
const char * remoteDumpFile,
unsigned int bufferDuration ) unsigned int bufferDuration )
throw ( Exception ); throw ( Exception );
@ -214,10 +193,7 @@ class CastSink : public Sink
* *
* @param socket socket connection to the server. * @param socket socket connection to the server.
* @param password password to the server. * @param password password to the server.
* @param mountPoint mount point of the stream on the server.
* @param remoteDumpFile remote dump file (may be NULL).
* @param name name of the stream. * @param name name of the stream.
* @param description description of the stream.
* @param url URL associated with the stream. * @param url URL associated with the stream.
* @param genre genre of the stream. * @param genre genre of the stream.
* @param bitRate bitrate of the stream (e.g. mp3 bitrate). * @param bitRate bitrate of the stream (e.g. mp3 bitrate).
@ -229,27 +205,21 @@ class CastSink : public Sink
inline inline
CastSink ( TcpSocket * socket, CastSink ( TcpSocket * socket,
const char * password, const char * password,
const char * mountPoint,
unsigned int bitRate, unsigned int bitRate,
const char * name = 0, const char * name = 0,
const char * description = 0,
const char * url = 0, const char * url = 0,
const char * genre = 0, const char * genre = 0,
bool isPublic = false, bool isPublic = false,
const char * remoteDumpFile = 0,
unsigned int bufferDuration = 10 ) unsigned int bufferDuration = 10 )
throw ( Exception ) throw ( Exception )
{ {
init( socket, init( socket,
password, password,
mountPoint,
bitRate, bitRate,
name, name,
description,
url, url,
genre, genre,
isPublic, isPublic,
remoteDumpFile,
bufferDuration ); bufferDuration );
} }
@ -264,14 +234,11 @@ class CastSink : public Sink
{ {
init( cs.socket.get(), init( cs.socket.get(),
cs.password, cs.password,
cs.mountPoint,
cs.bitRate, cs.bitRate,
cs.name, cs.name,
cs.description,
cs.url, cs.url,
cs.genre, cs.genre,
cs.isPublic, cs.isPublic,
cs.remoteDumpFile,
cs.bufferDuration ); cs.bufferDuration );
} }
@ -301,14 +268,11 @@ class CastSink : public Sink
Sink::operator=( cs ); Sink::operator=( cs );
init( cs.socket.get(), init( cs.socket.get(),
cs.password, cs.password,
cs.mountPoint,
cs.bitRate, cs.bitRate,
cs.name, cs.name,
cs.description,
cs.url, cs.url,
cs.genre, cs.genre,
cs.isPublic, cs.isPublic,
cs.remoteDumpFile,
cs.bufferDuration ); cs.bufferDuration );
} }
return *this; return *this;
@ -400,28 +364,6 @@ class CastSink : public Sink
return password; return password;
} }
/**
* Get the mount point of the stream on the server.
*
* @return the mount point of the stream on the server.
*/
inline const char *
getMountPoint ( void ) const throw ()
{
return mountPoint;
}
/**
* Get the remote dump file if any.
*
* @return the remote dump file. May be NULL.
*/
inline const char *
getRemoteDumpFile ( void ) const throw ()
{
return remoteDumpFile;
}
/** /**
* Get the name of the stream. * Get the name of the stream.
* *
@ -433,17 +375,6 @@ class CastSink : public Sink
return name; return name;
} }
/**
* Get the description of the stream.
*
* @return the description of the stream.
*/
inline const char *
getDescription ( void ) const throw ()
{
return description;
}
/** /**
* Get the URL associated with the stream. * Get the URL associated with the stream.
* *
@ -516,6 +447,9 @@ class CastSink : public Sink
$Source$ $Source$
$Log$ $Log$
Revision 1.6 2001/09/09 11:27:31 darkeye
added support for ShoutCast servers
Revision 1.5 2001/08/29 21:08:30 darkeye Revision 1.5 2001/08/29 21:08:30 darkeye
made some description options in the darkice config file optional made some description options in the darkice config file optional

View File

@ -72,6 +72,8 @@
#include "Util.h" #include "Util.h"
#include "IceCast.h"
#include "ShoutCast.h"
#include "DarkIce.h" #include "DarkIce.h"
@ -146,31 +148,33 @@ DarkIce :: init ( const Config & config ) throw ( Exception )
channel ); channel );
encConnector = new Connector( dsp.get()); encConnector = new Connector( dsp.get());
configLameLib( config, bufferSecs); configIceCast( config, bufferSecs);
configShoutCast( config, bufferSecs);
} }
/*------------------------------------------------------------------------------ /*------------------------------------------------------------------------------
* Look for the lame library outputs from the config file. * Look for the IceCast stream outputs in the config file
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void
DarkIce :: configLameLib ( const Config & config, DarkIce :: configIceCast ( const Config & config,
unsigned int bufferSecs ) unsigned int bufferSecs )
throw ( Exception ) throw ( Exception )
{ {
// look for lame encoder output streams, sections [lamelib0], [lamelib1]... // look for IceCast encoder output streams,
char lame[] = "lame "; // sections [icecast-0], [icecast-1], ...
size_t lameLen = Util::strLen( lame); char stream[] = "icecast- ";
size_t streamLen = Util::strLen( stream);
unsigned int u; unsigned int u;
for ( u = 0; u < maxOutput; ++u ) { for ( u = 0; u < maxOutput; ++u ) {
const ConfigSection * cs; const ConfigSection * cs;
const char * str; const char * str;
// ugly hack to change the section name to "lame0", "lame1", etc. // ugly hack to change the section name to "stream0", "stream1", etc.
lame[lameLen-1] = '0' + u; stream[streamLen-1] = '0' + u;
if ( !(cs = config.get( lame)) ) { if ( !(cs = config.get( stream)) ) {
break; break;
} }
@ -188,13 +192,15 @@ DarkIce :: configLameLib ( const Config & config,
unsigned int lowpass = 0; unsigned int lowpass = 0;
unsigned int highpass = 0; unsigned int highpass = 0;
str = cs->getForSure( "bitrate", " missing in section ", lame); str = cs->getForSure("bitrate", " missing in section ", stream);
bitrate = Util::strToL( str); bitrate = Util::strToL( str);
server = cs->getForSure( "server", " missing in section ", lame); server = cs->getForSure( "server", " missing in section ", stream);
str = cs->getForSure( "port", " missing in section ", lame); str = cs->getForSure( "port", " missing in section ", stream);
port = Util::strToL( str); port = Util::strToL( str);
password = cs->getForSure( "password", " missing in section ", lame); password = cs->getForSure("password"," missing in section ",stream);
mountPoint = cs->getForSure( "mountPoint"," missing in section ",lame); mountPoint = cs->getForSure( "mountPoint",
" missing in section ",
stream);
remoteDumpFile = cs->get( "remoteDumpFile"); remoteDumpFile = cs->get( "remoteDumpFile");
name = cs->get( "name"); name = cs->get( "name");
description = cs->get("description"); description = cs->get("description");
@ -217,25 +223,120 @@ DarkIce :: configLameLib ( const Config & config,
reportEvent( 6, "using buffer size", bs); reportEvent( 6, "using buffer size", bs);
// streaming related stuff // streaming related stuff
lameLibOuts[u].socket = new TcpSocket( server, port); lameLibOuts[u].socket = new TcpSocket( server, port);
lameLibOuts[u].ice = new IceCast( lameLibOuts[u].socket.get(), lameLibOuts[u].server = new IceCast( lameLibOuts[u].socket.get(),
password, password,
mountPoint, mountPoint,
bitrate, bitrate,
name, name,
description, description,
url, url,
genre, genre,
isPublic, isPublic,
remoteDumpFile ); remoteDumpFile );
lameLibOuts[u].encoder = new LameLibEncoder( lameLibOuts[u].ice.get(), lameLibOuts[u].encoder = new LameLibEncoder(lameLibOuts[u].server.get(),
dsp.get(), dsp.get(),
bitrate, bitrate,
dsp->getSampleRate(), dsp->getSampleRate(),
dsp->getChannel(), dsp->getChannel(),
lowpass, lowpass,
highpass ); highpass );
encConnector->attach( lameLibOuts[u].encoder.get());
}
noLameLibOuts = u;
}
/*------------------------------------------------------------------------------
* Look for the ShoutCast stream outputs in the config file
*----------------------------------------------------------------------------*/
void
DarkIce :: configShoutCast ( const Config & config,
unsigned int bufferSecs )
throw ( Exception )
{
// look for IceCast encoder output streams,
// sections [shoutcast-0], [shoutcast-1], ...
char stream[] = "shoutcast- ";
size_t streamLen = Util::strLen( stream);
unsigned int u;
for ( u = 0; u < maxOutput; ++u ) {
const ConfigSection * cs;
const char * str;
// ugly hack to change the section name to "stream0", "stream1", etc.
stream[streamLen-1] = '0' + u;
if ( !(cs = config.get( stream)) ) {
break;
}
unsigned int bitrate = 0;
const char * server = 0;
unsigned int port = 0;
const char * password = 0;
const char * name = 0;
const char * url = 0;
const char * genre = 0;
bool isPublic = false;
unsigned int lowpass = 0;
unsigned int highpass = 0;
const char * irc = 0;
const char * aim = 0;
const char * icq = 0;
str = cs->getForSure("bitrate", " missing in section ", stream);
bitrate = Util::strToL( str);
server = cs->getForSure( "server", " missing in section ", stream);
str = cs->getForSure( "port", " missing in section ", stream);
port = Util::strToL( str);
password = cs->getForSure("password"," missing in section ",stream);
name = cs->get( "name");
url = cs->get( "url");
genre = cs->get( "genre");
str = cs->get( "public");
isPublic = str ? (Util::strEq( str, "yes") ? true : false) : false;
str = cs->get( "lowpass");
lowpass = str ? Util::strToL( str) : 0;
str = cs->get( "highpass");
highpass = str ? Util::strToL( str) : 0;
irc = cs->get( "irc");
aim = cs->get( "aim");
icq = cs->get( "icq");
// go on and create the things
// encoder related stuff
unsigned int bs = bufferSecs *
(dsp->getBitsPerSample() / 8) *
dsp->getChannel() *
dsp->getSampleRate();
reportEvent( 6, "using buffer size", bs);
// streaming related stuff
lameLibOuts[u].socket = new TcpSocket( server, port);
lameLibOuts[u].server = new ShoutCast( lameLibOuts[u].socket.get(),
password,
bitrate,
name,
url,
genre,
isPublic,
irc,
aim,
icq );
lameLibOuts[u].encoder = new LameLibEncoder(lameLibOuts[u].server.get(),
dsp.get(),
bitrate,
dsp->getSampleRate(),
dsp->getChannel(),
lowpass,
highpass );
encConnector->attach( lameLibOuts[u].encoder.get()); encConnector->attach( lameLibOuts[u].encoder.get());
} }
@ -376,6 +477,9 @@ DarkIce :: run ( void ) throw ( Exception )
$Source$ $Source$
$Log$ $Log$
Revision 1.17 2001/09/09 11:27:31 darkeye
added support for ShoutCast servers
Revision 1.16 2001/09/05 20:11:15 darkeye Revision 1.16 2001/09/05 20:11:15 darkeye
removed dependency on locally stored SGI STL header files removed dependency on locally stored SGI STL header files
now compiler-supplied C++ library STL header files are used now compiler-supplied C++ library STL header files are used

View File

@ -57,7 +57,7 @@
#include "Connector.h" #include "Connector.h"
#include "LameLibEncoder.h" #include "LameLibEncoder.h"
#include "TcpSocket.h" #include "TcpSocket.h"
#include "IceCast.h" #include "CastSink.h"
#include "Config.h" #include "Config.h"
@ -90,7 +90,7 @@ class DarkIce : public virtual Referable, public virtual Reporter
typedef struct { typedef struct {
Ref<LameLibEncoder> encoder; Ref<LameLibEncoder> encoder;
Ref<TcpSocket> socket; Ref<TcpSocket> socket;
Ref<IceCast> ice; Ref<CastSink> server;
} LameLibOutput; } LameLibOutput;
/** /**
@ -139,7 +139,7 @@ class DarkIce : public virtual Referable, public virtual Reporter
init ( const Config & config ) throw ( Exception ); init ( const Config & config ) throw ( Exception );
/** /**
* Look for the lame library outputs from the config file. * Look for the icecast stream outputs from the config file.
* Called from init() * Called from init()
* *
* @param config the config Object to read initialization * @param config the config Object to read initialization
@ -147,9 +147,21 @@ class DarkIce : public virtual Referable, public virtual Reporter
* @exception Exception * @exception Exception
*/ */
void void
configLameLib ( const Config & config, configIceCast ( const Config & config,
unsigned int bufferSecs ) throw ( Exception ); unsigned int bufferSecs ) throw ( Exception );
/**
* Look for the shoutcast stream outputs from the config file.
* Called from init()
*
* @param config the config Object to read initialization
* information from.
* @exception Exception
*/
void
configShoutCast ( const Config & config,
unsigned int bufferSecs ) throw ( Exception );
/** /**
* Set POSIX real-time scheduling for the encoding process, * Set POSIX real-time scheduling for the encoding process,
* if user permissions enable it. * if user permissions enable it.
@ -269,6 +281,9 @@ class DarkIce : public virtual Referable, public virtual Reporter
$Source$ $Source$
$Log$ $Log$
Revision 1.10 2001/09/09 11:27:31 darkeye
added support for ShoutCast servers
Revision 1.9 2001/08/30 17:25:56 darkeye Revision 1.9 2001/08/30 17:25:56 darkeye
renamed configure.h to config.h renamed configure.h to config.h

View File

@ -49,6 +49,7 @@
#include "Exception.h" #include "Exception.h"
#include "Source.h" #include "Source.h"
#include "Sink.h" #include "Sink.h"
#include "Util.h"
#include "IceCast.h" #include "IceCast.h"
@ -77,6 +78,37 @@ static const char fileid[] = "$Id$";
/*------------------------------------------------------------------------------ /*------------------------------------------------------------------------------
* Initialize the object * Initialize the object
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void
IceCast :: init ( const char * mountPoint,
const char * description,
const char * remoteDumpFile )
throw ( Exception )
{
this->mountPoint = Util::strDup( mountPoint);
this->description = description ? Util::strDup( description) : 0;
this->remoteDumpFile = remoteDumpFile ? Util::strDup( remoteDumpFile) : 0;
}
/*------------------------------------------------------------------------------
* De-initialize the object
*----------------------------------------------------------------------------*/
void
IceCast :: strip ( void ) throw ( Exception )
{
delete[] mountPoint;
if ( description ) {
delete[] description;
}
if ( remoteDumpFile ) {
delete[] remoteDumpFile;
}
}
/*------------------------------------------------------------------------------
* Log in to the IceCast server
*----------------------------------------------------------------------------*/
bool bool
IceCast :: sendLogin ( void ) throw ( Exception ) IceCast :: sendLogin ( void ) throw ( Exception )
{ {
@ -94,7 +126,7 @@ IceCast :: sendLogin ( void ) throw ( Exception )
} }
/* send the request, a string like: /* send the request, a string like:
* "SOURCE <password> /<mountpoint>\n\n" */ * "SOURCE <password> /<mountpoint>\n" */
str = "SOURCE "; str = "SOURCE ";
sink->write( str, strlen( str)); sink->write( str, strlen( str));
str = getPassword(); str = getPassword();
@ -103,21 +135,8 @@ IceCast :: sendLogin ( void ) throw ( Exception )
sink->write( str, strlen( str)); sink->write( str, strlen( str));
str = getMountPoint(); str = getMountPoint();
sink->write( str, strlen( str)); sink->write( str, strlen( str));
str = "\n\n"; str = "\n";
sink->write( str, strlen( str)); sink->write( str, strlen( str));
sink->flush();
/* read the anticipated response: "OK" */
len = source->read( resp, STRBUF_SIZE);
if ( len < 2 || resp[0] != 'O' || resp[1] != 'K' ) {
return false;
}
/* suck anything that the other side has to say */
while ( source->canRead( 0, 0) &&
(len = source->read( resp, STRBUF_SIZE)) ) {
;
}
/* send the x-audiocast headers */ /* send the x-audiocast headers */
if ( getName() ) { if ( getName() ) {
@ -194,6 +213,9 @@ IceCast :: sendLogin ( void ) throw ( Exception )
$Source$ $Source$
$Log$ $Log$
Revision 1.7 2001/09/09 11:27:31 darkeye
added support for ShoutCast servers
Revision 1.6 2001/08/30 17:25:56 darkeye Revision 1.6 2001/08/30 17:25:56 darkeye
renamed configure.h to config.h renamed configure.h to config.h

View File

@ -60,6 +60,43 @@ class IceCast : public CastSink
{ {
private: private:
/**
* Mount point of the stream on the server.
*/
char * mountPoint;
/**
* Remote dump file if any.
*/
char * remoteDumpFile;
/**
* Description of the stream.
*/
char * description;
/**
* Initalize the object.
*
* @param mountPoint mount point of the stream on the server.
* @param remoteDumpFile remote dump file (may be NULL).
* @param description description of the stream.
* @exception Exception
*/
void
init ( const char * mountPoint,
const char * description,
const char * remoteDumpFile )
throw ( Exception );
/**
* De-initalize the object.
*
* @exception Exception
*/
void
strip ( void ) throw ( Exception );
protected: protected:
@ -118,16 +155,14 @@ class IceCast : public CastSink
throw ( Exception ) throw ( Exception )
: CastSink( socket, : CastSink( socket,
password, password,
mountPoint,
bitRate, bitRate,
name, name,
description,
url, url,
genre, genre,
isPublic, isPublic,
remoteDumpFile,
bufferDuration ) bufferDuration )
{ {
init( mountPoint, description, remoteDumpFile);
} }
/** /**
@ -139,6 +174,9 @@ class IceCast : public CastSink
IceCast( const IceCast & cs ) throw ( Exception ) IceCast( const IceCast & cs ) throw ( Exception )
: CastSink( cs ) : CastSink( cs )
{ {
init( cs.getMountPoint(),
cs.getDescription(),
cs.getRemoteDumpFile() );
} }
/** /**
@ -149,6 +187,7 @@ class IceCast : public CastSink
inline virtual inline virtual
~IceCast( void ) throw ( Exception ) ~IceCast( void ) throw ( Exception )
{ {
strip();
} }
/** /**
@ -162,10 +201,48 @@ class IceCast : public CastSink
operator= ( const IceCast & cs ) throw ( Exception ) operator= ( const IceCast & cs ) throw ( Exception )
{ {
if ( this != &cs ) { if ( this != &cs ) {
strip();
CastSink::operator=( cs ); CastSink::operator=( cs );
init( cs.getMountPoint(),
cs.getDescription(),
cs.getRemoteDumpFile() );
} }
return *this; return *this;
} }
/**
* Get the mount point of the stream on the server.
*
* @return the mount point of the stream on the server.
*/
inline const char *
getMountPoint ( void ) const throw ()
{
return mountPoint;
}
/**
* Get the remote dump file if any.
*
* @return the remote dump file. May be NULL.
*/
inline const char *
getRemoteDumpFile ( void ) const throw ()
{
return remoteDumpFile;
}
/**
* Get the description of the stream.
*
* @return the description of the stream.
*/
inline const char *
getDescription ( void ) const throw ()
{
return description;
}
}; };
@ -184,6 +261,9 @@ class IceCast : public CastSink
$Source$ $Source$
$Log$ $Log$
Revision 1.6 2001/09/09 11:27:31 darkeye
added support for ShoutCast servers
Revision 1.5 2001/08/29 21:08:30 darkeye Revision 1.5 2001/08/29 21:08:30 darkeye
made some description options in the darkice config file optional made some description options in the darkice config file optional

View File

@ -17,6 +17,8 @@ darkice_SOURCES = AudioEncoder.h\
Exception.h\ Exception.h\
IceCast.cpp\ IceCast.cpp\
IceCast.h\ IceCast.h\
ShoutCast.cpp\
ShoutCast.h\
LameLibEncoder.cpp\ LameLibEncoder.cpp\
LameLibEncoder.h\ LameLibEncoder.h\
OssDspSource.cpp\ OssDspSource.cpp\

View File

@ -0,0 +1,224 @@
/*------------------------------------------------------------------------------
Copyright (c) 2000 Tyrell Corporation. All rights reserved.
Tyrell DarkIce
File : ShoutCast.cpp
Version : $Revision$
Author : $Author$
Location : $Source$
Copyright notice:
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 files */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_STDIO_H
#include <stdio.h>
#else
#error need stdio.h
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#else
#error need string.h
#endif
#include "Exception.h"
#include "Source.h"
#include "Sink.h"
#include "Util.h"
#include "ShoutCast.h"
/* =================================================== local data structures */
/* ================================================ local constants & macros */
/*------------------------------------------------------------------------------
* File identity
*----------------------------------------------------------------------------*/
static const char fileid[] = "$Id$";
/*------------------------------------------------------------------------------
* Size of string conversion buffer
*----------------------------------------------------------------------------*/
#define STRBUF_SIZE 32
/* =============================================== local function prototypes */
/* ============================================================= module code */
/*------------------------------------------------------------------------------
* Initialize the object
*----------------------------------------------------------------------------*/
void
ShoutCast :: init ( const char * irc,
const char * aim,
const char * icq )
throw ( Exception )
{
this->irc = irc ? Util::strDup( irc) : 0;
this->aim = aim ? Util::strDup( aim) : 0;
this->icq = icq ? Util::strDup( icq) : 0;
}
/*------------------------------------------------------------------------------
* De-initialize the object
*----------------------------------------------------------------------------*/
void
ShoutCast :: strip ( void ) throw ( Exception )
{
if ( irc ) {
delete[] irc;
}
if ( aim ) {
delete[] aim;
}
if ( icq ) {
delete[] icq;
}
}
/*------------------------------------------------------------------------------
* Log in to the ShoutCast server using the icy login scheme
*----------------------------------------------------------------------------*/
bool
ShoutCast :: sendLogin ( void ) throw ( Exception )
{
Sink * sink = getSink();
Source * source = getSocket();
const char * str;
char resp[STRBUF_SIZE];
unsigned int len;
if ( !source->isOpen() ) {
return false;
}
if ( !sink->isOpen() ) {
return false;
}
/* first line is the password in itself */
str = getPassword();
sink->write( str, strlen( str));
str = "\n";
sink->write( str, strlen( str));
sink->flush();
/* send the icy headers */
if ( getName() ) {
str = "icy-name:";
sink->write( str, strlen( str));
str = getName();
sink->write( str, strlen( str));
}
if ( getUrl() ) {
str = "\nicy-url:";
sink->write( str, strlen( str));
str = getUrl();
sink->write( str, strlen( str));
}
if ( getGenre() ) {
str = "\nicy-genre:";
sink->write( str, strlen( str));
str = getGenre();
sink->write( str, strlen( str));
}
if ( getIrc() ) {
str = "\nicy-irc:";
sink->write( str, strlen( str));
str = getIrc();
sink->write( str, strlen( str));
}
if ( getAim() ) {
str = "\nicy-aim:";
sink->write( str, strlen( str));
str = getAim();
sink->write( str, strlen( str));
}
if ( getIcq() ) {
str = "\nicy-icq:";
sink->write( str, strlen( str));
str = getIcq();
sink->write( str, strlen( str));
}
str = "\nicy-br:";
sink->write( str, strlen( str));
if ( snprintf( resp, STRBUF_SIZE, "%d", getBitRate()) == -1 ) {
throw Exception( __FILE__, __LINE__, "snprintf overflow");
}
sink->write( resp, strlen( resp));
str = "\nicy-pub:";
sink->write( str, strlen( str));
str = getIsPublic() ? "yes" : "no";
sink->write( str, strlen( str));
str = "\n\n";
sink->write( str, strlen( str));
sink->flush();
/* read the anticipated response: "OK" */
len = source->read( resp, STRBUF_SIZE);
if ( len < 2 || resp[0] != 'O' || resp[1] != 'K' ) {
return false;
}
/* suck anything that the other side has to say */
while ( source->canRead( 0, 0) &&
(len = source->read( resp, STRBUF_SIZE)) ) {
;
}
return true;
}
/*------------------------------------------------------------------------------
$Source$
$Log$
Revision 1.1 2001/09/09 11:27:31 darkeye
added support for ShoutCast servers
------------------------------------------------------------------------------*/

View File

@ -0,0 +1,266 @@
/*------------------------------------------------------------------------------
Copyright (c) 2000 Tyrell Corporation. All rights reserved.
Tyrell DarkIce
File : ShoutCast.h
Version : $Revision$
Author : $Author$
Location : $Source$
Copyright notice:
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.
------------------------------------------------------------------------------*/
#ifndef SHOUT_CAST_H
#define SHOUT_CAST_H
#ifndef __cplusplus
#error This is a C++ include file
#endif
/* ============================================================ include files */
#include "Sink.h"
#include "TcpSocket.h"
#include "CastSink.h"
/* ================================================================ constants */
/* =================================================================== macros */
/* =============================================================== data types */
/**
* Class representing output to a ShoutCast server with
* icy login
*
* @author $Author$
* @version $Revision$
*/
class ShoutCast : public CastSink
{
private:
/**
* IRC info string for the stream
*/
char * irc;
/**
* AIM info string for the stream
*/
char * aim;
/**
* ICQ info string for the stream
*/
char * icq;
/**
* Initalize the object.
*
* @param irc IRC info string for the stream.
* @param aim AIM info string for the stream.
* @param icq ICQ info string for the stream.
* @exception Exception
*/
void
init ( const char * irc,
const char * aim,
const char * icq )
throw ( Exception );
/**
* De-initalize the object.
*
* @exception Exception
*/
void
strip ( void ) throw ( Exception );
protected:
/**
* Default constructor. Always throws an Exception.
*
* @exception Exception
*/
inline
ShoutCast ( void ) throw ( Exception )
{
throw Exception( __FILE__, __LINE__);
}
/**
* Log in to the server using the socket avialable.
*
* @return true if login was successful, false otherwise.
* @exception Exception
*/
virtual bool
sendLogin ( void ) throw ( Exception );
public:
/**
* Constructor.
*
* @param socket socket connection to the server.
* @param password password to the server.
* @param name name of the stream.
* @param url URL associated with the stream.
* @param genre genre of the stream.
* @param bitRate bitrate of the stream (e.g. mp3 bitrate).
* @param isPublic is the stream public?
* @param irc IRC info string for the stream.
* @param aim AIM info string for the stream.
* @param icq ICQ info string for the stream.
* @param bufferDuration duration of the BufferedSink buffer
* in seconds.
* @exception Exception
*/
inline
ShoutCast ( TcpSocket * socket,
const char * password,
unsigned int bitRate,
const char * name = 0,
const char * url = 0,
const char * genre = 0,
bool isPublic = false,
const char * irc = 0,
const char * aim = 0,
const char * icq = 0,
unsigned int bufferDuration = 10 )
throw ( Exception )
: CastSink( socket,
password,
bitRate,
name,
url,
genre,
isPublic,
bufferDuration )
{
init( irc, aim, icq);
}
/**
* Copy constructor.
*
* @param cs the ShoutCast to copy.
*/
inline
ShoutCast( const ShoutCast & cs ) throw ( Exception )
: CastSink( cs )
{
init( cs.getIrc(), cs.getAim(), cs.getIcq());
}
/**
* Destructor.
*
* @exception Exception
*/
inline virtual
~ShoutCast( void ) throw ( Exception )
{
strip();
}
/**
* Assignment operator.
*
* @param cs the ShoutCast to assign this to.
* @return a reference to this ShoutCast.
* @exception Exception
*/
inline virtual ShoutCast &
operator= ( const ShoutCast & cs ) throw ( Exception )
{
if ( this != &cs ) {
strip();
CastSink::operator=( cs );
init( cs.getIrc(), cs.getAim(), cs.getIcq());
}
return *this;
}
/**
* Get the IRC info string for the stream.
*
* @return the IRC info string for the stream.
*/
inline const char *
getIrc ( void ) const throw ()
{
return irc;
}
/**
* Get the AIM info string for the stream.
*
* @return the AIM info string for the stream.
*/
inline const char *
getAim ( void ) const throw ()
{
return aim;
}
/**
* Get the ICQ info string for the stream.
*
* @return the ICQ info string for the stream.
*/
inline const char *
getIcq ( void ) const throw ()
{
return icq;
}
};
/* ================================================= external data structures */
/* ====================================================== function prototypes */
#endif /* SHOUT_CAST_H */
/*------------------------------------------------------------------------------
$Source$
$Log$
Revision 1.1 2001/09/09 11:27:31 darkeye
added support for ShoutCast servers
------------------------------------------------------------------------------*/