aboutsummaryrefslogtreecommitdiff
path: root/src/plugins
diff options
context:
space:
mode:
authortrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2009-09-18 18:17:29 +0000
committertrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2009-09-18 18:17:29 +0000
commit136f634c6c334fe1f1b77c9640fe49c8204d011f (patch)
treec5430eeb0b5d1455ef9231a3749fa4d4a1e3862f /src/plugins
parente51ee1711dbfe631ed2d54fb63d4d2e59e2ac71c (diff)
downloadqmmp-136f634c6c334fe1f1b77c9640fe49c8204d011f.tar.gz
qmmp-136f634c6c334fe1f1b77c9640fe49c8204d011f.tar.bz2
qmmp-136f634c6c334fe1f1b77c9640fe49c8204d011f.zip
added transport api, moved http into plugin, fixed problems with cue metadata
git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@1231 90c681e8-e032-0410-971d-27865f9a5e38
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/CMakeLists.txt1
-rw-r--r--src/plugins/Input/cue/decoder_cue.cpp2
-rw-r--r--src/plugins/Transports/CMakeLists.txt5
-rw-r--r--src/plugins/Transports/Transports.pro4
-rw-r--r--src/plugins/Transports/http/CMakeLists.txt59
-rw-r--r--src/plugins/Transports/http/downloader.cpp361
-rw-r--r--src/plugins/Transports/http/downloader.h87
-rw-r--r--src/plugins/Transports/http/http.pro33
-rw-r--r--src/plugins/Transports/http/httpinputfactory.cpp38
-rw-r--r--src/plugins/Transports/http/httpinputfactory.h39
-rw-r--r--src/plugins/Transports/http/httpinputsource.cpp51
-rw-r--r--src/plugins/Transports/http/httpinputsource.h49
-rw-r--r--src/plugins/Transports/http/streamreader.cpp134
-rw-r--r--src/plugins/Transports/http/streamreader.h81
-rw-r--r--src/plugins/plugins.pro3
15 files changed, 946 insertions, 1 deletions
diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt
index 32dc59f34..00eabaad5 100644
--- a/src/plugins/CMakeLists.txt
+++ b/src/plugins/CMakeLists.txt
@@ -6,3 +6,4 @@ add_subdirectory(General)
add_subdirectory(PlaylistFormats)
add_subdirectory(CommandLineOptions)
add_subdirectory(FileDialogs)
+add_subdirectory(Transports)
diff --git a/src/plugins/Input/cue/decoder_cue.cpp b/src/plugins/Input/cue/decoder_cue.cpp
index 944c9911a..cf06438e9 100644
--- a/src/plugins/Input/cue/decoder_cue.cpp
+++ b/src/plugins/Input/cue/decoder_cue.cpp
@@ -88,6 +88,8 @@ bool DecoderCUE::initialize()
audioParameters().channels() *
audioParameters().bits() * m_length/8000;
m_totalBytes = 0;
+
+ StateHandler::instance()->dispatch(parser.info(track)->metaData());
return TRUE;
}
diff --git a/src/plugins/Transports/CMakeLists.txt b/src/plugins/Transports/CMakeLists.txt
new file mode 100644
index 000000000..1de020fbf
--- /dev/null
+++ b/src/plugins/Transports/CMakeLists.txt
@@ -0,0 +1,5 @@
+SET(USE_CURL TRUE CACHE BOOL "enable/disable curl-based http plugin")
+
+IF(USE_CURL)
+add_subdirectory(http)
+ENDIF(USE_CURL)
diff --git a/src/plugins/Transports/Transports.pro b/src/plugins/Transports/Transports.pro
new file mode 100644
index 000000000..26d09c134
--- /dev/null
+++ b/src/plugins/Transports/Transports.pro
@@ -0,0 +1,4 @@
+include(../../../qmmp.pri)
+
+SUBDIRS += http
+TEMPLATE = subdirs
diff --git a/src/plugins/Transports/http/CMakeLists.txt b/src/plugins/Transports/http/CMakeLists.txt
new file mode 100644
index 000000000..939c22b12
--- /dev/null
+++ b/src/plugins/Transports/http/CMakeLists.txt
@@ -0,0 +1,59 @@
+project(libhttp)
+
+cmake_minimum_required(VERSION 2.4.7)
+
+if(COMMAND cmake_policy)
+ cmake_policy(SET CMP0003 NEW)
+ cmake_policy(SET CMP0005 NEW)
+endif(COMMAND cmake_policy)
+
+# qt plugin
+ADD_DEFINITIONS( -Wall )
+ADD_DEFINITIONS(${QT_DEFINITIONS})
+ADD_DEFINITIONS(-DQT_PLUGIN)
+ADD_DEFINITIONS(-DQT_NO_DEBUG)
+ADD_DEFINITIONS(-DQT_SHARED)
+ADD_DEFINITIONS(-DQT_THREAD)
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+SET(QT_INCLUDES
+ ${QT_INCLUDES}
+ ${CMAKE_CURRENT_BINARY_DIR}/../../../
+)
+
+# libqmmp
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../)
+link_directories(${CMAKE_CURRENT_BINARY_DIR}/../../../qmmp)
+
+# libcurl
+pkg_search_module(CURL libcurl)
+include_directories(${CURL_INCLUDE_DIRS})
+link_directories(${CURL_LIBRARY_DIRS})
+
+SET(libhttp_SRCS
+ streamreader.cpp
+ downloader.cpp
+ httpinputfactory.cpp
+ httpinputsource.cpp
+)
+
+SET(libhttp_MOC_HDRS
+ downloader.h
+ httpinputfactory.h
+ httpinputsource.h
+ streamreader.h
+)
+
+QT4_WRAP_CPP(libhttp_MOC_SRCS ${libhttp_MOC_HDRS})
+
+# Don't forget to include output directory, otherwise
+# the UI file won't be wrapped!
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+IF(CURL_FOUND)
+ADD_LIBRARY(http MODULE ${libhttp_SRCS} ${libhttp_MOC_SRCS})
+add_dependencies(http qmmp)
+target_link_libraries(http ${QT_LIBRARIES} -lqmmp ${CURL_LDFLAGS} ${CURL_CFLAGS})
+install(TARGETS http DESTINATION ${LIB_DIR}/qmmp/Transports)
+ENDIF(CURL_FOUND)
diff --git a/src/plugins/Transports/http/downloader.cpp b/src/plugins/Transports/http/downloader.cpp
new file mode 100644
index 000000000..06653fde9
--- /dev/null
+++ b/src/plugins/Transports/http/downloader.cpp
@@ -0,0 +1,361 @@
+/***************************************************************************
+ * Copyright (C) 2006-2009 by Ilya Kotov *
+ * forkotov02@hotmail.ru *
+ * *
+ * 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 <QApplication>
+#include <QStringList>
+#include <QSettings>
+#include <QDir>
+#include <QMap>
+#include <stdint.h>
+#include <stdlib.h>
+#include <qmmp/qmmp.h>
+#include <qmmp/statehandler.h>
+#include "downloader.h"
+
+//curl callbacks
+static size_t curl_write_data(void *data, size_t size, size_t nmemb,
+ void *pointer)
+{
+ Downloader *dl = (Downloader *)pointer;
+ dl->mutex()->lock ();
+ size_t buf_start = dl->stream()->buf_fill;
+ size_t data_size = size * nmemb;
+ dl->stream()->buf_fill += data_size;
+
+ dl->stream()->buf = (char *)realloc (dl->stream()->buf, dl->stream()->buf_fill);
+ memcpy (dl->stream()->buf + buf_start, data, data_size);
+ dl->mutex()->unlock();
+ dl->checkBuffer();
+ return data_size;
+}
+
+static size_t curl_header(void *data, size_t size, size_t nmemb,
+ void *pointer)
+{
+ Downloader *dl = (Downloader *)pointer;
+ dl->mutex()->lock ();
+ size_t data_size = size * nmemb;
+ if (data_size < 3)
+ {
+ dl->mutex()->unlock();
+ return data_size;
+ }
+
+ //qDebug("header received: %s", (char*) data);
+ QString str = QString::fromAscii((char *) data, data_size);
+ str = str.trimmed ();
+ 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().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 (key == "icy-metaint")
+ {
+ dl->stream()->icy_metaint = value.toInt();
+ dl->stream()->icy_meta_data = TRUE;
+ }
+ }
+ dl->mutex()->unlock();
+ return data_size;
+}
+
+int curl_progress(void *pointer, double dltotal, double dlnow, double ultotal, double ulnow)
+{
+ Q_UNUSED(dltotal);
+ Q_UNUSED(dlnow);
+ Q_UNUSED(ultotal);
+ Q_UNUSED(ulnow);
+ Downloader *dl = (Downloader *)pointer;
+ dl->mutex()->lock ();
+ bool aborted = dl->stream()->aborted;
+ dl->mutex()->unlock();
+ if (aborted)
+ return -1;
+ return 0;
+}
+
+Downloader::Downloader(QObject *parent, const QString &url)
+ : QThread(parent)
+{
+ m_url = 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;
+}
+
+
+Downloader::~Downloader()
+{
+ abort();
+ curl_global_cleanup();
+ m_stream.aborted = TRUE;
+ m_stream.buf_fill = 0;
+ if (m_stream.buf)
+ free(m_stream.buf);
+
+ m_stream.buf = 0;
+}
+
+
+qint64 Downloader::read(char* data, qint64 maxlen)
+{
+
+ qint64 len = 0;
+ m_mutex.lock();
+ if (!m_stream.icy_meta_data || m_stream.icy_metaint == 0)
+ len = readBuffer(data, maxlen);
+ else
+ {
+ 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 len;
+}
+
+Stream *Downloader::stream()
+{
+ return &m_stream;
+}
+
+QMutex *Downloader::mutex()
+{
+ return &m_mutex;
+}
+
+QString Downloader::contentType()
+{
+ QString content;
+ if (m_stream.header.contains("content-type"))
+ content = m_stream.header.value("content-type");
+ return content;
+}
+
+void Downloader::abort()
+{
+ m_mutex.lock();
+
+ if (m_stream.aborted)
+ {
+ m_mutex.unlock();
+ return;
+ }
+ m_stream.aborted = TRUE;
+ m_mutex.unlock();
+ wait();
+ if (m_handle)
+ {
+ curl_easy_cleanup(m_handle);
+ m_handle = 0;
+ }
+}
+
+int Downloader::bytesAvailable()
+{
+ m_mutex.lock();
+ int b = m_stream.buf_fill;
+ m_mutex.unlock();
+ return b;
+}
+
+void Downloader::run()
+{
+ qDebug("Downloader: starting download thread");
+ m_handle = curl_easy_init();
+ //proxy
+ QSettings settings ( Qmmp::configFile(), QSettings::IniFormat );
+ if (Qmmp::useProxy())
+ curl_easy_setopt(m_handle, CURLOPT_PROXY,
+ strdup((Qmmp::proxy().host() + ":" +
+ QString("%1").arg(Qmmp::proxy().port())).
+ toLatin1 ().constData ()));
+
+ if (Qmmp::useProxyAuth())
+ curl_easy_setopt(m_handle, CURLOPT_PROXYUSERPWD,
+ strdup((Qmmp::proxy().userName() + ":" +
+ Qmmp::proxy().password()).
+ toLatin1 ().constData ()));
+
+ // Set url to download
+ curl_easy_setopt(m_handle, CURLOPT_URL, strdup(m_url.toAscii().constData()));
+ // callback for wrting
+ curl_easy_setopt(m_handle, CURLOPT_WRITEFUNCTION, curl_write_data);
+ // Set destination file
+ curl_easy_setopt(m_handle, CURLOPT_WRITEDATA, this);
+ curl_easy_setopt(m_handle, CURLOPT_HEADERDATA, this);
+ curl_easy_setopt(m_handle, CURLOPT_HEADERFUNCTION, curl_header);
+ // Disable SSL
+ curl_easy_setopt(m_handle, CURLOPT_SSL_VERIFYPEER, FALSE);
+ curl_easy_setopt(m_handle, CURLOPT_SSL_VERIFYHOST, 0);
+ // Enable progress meter
+ curl_easy_setopt(m_handle, CURLOPT_NOPROGRESS, 0);
+ curl_easy_setopt(m_handle, CURLOPT_PROGRESSDATA, this);
+ 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);
+ // Auto referrer
+ curl_easy_setopt(m_handle, CURLOPT_AUTOREFERER, 1);
+ // Follow redirections
+ curl_easy_setopt(m_handle, CURLOPT_FOLLOWLOCATION, 1);
+ curl_easy_setopt(m_handle, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt(m_handle, CURLOPT_MAXREDIRS, 15);
+ // user agent
+ QString user_agent = QString("qmmp/%1").arg(Qmmp::strVersion());
+ curl_easy_setopt(m_handle, CURLOPT_USERAGENT, qPrintable(user_agent));
+ curl_easy_setopt(m_handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+
+ struct curl_slist *http200_aliases = curl_slist_append(NULL, "ICY");
+ struct curl_slist *http_headers = curl_slist_append(NULL, "Icy-MetaData: 1");
+ curl_easy_setopt(m_handle, CURLOPT_HTTP200ALIASES, http200_aliases);
+ curl_easy_setopt(m_handle, CURLOPT_HTTPHEADER, http_headers);
+ m_mutex.lock();
+ m_stream.buf_fill = 0;
+ m_stream.buf = 0;
+ m_stream.aborted = FALSE;
+ m_stream.header.clear ();
+ m_ready = FALSE;
+ int return_code;
+ qDebug("Downloader: starting libcurl");
+ m_mutex.unlock();
+ return_code = curl_easy_perform(m_handle);
+ qDebug("curl_easy_perform %d", return_code);
+ qDebug("Downloader: thread finished");
+}
+
+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;
+}
+
+const QString &Downloader::title() const
+{
+ return m_title;
+}
+
+void Downloader::checkBuffer()
+{
+ if (m_stream.buf_fill > BUFFER_SIZE && !m_ready)
+ {
+ m_ready = TRUE;
+ qDebug("Downloader: ready");
+ emit readyRead();
+ }
+ else if (!m_ready)
+ {
+ emit bufferingProgress(100 * m_stream.buf_fill / BUFFER_SIZE);
+ qApp->processEvents();
+ }
+
+}
+
+bool Downloader::isReady()
+{
+ return m_ready;
+}
+
+void Downloader::readICYMetaData()
+{
+ uint8_t packet_size;
+ m_metacount = 0;
+ m_mutex.lock();
+ readBuffer((char *)&packet_size, sizeof(packet_size));
+ if (packet_size != 0)
+ {
+ 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("Downloader: ICY metadata: %s", packet);
+ parseICYMetaData(packet);
+ }
+ m_mutex.unlock();
+
+}
+
+void Downloader::parseICYMetaData(char *data)
+{
+ QString str(data);
+ QStringList list(str.split(";", QString::SkipEmptyParts));
+ foreach(QString line, list)
+ {
+ if (line.contains("StreamTitle="))
+ {
+ line = line.right(line.size() - line.indexOf("=") - 1).trimmed();
+ m_title = line.remove("'");
+ if (!m_title.isEmpty())
+ {
+ QMap<Qmmp::MetaData, QString> metaData;
+ metaData.insert(Qmmp::TITLE, m_title);
+ metaData.insert(Qmmp::URL, m_url);
+ StateHandler::instance()->dispatch(metaData);
+ }
+ break;
+ }
+ }
+}
diff --git a/src/plugins/Transports/http/downloader.h b/src/plugins/Transports/http/downloader.h
new file mode 100644
index 000000000..0ac96786d
--- /dev/null
+++ b/src/plugins/Transports/http/downloader.h
@@ -0,0 +1,87 @@
+/***************************************************************************
+ * Copyright (C) 2006-2008 by Ilya Kotov *
+ * forkotov02@hotmail.ru *
+ * *
+ * 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 DOWNLOADER_H
+#define DOWNLOADER_H
+
+#include <QThread>
+#include <QMutex>
+#include <QByteArray>
+#include <QMap>
+
+#include <curl/curl.h>
+
+#define BUFFER_SIZE 128000
+
+/*! @internal
+ * @author Ilya Kotov <forkotov02@hotmail.ru>
+ */
+struct Stream
+{
+ char *buf;
+ int buf_fill;
+ QString content_type;
+ bool aborted;
+ QMap <QString, QString> header;
+ bool icy_meta_data;
+ int icy_metaint;
+};
+/*! @internal
+ * @author Ilya Kotov <forkotov02@hotmail.ru>
+ */
+class Downloader : public QThread
+{
+ Q_OBJECT
+public:
+ Downloader(QObject *parent, const QString &url);
+
+ ~Downloader();
+
+ qint64 read(char* data, qint64 maxlen);
+ Stream *stream();
+ QMutex *mutex();
+ QString contentType();
+ void abort();
+ int bytesAvailable();
+ const QString& title() const;
+ void checkBuffer();
+ bool isReady();
+
+signals:
+ void readyRead();
+ void bufferingProgress(int);
+
+private:
+ qint64 readBuffer(char* data, qint64 maxlen);
+ void readICYMetaData();
+ void parseICYMetaData(char *data);
+ CURL *m_handle;
+ QMutex m_mutex;
+ Stream m_stream;
+ QString m_url;
+ int m_metacount;
+ QString m_title;
+ bool m_ready;
+
+protected:
+ void run();
+
+};
+
+#endif
diff --git a/src/plugins/Transports/http/http.pro b/src/plugins/Transports/http/http.pro
new file mode 100644
index 000000000..e9b630e18
--- /dev/null
+++ b/src/plugins/Transports/http/http.pro
@@ -0,0 +1,33 @@
+include(../../plugins.pri)
+HEADERS += downloader.h \
+ streamreader.h \
+ httpinputfactory.h \
+ httpinputsource.h
+SOURCES += downloader.cpp \
+ streamreader.cpp \
+ httpinputfactory.cpp \
+ httpinputsource.cpp
+win32:HEADERS += ../../../../src/qmmp/inputsource.h \
+ ../../../../src/qmmp/inputsourcefactory.h
+TARGET = $$PLUGINS_PREFIX/Transports/http
+unix:QMAKE_CLEAN = $$PLUGINS_PREFIX/Input/libhttp.so
+INCLUDEPATH += ../../../
+CONFIG += release \
+ warn_on \
+ plugin \
+ link_pkgconfig
+TEMPLATE = lib
+unix {
+ QMAKE_LIBDIR += ../../../../lib
+ LIBS += -lqmmp \
+ -L/usr/lib
+ PKGCONFIG += libcurl
+ isEmpty(LIB_DIR):LIB_DIR = /lib
+ win32 {
+ QMAKE_LIBDIR += ../../../../bin
+ LIBS += -lqmmp0 \
+ -lcurldll
+ }
+ target.path = $$LIB_DIR/qmmp/Transports
+ INSTALLS += target
+}
diff --git a/src/plugins/Transports/http/httpinputfactory.cpp b/src/plugins/Transports/http/httpinputfactory.cpp
new file mode 100644
index 000000000..69bfcbb79
--- /dev/null
+++ b/src/plugins/Transports/http/httpinputfactory.cpp
@@ -0,0 +1,38 @@
+/***************************************************************************
+ * Copyright (C) 2009 by Ilya Kotov *
+ * forkotov02@hotmail.ru *
+ * *
+ * 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 <QtPlugin>
+#include "httpinputsource.h"
+#include "httpinputfactory.h"
+
+const InputSourceProperties HTTPInputFactory::properties() const
+{
+ InputSourceProperties p;
+ p.protocols = "http";
+ p.shortName = "http";
+ return p;
+}
+
+InputSource *HTTPInputFactory::create(const QString &url, QObject *parent)
+{
+ return new HTTPInputSource(url, parent);
+}
+//Q_EXPORT_PLUGIN2(http, HTTPInputFactory);
+Q_EXPORT_PLUGIN(HTTPInputFactory);
diff --git a/src/plugins/Transports/http/httpinputfactory.h b/src/plugins/Transports/http/httpinputfactory.h
new file mode 100644
index 000000000..78e02f1f4
--- /dev/null
+++ b/src/plugins/Transports/http/httpinputfactory.h
@@ -0,0 +1,39 @@
+/***************************************************************************
+ * Copyright (C) 2009 by Ilya Kotov *
+ * forkotov02@hotmail.ru *
+ * *
+ * 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 HTTPINPUTFACTORY_H
+#define HTTPINPUTFACTORY_H
+
+#include <QObject>
+#include <qmmp/inputsourcefactory.h>
+
+/*!
+ * @author Ilya Kotov <forkotov02@hotmail.ru>
+ */
+class HTTPInputFactory : public QObject, InputSourceFactory
+{
+Q_OBJECT
+Q_INTERFACES(InputSourceFactory);
+public:
+ const InputSourceProperties properties() const;
+ InputSource *create(const QString &url, QObject *parent = 0);
+};
+
+#endif // HTTPINPUTFACTORY_H
diff --git a/src/plugins/Transports/http/httpinputsource.cpp b/src/plugins/Transports/http/httpinputsource.cpp
new file mode 100644
index 000000000..b8f838d83
--- /dev/null
+++ b/src/plugins/Transports/http/httpinputsource.cpp
@@ -0,0 +1,51 @@
+/***************************************************************************
+ * Copyright (C) 2009 by Ilya Kotov *
+ * forkotov02@hotmail.ru *
+ * *
+ * 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 "streamreader.h"
+#include "httpinputsource.h"
+
+HTTPInputSource::HTTPInputSource(const QString &url, QObject *parent) : InputSource(url,parent)
+{
+ m_reader = new StreamReader(url, this);
+ connect(m_reader, SIGNAL(readyRead()),SLOT(open()));
+}
+
+QIODevice *HTTPInputSource::ioDevice()
+{
+ return m_reader;
+}
+
+bool HTTPInputSource::initialize()
+{
+ m_reader->downloadFile();
+ return TRUE;
+}
+
+bool HTTPInputSource::isReady()
+{
+ return m_reader->isOpen();
+}
+
+void HTTPInputSource::open()
+{
+ qDebug("open");
+ m_reader->open(QIODevice::ReadOnly);
+ emit(ready(this));
+}
diff --git a/src/plugins/Transports/http/httpinputsource.h b/src/plugins/Transports/http/httpinputsource.h
new file mode 100644
index 000000000..2c4d32f89
--- /dev/null
+++ b/src/plugins/Transports/http/httpinputsource.h
@@ -0,0 +1,49 @@
+/***************************************************************************
+ * Copyright (C) 2009 by Ilya Kotov *
+ * forkotov02@hotmail.ru *
+ * *
+ * 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 HTTPINPUTSOURCE_H
+#define HTTPINPUTSOURCE_H
+
+#include <qmmp/inputsource.h>
+
+class StreamReader;
+
+/**
+ @author Ilya Kotov <forkotov02@hotmail.ru>
+*/
+class HTTPInputSource : public InputSource
+{
+Q_OBJECT
+public:
+ HTTPInputSource(const QString &url, QObject *parent = 0);
+
+ QIODevice *ioDevice();
+ bool initialize();
+ bool isReady();
+
+private slots:
+ void open();
+
+private:
+ StreamReader *m_reader;
+
+};
+
+#endif // HTTPINPUTSOURCE_H
diff --git a/src/plugins/Transports/http/streamreader.cpp b/src/plugins/Transports/http/streamreader.cpp
new file mode 100644
index 000000000..5d61c76d1
--- /dev/null
+++ b/src/plugins/Transports/http/streamreader.cpp
@@ -0,0 +1,134 @@
+/***************************************************************************
+ * Copyright (C) 2006-2008 by Ilya Kotov *
+ * forkotov02@hotmail.ru *
+ * *
+ * 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 <QApplication>
+#include <QUrl>
+
+#include "downloader.h"
+#include "streamreader.h"
+
+StreamReader::StreamReader(const QString &name, QObject *parent)
+ : QIODevice(parent)
+{
+ m_downloader = new Downloader(this, name);
+ connect(m_downloader, SIGNAL(readyRead()), SIGNAL(readyRead()));
+ connect(m_downloader, SIGNAL(bufferingProgress(int)), SIGNAL(bufferingProgress(int)));
+}
+
+StreamReader::~StreamReader()
+{
+ m_downloader->abort();
+ qDebug("StreamReader::~StreamReader()");
+}
+
+bool StreamReader::atEnd () const
+{
+ return FALSE;
+}
+
+qint64 StreamReader::bytesAvailable () const
+{
+ return m_downloader->bytesAvailable ();
+}
+
+qint64 StreamReader::bytesToWrite () const
+{
+ return -1;
+}
+
+bool StreamReader::canReadLine () const
+{
+ return FALSE;
+}
+
+void StreamReader::close ()
+{
+ m_downloader->abort();
+}
+
+bool StreamReader::isSequential () const
+{
+ return TRUE;
+}
+
+bool StreamReader::open ( OpenMode mode )
+{
+ if (mode != QIODevice::ReadOnly)
+ return FALSE;
+ //downloadFile();
+ setOpenMode(QIODevice::ReadOnly);
+ if (m_downloader->isReady())
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool StreamReader::reset ()
+{
+ QIODevice::reset();
+ return TRUE;
+}
+
+bool StreamReader::seek ( qint64 pos )
+{
+ QIODevice::seek(pos);
+ return FALSE;
+}
+
+qint64 StreamReader::size () const
+{
+ return bytesAvailable ();
+}
+
+bool StreamReader::waitForBytesWritten ( int msecs )
+{
+ //usleep(msecs*1000);
+ return TRUE;
+}
+
+bool StreamReader::waitForReadyRead ( int msecs )
+{
+ //usleep(msecs*1000);
+ return TRUE;
+}
+
+qint64 StreamReader::readData(char* data, qint64 maxlen)
+{
+ return m_downloader->read (data, maxlen);
+}
+
+qint64 StreamReader::writeData(const char*, qint64)
+{
+ return 0;
+}
+
+void StreamReader::downloadFile()
+{
+ m_downloader->start();
+}
+
+const QString &StreamReader::contentType()
+{
+ m_downloader->mutex()->lock ();
+ m_contentType = m_downloader->contentType();
+ m_downloader->mutex()->unlock();
+ qApp->processEvents();
+ qDebug("StreamReader: content type: %s", qPrintable(m_contentType));
+ return m_contentType;
+}
diff --git a/src/plugins/Transports/http/streamreader.h b/src/plugins/Transports/http/streamreader.h
new file mode 100644
index 000000000..e73f65389
--- /dev/null
+++ b/src/plugins/Transports/http/streamreader.h
@@ -0,0 +1,81 @@
+/***************************************************************************
+ * Copyright (C) 2006-2008 by Ilya Kotov *
+ * forkotov02@hotmail.ru *
+ * *
+ * 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 STREAMREADER_H
+#define STREAMREADER_H
+
+#include <QObject>
+#include <QIODevice>
+#include <QUrl>
+
+class QFileInfo;
+
+class Downloader;
+
+/*! @internal
+ * @author Ilya Kotov <forkotov02@hotmail.ru>
+ */
+class StreamReader : public QIODevice
+{
+ Q_OBJECT
+public:
+ StreamReader(const QString &name, QObject *parent = 0);
+
+ ~StreamReader();
+
+ /**
+ * QIODevice API
+ */
+ bool atEnd () const;
+ qint64 bytesAvailable () const;
+ qint64 bytesToWrite () const;
+ bool canReadLine () const;
+ void close ();
+ bool isSequential () const;
+ bool open ( OpenMode mode );
+ //qint64 pos () const;
+ bool reset ();
+ bool seek ( qint64 pos );
+ qint64 size () const;
+ bool waitForBytesWritten ( int msecs );
+ bool waitForReadyRead ( int msecs );
+
+ /**
+ * returns content type of a stream
+ */
+ const QString &contentType();
+ void downloadFile();
+
+signals:
+ void readyRead();
+ void bufferingProgress(int);
+
+protected:
+ qint64 readData(char*, qint64);
+ qint64 writeData(const char*, qint64);
+
+private:
+ //void downloadFile();
+ void fillBuffer();
+ QUrl m_url;
+ QString m_contentType;
+ Downloader *m_downloader;
+};
+
+#endif
diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro
index ea3c6fc19..dfa993d89 100644
--- a/src/plugins/plugins.pro
+++ b/src/plugins/plugins.pro
@@ -1,7 +1,8 @@
SUBDIRS += Input \
Output \
General \
- Visual
+ Visual \
+ Transports
unix:SUBDIRS += Effect \
PlaylistFormats \