diff -urN mythmusic/mythmusic/mythmusic.pro mythmusic-local/mythmusic/mythmusic.pro
--- mythmusic/mythmusic/mythmusic.pro	2003-10-05 13:17:51.000000000 +0200
+++ mythmusic-local/mythmusic/mythmusic.pro	2003-09-29 15:59:19.000000000 +0200
@@ -29,7 +29,7 @@
 HEADERS += audiooutput.h buffer.h cddecoder.h cdrip.h constants.h databasebox.h 
 HEADERS += decoder.h flacdecoder.h flacencoder.h maddecoder.h mainvisual.h
 HEADERS += metadata.h playbackbox.h playlist.h polygon.h output.h recycler.h 
-HEADERS += streaminput.h synaesthesia.h encoder.h visualize.h
+HEADERS += streaminput.h shoutcaststream.h synaesthesia.h encoder.h visualize.h
 HEADERS += treecheckitem.h visual.h vorbisdecoder.h vorbisencoder.h polygon.h
 HEADERS += bumpscope.h globalsettings.h lameencoder.h
 HEADERS += goom/filters.h goom/goomconfig.h goom/goom_core.h goom/graphic.h
@@ -39,7 +39,8 @@
 SOURCES += audiooutput.cpp cddecoder.cpp cdrip.cpp databasebox.cpp decoder.cpp 
 SOURCES += flacdecoder.cpp flacencoder.cpp maddecoder.cpp main.cpp
 SOURCES += mainvisual.cpp metadata.cpp playbackbox.cpp playlist.cpp output.cpp 
-SOURCES += recycler.cpp streaminput.cpp encoder.cpp resample.c
+SOURCES += recycler.cpp streaminput.cpp shoutcaststream.cpp 
+SOURCES += encoder.cpp resample.c
 SOURCES += synaesthesia.cpp treecheckitem.cpp vorbisdecoder.cpp lameencoder.cpp
 SOURCES += vorbisencoder.cpp visualize.cpp bumpscope.cpp globalsettings.cpp
 SOURCES += goom/filters.c goom/goom_core.c goom/graphic.c goom/tentacle3d.c
diff -urN mythmusic/mythmusic/playbackbox.cpp mythmusic-local/mythmusic/playbackbox.cpp
--- mythmusic/mythmusic/playbackbox.cpp	2003-10-05 13:17:51.000000000 +0200
+++ mythmusic-local/mythmusic/playbackbox.cpp	2003-10-05 12:14:34.000000000 +0200
@@ -7,9 +7,9 @@
 #include "metadata.h"
 #include "audiooutput.h"
 #include "constants.h"
-#include "streaminput.h"
 #include "output.h"
 #include "decoder.h"
+#include "streaminput.h"
 #include "playbackbox.h"
 #include "databasebox.h"
 #include "mainvisual.h"
@@ -531,9 +531,6 @@
         return;
     }
 
-    QUrl sourceurl(playfile);
-    QString sourcename(playfile);
-
     bool startoutput = false;
 
     if (!output)
@@ -558,25 +555,57 @@
         return;
     }
 
-    if (!sourceurl.isLocalFile()) 
+/*
+    switch StreamInput::supports(playfile) {
+    case kLocalFile:
+            input = new QFile(playfile);
+            break;
+    case kShoutcast:
+            stream = new ShoutcastStream();
+            // decoder is selected by file extension
+            playfile = "blah.mp3";
+            break;
+    default:
+            break;
+    }
+*/
+/*
+    if (stream) {
+        if (stream->initialize())
+        {
+            cout << "stream inited" << endl;
+            if (stream->start())
+                input = stream->getSocket();
+            if (!input)
+                cout << "stream not started" << endl;
+        }
+    }
+*/
+    input = new StreamInput(playfile);
+
+    cout << "'" << playfile.ascii() << "'" << endl; // DEBUG
+
+    if (! input->type())
     {
-        StreamInput streaminput(sourceurl);
-        streaminput.setup();
-        input = streaminput.socket();
-    } 
-    else
-        input = new QFile(playfile);
+        VERBOSE(VB_PLAYBACK, QString("mythmusic: error reading input "
+                        "file/stream: '%1'").arg(playfile));
+        stopAll();
+        return;
+    }
+
+    // filename extension of playfile selects decoder
+    playfile = input->name();
 
