diff options
| author | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2007-08-20 12:06:47 +0000 |
|---|---|---|
| committer | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2007-08-20 12:06:47 +0000 |
| commit | 3df482395b31866da7b91a25360ef952ec0a90aa (patch) | |
| tree | 59c2c4b97cec66b040b7b5d9dd5d39592474c97a /lib | |
| parent | 75719b8c81a6fa169f42bfba0d18716802effe39 (diff) | |
| download | qmmp-3df482395b31866da7b91a25360ef952ec0a90aa.tar.gz qmmp-3df482395b31866da7b91a25360ef952ec0a90aa.tar.bz2 qmmp-3df482395b31866da7b91a25360ef952ec0a90aa.zip | |
shoutcast metadata support
git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@102 90c681e8-e032-0410-971d-27865f9a5e38
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/downloader.cpp | 117 | ||||
| -rw-r--r-- | lib/downloader.h | 5 |
2 files changed, 100 insertions, 22 deletions
diff --git a/lib/downloader.cpp b/lib/downloader.cpp index c34b7cef2..56564419c 100644 --- a/lib/downloader.cpp +++ b/lib/downloader.cpp @@ -17,9 +17,11 @@ * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ -#include "downloader.h" -static int stop; +#include <QApplication> + + +#include "downloader.h" //curl callbacks static size_t curl_write_data(void *data, size_t size, size_t nmemb, @@ -52,16 +54,27 @@ static size_t curl_header(void *data, size_t size, size_t nmemb, //qDebug("header received: %s", (char*) data); QString str = QString::fromAscii((char *) data, data_size); str = str.trimmed (); - if (str.left(4).contains("HTTP") || str.left(4).contains("ICY")) + if (str.left(4).contains("HTTP")) { qDebug("Downloader: header received"); + //TODO open metadata socket + } + else if (str.left(4).contains("ICY")) + { + qDebug("Downloader: shoutcast header received"); + dl->stream()->icy_meta_data = TRUE; } else { - QString key = str.left(str.indexOf(":")).trimmed(); - QString value = str.right(str.size() - str.indexOf(":") - 1).trimmed(); + QString key = str.left(str.indexOf(":")).trimmed().toLower(); + QString value = str.right(str.size() - str.indexOf(":") - 1).trimmed().toLower(); dl->stream()->header.insert(key, value); qDebug("Downloader: key=%s, value=%s",qPrintable(key),qPrintable(value)); + + if (dl->stream()->icy_meta_data && (key == "icy-metaint")) + { + dl->stream()->icy_metaint = value.toInt(); + } } dl->mutex()->unlock(); return data_size; @@ -85,8 +98,11 @@ Downloader::Downloader(QObject *parent, const QString &url) curl_global_init(CURL_GLOBAL_ALL); m_stream.buf_fill = 0; m_stream.buf = 0; - + m_stream.icy_meta_data = FALSE; m_stream.aborted = TRUE; + m_stream.icy_metaint = 0; + m_handle = 0; + m_metacount = 0; } @@ -98,18 +114,36 @@ Downloader::~Downloader() qint64 Downloader::read(char* data, qint64 maxlen) { + + qint64 len = 0; m_mutex.lock(); - if (m_stream.buf_fill>0 && !m_stream.aborted) + if (!m_stream.icy_meta_data || m_stream.icy_metaint == 0) + len = readBuffer(data, maxlen); + else { - int len = qMin<qint64>(m_stream.buf_fill, maxlen); - memcpy(data, m_stream.buf, len); - m_stream.buf_fill -= len; - memmove(m_stream.buf, m_stream.buf + len, m_stream.buf_fill); - m_mutex.unlock(); - return len; + qint64 nread = 0; + qint64 to_read; + while (maxlen > nread && m_stream.buf_fill > nread) + { + to_read = qMin<qint64>(m_stream.icy_metaint - m_metacount, maxlen - nread); + //to_read = (maxlen - nread); + qint64 res = readBuffer(data + nread, to_read); + nread += res; + m_metacount += res; + if (m_metacount == m_stream.icy_metaint) + { + m_metacount = 0; + m_mutex.unlock(); + readICYMetaData(); + m_mutex.lock(); + } + + } + len = nread; + } m_mutex.unlock(); - return 0; + return len; } Stream *Downloader::stream() @@ -125,12 +159,8 @@ QMutex *Downloader::mutex() QString Downloader::contentType() { QString content; - if (m_stream.header.contains("Content-Type")) - content = m_stream.header.value("Content-Type"); - else if (m_stream.header.contains("content-type")) + if (m_stream.header.contains("content-type")) content = m_stream.header.value("content-type"); - else if (m_stream.header.contains("Content-type")) - content = m_stream.header.value("Content-type"); return content; } @@ -146,7 +176,11 @@ void Downloader::abort() m_stream.aborted = TRUE; m_mutex.unlock(); wait(); - curl_easy_cleanup(m_handle); + if (m_handle) + { + curl_easy_cleanup(m_handle); + m_handle = 0; + } } int Downloader::bytesAvailable() @@ -180,7 +214,7 @@ void Downloader::run() curl_easy_setopt(m_handle, CURLOPT_PROGRESSFUNCTION, curl_progress); // Any kind of authentication curl_easy_setopt(m_handle, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_easy_setopt(m_handle, CURLOPT_VERBOSE, 1); + //curl_easy_setopt(m_handle, CURLOPT_VERBOSE, 1); // Auto referrer curl_easy_setopt(m_handle, CURLOPT_AUTOREFERER, 1); // Follow redirections @@ -198,7 +232,7 @@ void Downloader::run() m_stream.buf = 0; m_stream.aborted = FALSE; m_stream.header.clear (); - int return_code, response; + int return_code; qDebug("Downloader: starting libcurl"); m_mutex.unlock(); return_code = curl_easy_perform(m_handle); @@ -213,3 +247,42 @@ void Downloader::run() m_mutex.unlock(); qDebug("Downloader: thread exited"); } + +qint64 Downloader::readBuffer(char* data, qint64 maxlen) +{ + if (m_stream.buf_fill > 0 && !m_stream.aborted) + { + int len = qMin<qint64>(m_stream.buf_fill, maxlen); + memcpy(data, m_stream.buf, len); + m_stream.buf_fill -= len; + memmove(m_stream.buf, m_stream.buf + len, m_stream.buf_fill); + return len; + } + return 0; +} + +void Downloader::readICYMetaData() +{ + uint8_t packet_size; + m_metacount = 0; + m_mutex.lock(); + readBuffer((char *)&packet_size, sizeof(packet_size)); + if (packet_size == 0) + qDebug("zero"); + else + { + int size = packet_size * 16; + char packet[size]; + while(m_stream.buf_fill < size && isRunning()) + { + m_mutex.unlock(); + qApp->processEvents(); + m_mutex.lock(); + } + readBuffer(packet, size); + qDebug(packet); + + } + m_mutex.unlock(); + +} diff --git a/lib/downloader.h b/lib/downloader.h index cdbc7b977..308fca83a 100644 --- a/lib/downloader.h +++ b/lib/downloader.h @@ -38,6 +38,8 @@ struct Stream QString content_type; bool aborted; QMap <QString, QString> header; + bool icy_meta_data; + int icy_metaint; }; class Downloader : public QThread @@ -56,10 +58,13 @@ public: int bytesAvailable(); private: + qint64 readBuffer(char* data, qint64 maxlen); + void readICYMetaData(); CURL *m_handle; QMutex m_mutex; Stream m_stream; QString m_url; + int m_metacount; protected: void run(); |