-    if (decoder && !decoder->factory()->supports(sourcename))
+    if (decoder && !decoder->factory()->supports(playfile))
         decoder = 0;
 
     if (!decoder) 
     {
-        decoder = Decoder::create(sourcename, input, output);
+        decoder = Decoder::create(playfile, input, output);
 
         if (!decoder) 
         {
-            printf("mythmusic: unsupported fileformat\n");
+            VERBOSE(VB_PLAYBACK, "mythmusic: unsupported audioformat");
             stopAll();
             return;
         }
diff -urN mythmusic/mythmusic/playbackbox.h mythmusic-local/mythmusic/playbackbox.h
--- mythmusic/mythmusic/playbackbox.h	2003-08-26 17:45:18.000000000 +0200
+++ mythmusic-local/mythmusic/playbackbox.h	2003-10-04 18:55:52.000000000 +0200
@@ -15,6 +15,7 @@
 
 class Output;
 class Decoder;
+class StreamInput;
 
 class PlaybackBox : public MythThemedDialog
 {
@@ -80,7 +81,7 @@
     
     void CycleVisualizer(void);
 
-    QIODevice *input;
+    StreamInput *input;
     Output *output;
     Decoder *decoder;
 
diff -urN mythmusic/mythmusic/shoutcaststream.cpp mythmusic-local/mythmusic/shoutcaststream.cpp
--- mythmusic/mythmusic/shoutcaststream.cpp	1970-01-01 01:00:00.000000000 +0100
+++ mythmusic-local/mythmusic/shoutcaststream.cpp	2003-10-05 13:00:56.000000000 +0200
@@ -0,0 +1,151 @@
+#include <qstring.h>
+#include <qurl.h>
+#include <qsocket.h>
+#include <qapplication.h>
+
+#include <iostream>
+using namespace std;
+
+#include "streaminput.h"
+#include "shoutcaststream.h"
+#include "mythtv/mythcontext.h"
+
+ShoutcastStream::ShoutcastStream(QUrl *url)
+                : QSocket()
+{
+    kconnected = 0;
+    streamurl = *url;
+    cout << "new shoutcast\n"; //DEBUG
+}
+
+bool ShoutcastStream::initialize()
+{
+    cout << "shoutcast: initialize\n"; //DEBUG
+    if (!streamurl.isValid())
+    {
+        return false;
+    }
+    else
+    {
+        if (streamurl.protocol() == "shoutcast")
+        {
+            streamurl.setProtocol("http");
+        }
+        else
+            return false;
+        if (!streamurl.hasPort())
+            streamurl.setPort(80);
+    }
+    return true;
+}
+
+bool ShoutcastStream::start()
+{
+    QString request;
+
+    request = "GET " + streamurl.path().utf8() + " HTTP/1.0" + "\r\n";
+    request += "Host: " + streamurl.host().utf8() + "\r\n";
+    request += "User-Agent: xmms/1.2.7\r\n";
+    request += "\r\n";
+
+    cout << "shoutcast: start '" << request.ascii() << "'\n"; //DEBUG
+
+    for (int i = 0; i < 3; i++)
+    {
+        if (openSocket())
+            break;
+    }
+    if (state() != QSocket::Connected)
+    {
+        VERBOSE(VB_NETWORK, QString("Couldn't connect to: '%1'").arg(streamurl.host()));
+        return false;
+    }
+    VERBOSE(VB_NETWORK, QString("Connected to: '%1'").arg(streamurl.host()));
+    sendRequest(request);
+    if (readlineSocket(request))
+    {
+        cout << request.ascii() << endl;
+        if (request != "ICY 200 OK\r\n")
+            return false;
+        else
+        {
+            while (bytesAvailable() < 65536)
+                usleep(100);
+        }
+    }
+    else
+        return false;
+
+    kconnected = 1;
+    return true ;
+}
+
+bool ShoutcastStream::openSocket()
+{
+    QString host = streamurl.host();
+    int port = streamurl.port();
+   
+    qApp->lock();
+    //socket = new QSocket();
+    connectToHost(host, port);
+    qApp->unlock();
+
+    int i = 0;
+    while (state() == QSocket::HostLookup ||
+           state() == QSocket::Connecting)
+    {
+        qApp->processEvents();
+
+        i++;
+        if (i > 500)
+            break;
+        usleep(50);
+    }
+        
+    if (state() != QSocket::Connected)
+        return false;
+    return true;
+}
+
+void ShoutcastStream::sendRequest(const QString request)
+{
+    writeBlock(request, request.length());
+    flush();
+    printf("\'%s\'",request.ascii()); //DEBUG
+}
+
+bool ShoutcastStream::readlineSocket(QString &request)
+{
+    int i = 0;
+    while (state() == QSocket::Connected)
+    {
+        if (canReadLine())
+        {
+            request = readLine();
+            return true;
+        }
+        i++;
+        if (i > 500)
+            break;
+        usleep(50);
+    }
+    return false;
+}
+
+Q_LONG ShoutcastStream::readBlock(char *data, long unsigned maxlen)
+{
+    cout << "shoutcast: readBlock\n"; //DEBUG
+    if (! kconnected)
+    {
+        cout << "shoutcast: readBlock N/C\n"; //DEBUG
+        if (initialize())
+        { 
+            if (! start())
+                return -1;
+        }
+        else
+            return -1;
+    }
+    return QSocket::readBlock(data, maxlen);
+}
+
diff -urN mythmusic/mythmusic/shoutcaststream.h mythmusic-local/mythmusic/shoutcaststream.h
--- mythmusic/mythmusic/shoutcaststream.h	1970-01-01 01:00:00.000000000 +0100
+++ mythmusic-local/mythmusic/shoutcaststream.h	2003-10-05 12:49:31.000000000 +0200
@@ -0,0 +1,29 @@
+#ifndef SHOUTCASTSTREAM_H
+#define SHOUTCASTSTREAM_H
+
+#include <qstring.h>
+#include <qurl.h>
+#include <qsocket.h>
+
+class ShoutcastStream : public QSocket
+{
+  public:
+    ShoutcastStream(QUrl *url);
+
+    Q_LONG readBlock(char *data, Q_ULONG maxlen);
+
+  private:
+    bool initialize();
+    bool start();
+
+    bool openSocket();
+    void closeSocket();
+    void sendRequest(const QString request);
+    bool readlineSocket(QString &request);
+
+    bool kconnected;
+    QUrl streamurl;
+    //QSocket *socket;
+    
+};
+#endif
diff -urN mythmusic/mythmusic/streaminput.cpp mythmusic-local/mythmusic/streaminput.cpp
--- mythmusic/mythmusic/streaminput.cpp	2003-10-05 13:17:51.000000000 +0200
+++ mythmusic-local/mythmusic/streaminput.cpp	2003-10-05 12:36:07.000000000 +0200
@@ -4,118 +4,171 @@
 // warranty, or liability of any kind.
 //
 
-#include "streaminput.h"
+// modified 09/2003 by Stefan Frank <sfr@gmx.net>
+// - added shoutcast streaming audio support
 
-#include <qapplication.h>
+//#include <unistd.h>
+//#include <qapplication.h>
+#include <qurl.h>
 #include <qsocket.h>
+#include <qiodevice.h>
+#include <qfile.h>
+#include <iostream>
+using namespace std;
 
+#include "streaminput.h"
+#include "shoutcaststream.h"
 
-StreamInput::StreamInput(const QUrl &source)
-    : request(0), url(source), sock(0), stage(0)
+StreamInput::StreamInput(QString playfile)
 {
-}
+    mediatype = "";
+    medianame = "";
+    device = NULL;
 
+    QUrl url(playfile);
 
-void StreamInput::setup()
-{
-    if (! url.isValid())
-	return;
+    cout << "new streaminput '" << playfile.ascii() << "'\n"; //DEBUG
+    if ( url.isValid())
+    {
+        streamurl = url;
+        QString proto = url.protocol();
+        medianame = playfile;
+        mediatype = "remote";
 
-    QString protocol = url.protocol();
-    QString host = url.host();
-    QString path = url.path();
-    int port = url.port();
+        if (url.isLocalFile())
+        {
+            mediatype = "local";
+            device = new QFile(playfile);
+        }
+        else if (proto == "shoutcast")
+        {
+            medianame = "blah.mp3";
+            device = new ShoutcastStream(&url);
+        }
+/*
+        else if (proto == "icecast")
+        {
+            medianame = "blah.ogg";
+            device = new IcecastStream(playfile);
+        }
+*/
+    }
+}
 
-    if (protocol != "mqp" || host.isNull())
-	return;
+StreamInput::~StreamInput()
+{
+    delete device;
+}
+/*
+bool StreamInput::openSocket(QUrl *source)
+{
+    QString host = source->host();
+    int port = source->port();
+   
+    qApp->lock();
+    socket = new QSocket();
+    socket->connectToHost(host, port);
+    qApp->unlock();
 
-    if (port == -1)
-	port = 42666;
+    int i = 0;
+    while (socket->state() == QSocket::HostLookup ||
+           socket->state() == QSocket::Connecting)
+    {
+        qApp->processEvents();
 
-    request = ".song " + path.utf8() + "\r\n";
+        i++;
+        if (i > 500)
+            break;
+        usleep(50);
+    }
+        
+    if (socket->state() != QSocket::Connected)
+        return false;
+    return true;
+}
 
+void StreamInput::closeSocket()
+{
+    socket->close();
+    delete socket;
 
-    sock = new QSocket;
-    connect(sock, SIGNAL(error(int)), this, SLOT(error(int)));
-    connect(sock, SIGNAL(hostFound()), this, SLOT(hostfound()));
-    connect(sock, SIGNAL(connected()), this, SLOT(connected()));
-    connect(sock, SIGNAL(readyRead()), this, SLOT(readyread()));
+}
 
-    sock->connectToHost(host, port);
 
-    while (stage != -1 && stage < 4) {
-	qDebug("processing one event: stage %d %d %ld",
-	       stage, sock->canReadLine(), sock->bytesAvailable());
-	qApp->processOneEvent();
-    }
+void StreamInput::sendRequest(const QString request)
+{
+    socket->writeBlock(request, request.length());
+    socket->flush();
+    printf("\'%s\'",request.ascii()); //DEBUG
+}
 
-    qDebug("disconnecting from socket");
-    disconnect(sock, SIGNAL(error(int)), this, SLOT(error(int)));
-    disconnect(sock, SIGNAL(hostFound()), this, SLOT(hostfound()));
-    disconnect(sock, SIGNAL(connected()), this, SLOT(connected()));
-    disconnect(sock, SIGNAL(readyRead()), this, SLOT(readyread()));
-
-    if (stage == -1) {
-	// some sort of error
-	delete sock;
-	sock = 0;
+bool StreamInput::readlineSocket(QString &request)
+{
+    int i = 0;
+    while (socket->state() == QSocket::Connected)
+    {
+        if (socket->canReadLine())
+        {
+            request = socket->readLine();
+            return true;
+        }
+        i++;
+        if (i > 500)
+            break;
+        usleep(50);
     }
+    return false;
 }
-
-
-void StreamInput::hostfound()
+*/
+bool StreamInput::open(int mode)
 {
-    qDebug("host found");
-    stage = 1;
+    if (mediatype == "local")
+        return device->open(mode);
+    return true;
 }
 
-
-void StreamInput::connected()
+void StreamInput::close()
 {
-    qDebug("connected... sending request '%s' %d", request.data(), request.length());
-
-    sock->writeBlock(request.data(), request.length());
-    sock->flush();
-
-    stage = 2;
+    device->close();
 }
 
-
-void StreamInput::readyread()
+void StreamInput::flush()
 {
-    if (stage == 2) {
-    qDebug("readyread... checking response");
-
-    if (! sock->canReadLine()) {
-	stage = -1;
-	qDebug("can't read line");
-	return;
-    }
+    device->flush();
+}
 
-    QString line = sock->readLine();
-    if (line.isEmpty()) {
-	stage = -1;
-	qDebug("line is empty");
-	return;
-    }
+Q_ULONG StreamInput::size() const
+{
+    return device->size();
+}
 
-    if (line.left(5) != "*GOOD") {
-	qDebug("server error response: %s", line.latin1());
-	stage = -1;
-	return;
-    }
+Q_LONG StreamInput::readBlock(char *data, Q_ULONG maxlen )
+{
+    cout << "streaminput: readBlock\n"; //DEBUG
+    return device->readBlock(data, maxlen);
+}
 
-    stage = 3;
-    } else if (sock->bytesAvailable() > 65536 || sock->atEnd()) {
-	stage = 4;
-    }
+Q_LONG StreamInput::writeBlock(const char *data, Q_ULONG len)
+{
+    return device->writeBlock(data, len);
 }
 
+Q_LONG StreamInput::readLine(char *data, Q_ULONG maxlen)
+{
+    return device->readLine(data, maxlen);
+}
 
-void StreamInput::error(int err)
+int StreamInput::getch()
 {
-    qDebug("socket error: %d", err);
+    return device->getch();
+}
 
-    stage = -1;
+int StreamInput::putch(int ch)
+{
+    return device->putch(ch);
 }
 
+int StreamInput::ungetch(int ch)
+{
+    return device->ungetch(ch);
+}
diff -urN mythmusic/mythmusic/streaminput.h mythmusic-local/mythmusic/streaminput.h
--- mythmusic/mythmusic/streaminput.h	2003-10-05 13:17:51.000000000 +0200
+++ mythmusic-local/mythmusic/streaminput.h	2003-10-05 12:16:36.000000000 +0200
@@ -7,35 +7,46 @@
 #ifndef INPUT_H
 #define INPUT_H
 
-class StreamInput;
-
+#include <qstring.h>
 #include <qurl.h>
 #include <qsocket.h>
 
-
-class StreamInput : public QObject
+class StreamInput : public QIODevice
 {
-    Q_OBJECT
-public:
-    StreamInput(const QUrl &);
-
-    QIODevice *socket() { return sock; }
-
-    void setup();
-
-
-private slots:
-    void hostfound();
-    void connected();
-    void readyread();
-    void error(int);
-
-
-private:
-    QCString request;
-    QUrl url;
-    QSocket *sock;
-    int stage;
+  public:
+    StreamInput(QString playfile);
+    ~StreamInput();
+
+    bool open( int mode );
+    void close();
+    void flush();
+
+    Q_ULONG size() const;
+
+    Q_LONG readBlock( char *data, Q_ULONG maxlen );
+    Q_LONG writeBlock( const char *data, Q_ULONG len );
+    Q_LONG readLine( char *data, Q_ULONG maxlen );
+
+    int getch();
+    int putch( int ch);
+    int ungetch( int ch);
+
+    QString type() { return mediatype; }
+    QString name() { return medianame; }
+    //virtual bool initialize() = 0;
+    //virtual bool start() = 0;
+
+  private:
+/*
+    bool openSocket(QUrl *source);
+    void closeSocket();
+    void sendRequest(const QString request);
+    bool readlineSocket(QString &request);
+*/
+    QIODevice *device;
+    QUrl streamurl;
+    QString mediatype;
+    QString medianame;
 };
 
 
