aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/plugins/Transports/http/httpinputfactory.cpp2
-rw-r--r--src/plugins/Transports/http/httpstreamreader.cpp1
-rw-r--r--src/plugins/Transports/http/httpstreamreader.h4
-rw-r--r--src/qmmp/inputsource.cpp19
-rw-r--r--src/qmmp/inputsource.h20
-rw-r--r--src/qmmp/qmmpaudioengine.cpp3
-rw-r--r--src/qmmp/qmmpevents.cpp17
-rw-r--r--src/qmmp/qmmpevents_p.h25
-rw-r--r--src/qmmp/soundcore.cpp17
-rw-r--r--src/qmmp/soundcore.h14
-rw-r--r--src/qmmp/statehandler.cpp24
-rw-r--r--src/qmmp/statehandler.h23
-rw-r--r--src/qmmpui/detailsdialog.cpp17
13 files changed, 157 insertions, 29 deletions
diff --git a/src/plugins/Transports/http/httpinputfactory.cpp b/src/plugins/Transports/http/httpinputfactory.cpp
index e21effae4..9a0b9fe1b 100644
--- a/src/plugins/Transports/http/httpinputfactory.cpp
+++ b/src/plugins/Transports/http/httpinputfactory.cpp
@@ -64,4 +64,4 @@ QTranslator *HTTPInputFactory::createTranslator(QObject *parent)
translator->load(QString(":/http_plugin_") + locale);
return translator;
}
-Q_EXPORT_PLUGIN2(http, HTTPInputFactory);
+Q_EXPORT_PLUGIN2(http, HTTPInputFactory)
diff --git a/src/plugins/Transports/http/httpstreamreader.cpp b/src/plugins/Transports/http/httpstreamreader.cpp
index f82a1950c..0013eb3b5 100644
--- a/src/plugins/Transports/http/httpstreamreader.cpp
+++ b/src/plugins/Transports/http/httpstreamreader.cpp
@@ -372,6 +372,7 @@ void HttpStreamReader::checkBuffer()
}
metaData.insert(Qmmp::URL, m_url);
(qobject_cast<InputSource *>(parent()))->addMetaData(metaData);
+ (qobject_cast<InputSource *>(parent()))->addStreamInfo(m_stream.header);
}
emit ready();
}
diff --git a/src/plugins/Transports/http/httpstreamreader.h b/src/plugins/Transports/http/httpstreamreader.h
index b9b84c160..488463902 100644
--- a/src/plugins/Transports/http/httpstreamreader.h
+++ b/src/plugins/Transports/http/httpstreamreader.h
@@ -25,7 +25,7 @@
#include <QUrl>
#include <QMutex>
#include <QString>
-#include <QMap>
+#include <QHash>
#include <QThread>
#include <curl/curl.h>
#ifdef WITH_ENCA
@@ -45,7 +45,7 @@ struct HttpStreamData
long buf_fill;
QString content_type;
bool aborted;
- QMap <QString, QString> header;
+ QHash <QString, QString> header;
bool icy_meta_data;
int icy_metaint;
};
diff --git a/src/qmmp/inputsource.cpp b/src/qmmp/inputsource.cpp
index 88bcb8d32..67fb4b93f 100644
--- a/src/qmmp/inputsource.cpp
+++ b/src/qmmp/inputsource.cpp
@@ -32,6 +32,7 @@ InputSource::InputSource(const QString &source, QObject *parent) : QObject(paren
m_url = source;
m_offset = -1;
m_hasMetaData = false;
+ m_hasStreamInfo = false;
}
QString InputSource::contentType() const
@@ -70,6 +71,23 @@ void InputSource::addMetaData(const QMap<Qmmp::MetaData, QString> &metaData)
m_hasMetaData = true;
}
+void InputSource::addStreamInfo(const QHash<QString, QString> &info)
+{
+ m_streamInfo = info;
+ m_hasStreamInfo = true;
+}
+
+bool InputSource::hasStreamInfo() const
+{
+ return m_hasStreamInfo;
+}
+
+QHash<QString, QString> InputSource::takeStreamInfo()
+{
+ m_hasStreamInfo = false;
+ return m_streamInfo;
+}
+
// static methods
QList<InputSourceFactory*> *InputSource::m_factories = 0;
QHash <InputSourceFactory*, QString> *InputSource::m_files = 0;
@@ -157,4 +175,3 @@ void InputSource::checkFactories()
}
}
}
-
diff --git a/src/qmmp/inputsource.h b/src/qmmp/inputsource.h
index af0012e0f..826fc4b2b 100644
--- a/src/qmmp/inputsource.h
+++ b/src/qmmp/inputsource.h
@@ -84,11 +84,26 @@ public:
*/
bool hasMetaData() const;
/*!
- * Takes metadata out of decoder and returns it.
+ * Takes metadata out of InputSource object and returns it.
* Attention: hasMetaData() should return \b true before use of this fuction.
*/
QMap<Qmmp::MetaData, QString> takeMetaData();
/*!
+ * Informs input source object about received stream information (for example icy data).
+ * Call of this function is required for all non-local streams/files
+ * @param info Stream information map.
+ */
+ void addStreamInfo(const QHash<QString, QString> &info);
+ /*!
+ * Returns \b true when stream information has received, otherwise returns \b false.
+ */
+ bool hasStreamInfo() const;
+ /*!
+ * Takes stream information out of InputSource object and returns it.
+ * Attention: hasStreamInfo() should return \b true before use of this fuction.
+ */
+ QHash<QString, QString> takeStreamInfo();
+ /*!
* Creates InputSource object.
* @param url Input source path or url.
* @param parent Parent object.
@@ -123,7 +138,8 @@ private:
QString m_url;
qint64 m_offset;
QMap<Qmmp::MetaData, QString> m_metaData;
- bool m_hasMetaData;
+ QHash<QString, QString> m_streamInfo;
+ bool m_hasMetaData, m_hasStreamInfo;
static void checkFactories();
static QList<InputSourceFactory*> *m_factories;
static QHash <InputSourceFactory*, QString> *m_files;
diff --git a/src/qmmp/qmmpaudioengine.cpp b/src/qmmp/qmmpaudioengine.cpp
index 91838d904..ae7b6faee 100644
--- a/src/qmmp/qmmpaudioengine.cpp
+++ b/src/qmmp/qmmpaudioengine.cpp
@@ -345,6 +345,9 @@ void QmmpAudioEngine::run()
StateHandler::instance()->dispatch(m_decoder->takeMetaData());
if(m_inputs[m_decoder]->hasMetaData())
StateHandler::instance()->dispatch(m_inputs[m_decoder]->takeMetaData());
+ if(m_inputs[m_decoder]->hasStreamInfo())
+ StateHandler::instance()->dispatch(m_inputs[m_decoder]->takeStreamInfo());
+
// decode
len = m_decoder->read((char *)(m_output_buf + m_output_at), m_output_size - m_output_at);
diff --git a/src/qmmp/qmmpevents.cpp b/src/qmmp/qmmpevents.cpp
index 6fec6ac15..b28fd366e 100644
--- a/src/qmmp/qmmpevents.cpp
+++ b/src/qmmp/qmmpevents.cpp
@@ -47,13 +47,26 @@ MetaDataChangedEvent::MetaDataChangedEvent(const QMap<Qmmp::MetaData, QString> &
MetaDataChangedEvent::~MetaDataChangedEvent(){}
-QMap<Qmmp::MetaData, QString>MetaDataChangedEvent::metaData()
+QMap<Qmmp::MetaData, QString>MetaDataChangedEvent::metaData() const
{
return m_metaData;
}
-QString MetaDataChangedEvent::metaData(Qmmp::MetaData key)
+QString MetaDataChangedEvent::metaData(Qmmp::MetaData key) const
{
return m_metaData.value(key);
}
+StreamInfoChangedEvent::StreamInfoChangedEvent(const QHash<QString, QString> &info)
+ : QEvent (EVENT_STREAM_INFO_CHANGED)
+{
+ m_streamInfo = info;
+}
+
+StreamInfoChangedEvent::~StreamInfoChangedEvent(){}
+
+QHash<QString, QString>StreamInfoChangedEvent::streamInfo() const
+{
+ return m_streamInfo;
+}
+
diff --git a/src/qmmp/qmmpevents_p.h b/src/qmmp/qmmpevents_p.h
index 0b25e9d7a..ae126295a 100644
--- a/src/qmmp/qmmpevents_p.h
+++ b/src/qmmp/qmmpevents_p.h
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright (C) 2011 by Ilya Kotov *
+ * Copyright (C) 2011-2012 by Ilya Kotov *
* forkotov02@hotmail.ru *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -22,6 +22,7 @@
#define QMMPEVENTS_P_H
#include <QMap>
+#include <QHash>
#include <QEvent>
#include "qmmp.h"
@@ -29,6 +30,7 @@
#define EVENT_NEXT_TRACK_REQUEST (QEvent::Type(QEvent::User + 1)) /*!< @internal */
#define EVENT_FINISHED (QEvent::Type(QEvent::User + 2)) /*!< @internal */
#define EVENT_METADATA_CHANGED (QEvent::Type(QEvent::User + 3)) /*!< @internal */
+#define EVENT_STREAM_INFO_CHANGED (QEvent::Type(QEvent::User + 4)) /*!< @internal */
/*! @internal
* @author Ilya Kotov <forkotov02@hotmail.ru>
@@ -59,14 +61,31 @@ public:
/*!
* Returns all meta data in map.
*/
- QMap <Qmmp::MetaData, QString> metaData();
+ QMap <Qmmp::MetaData, QString> metaData() const;
/*!
* Returns the metdata string associated with the given \b key.
*/
- QString metaData(Qmmp::MetaData key);
+ QString metaData(Qmmp::MetaData key) const;
private:
QMap<Qmmp::MetaData, QString> m_metaData;
};
+/*! @internal
+ * @author Ilya Kotov <forkotov02@hotmail.ru>
+ */
+class StreamInfoChangedEvent : public QEvent
+{
+public:
+ StreamInfoChangedEvent(const QHash<QString, QString> &info);
+ virtual ~StreamInfoChangedEvent();
+ /*!
+ * Returns all stream information.
+ */
+ QHash <QString, QString> streamInfo() const;
+
+private:
+ QHash<QString, QString> m_streamInfo;
+};
+
#endif // QMMPEVENTS_P_H
diff --git a/src/qmmp/soundcore.cpp b/src/qmmp/soundcore.cpp
index 90fec3d31..4dccb3c1c 100644
--- a/src/qmmp/soundcore.cpp
+++ b/src/qmmp/soundcore.cpp
@@ -209,16 +209,21 @@ Qmmp::State SoundCore::state() const
return m_handler->state();
}
-QMap <Qmmp::MetaData, QString> SoundCore::metaData()
+QMap <Qmmp::MetaData, QString> SoundCore::metaData() const
{
return m_metaData;
}
-QString SoundCore::metaData(Qmmp::MetaData key)
+QString SoundCore::metaData(Qmmp::MetaData key) const
{
return m_metaData[key];
}
+QHash<QString, QString> SoundCore::streamInfo() const
+{
+ return m_streamInfo;
+}
+
void SoundCore::startNextSource()
{
if(m_sources.isEmpty())
@@ -321,13 +326,21 @@ bool SoundCore::event(QEvent *e)
Qmmp::State st = ((StateChangedEvent *) e)->currentState();
emit stateChanged(st);
if(st == Qmmp::Stopped)
+ {
+ m_streamInfo.clear();
startNextEngine();
+ }
}
else if(e->type() == EVENT_METADATA_CHANGED)
{
m_metaData = ((MetaDataChangedEvent *) e)->metaData();
emit metaDataChanged();
}
+ else if(e->type() == EVENT_STREAM_INFO_CHANGED)
+ {
+ m_streamInfo = ((StreamInfoChangedEvent *) e)->streamInfo();
+ emit streamInfoChanged();
+ }
else if(e->type() == EVENT_NEXT_TRACK_REQUEST)
emit nextTrackRequest();
else if(e->type() == EVENT_FINISHED)
diff --git a/src/qmmp/soundcore.h b/src/qmmp/soundcore.h
index 71454eddf..e1be74c93 100644
--- a/src/qmmp/soundcore.h
+++ b/src/qmmp/soundcore.h
@@ -23,6 +23,7 @@
#include <QObject>
#include <QString>
#include <QQueue>
+#include <QHash>
#include "decoder.h"
#include "output.h"
#include "visual.h"
@@ -98,11 +99,15 @@ public:
/*!
* Returns all meta data in map.
*/
- QMap <Qmmp::MetaData, QString> metaData();
+ QMap <Qmmp::MetaData, QString> metaData() const;
/*!
* Returns the metdata string associated with the given \b key.
*/
- QString metaData(Qmmp::MetaData key);
+ QString metaData(Qmmp::MetaData key) const;
+ /*!
+ * Returns a hash of stream information if available
+ */
+ QHash<QString, QString> streamInfo() const;
/*!
* Returns a pointer to the SoundCore instance.
*/
@@ -179,6 +184,10 @@ signals:
*/
void metaDataChanged ();
/*!
+ * Emitted when new stream information is available.
+ */
+ void streamInfoChanged();
+ /*!
* This signal is emitted when the state of the SoundCore has changed.
*/
void stateChanged (Qmmp::State newState);
@@ -216,6 +225,7 @@ private:
INVALID_SOURCE
};
QMap <Qmmp::MetaData, QString> m_metaData;
+ QHash <QString, QString> m_streamInfo;
Decoder* m_decoder;
QString m_url;
QList <Visual*> m_visuals;
diff --git a/src/qmmp/statehandler.cpp b/src/qmmp/statehandler.cpp
index 1c80a8d72..683938559 100644
--- a/src/qmmp/statehandler.cpp
+++ b/src/qmmp/statehandler.cpp
@@ -50,11 +50,7 @@ StateHandler::~StateHandler()
m_instance = 0;
}
-void StateHandler::dispatch(qint64 elapsed,
- int bitrate,
- quint32 frequency,
- int precision,
- int channels)
+void StateHandler::dispatch(qint64 elapsed, int bitrate, quint32 frequency, int precision, int channels)
{
m_mutex.lock();
if (qAbs(m_elapsed - elapsed) > TICK_INTERVAL)
@@ -126,6 +122,23 @@ void StateHandler::dispatch(const QMap<Qmmp::MetaData, QString> &metaData)
m_mutex.unlock();
}
+void StateHandler::dispatch(const QHash<QString, QString> &info)
+{
+ m_mutex.lock();
+ QHash<QString, QString> tmp = info;
+ foreach(QString value, tmp.values()) //remove empty keys
+ {
+ if (value.isEmpty())
+ tmp.remove(tmp.key(value));
+ }
+ if(m_streamInfo != tmp)
+ {
+ m_streamInfo = tmp;
+ qApp->postEvent(parent(), new StreamInfoChangedEvent(m_streamInfo));
+ }
+ m_mutex.unlock();
+}
+
void StateHandler::dispatch(Qmmp::State state)
{
m_mutex.lock();
@@ -140,6 +153,7 @@ void StateHandler::dispatch(Qmmp::State state)
m_precision = 0;
m_channels = 0;
m_metaData.clear();
+ m_streamInfo.clear();
m_sendAboutToFinish = true;
}
if (m_state != state)
diff --git a/src/qmmp/statehandler.h b/src/qmmp/statehandler.h
index fa098333a..2c4742cb4 100644
--- a/src/qmmp/statehandler.h
+++ b/src/qmmp/statehandler.h
@@ -22,6 +22,7 @@
#include <QObject>
#include <QMap>
+#include <QHash>
#include <QMutex>
#include "abstractengine.h"
#include "qmmp.h"
@@ -50,24 +51,24 @@ public:
* @param precision Sample size (in bits).
* @param channels Number of channels.
*/
- virtual void dispatch(qint64 elapsed,
- int bitrate,
- quint32 frequency,
- int precision,
- int channels);
+ void dispatch(qint64 elapsed, int bitrate, quint32 frequency, int precision, int channels);
/*!
* Sends metadata \b metaData
*/
- virtual void dispatch(const QMap<Qmmp::MetaData, QString> &metaData);
+ void dispatch(const QMap<Qmmp::MetaData, QString> &metaData);
+ /*!
+ * Sends stream information \b info
+ */
+ void dispatch(const QHash<QString, QString> &info);
/*!
* Sends playback state.
*/
- virtual void dispatch(Qmmp::State state);
+ void dispatch(Qmmp::State state);
/*!
* Sends buffering progress.
* @param percent Indicates the current percentage of buffering completed.
*/
- virtual void dispatchBuffer(int percent);
+ void dispatchBuffer(int percent);
/*!
* Returns the current time (in milliseconds).
*/
@@ -93,9 +94,12 @@ public:
*/
Qmmp::State state() const;
/*!
- * Sends \b nextTrackRequest() event manually.
+ * Sends next track request.
*/
void sendNextTrackRequest();
+ /*!
+ * Sends playback finished event.
+ */
void sendFinished();
/*!
* Returns a pointer to the first created StateHandler instance.
@@ -142,6 +146,7 @@ private:
int m_bitrate, m_precision, m_channels;
static StateHandler* m_instance;
QMap <Qmmp::MetaData, QString> m_metaData;
+ QHash <QString, QString> m_streamInfo;
Qmmp::State m_state;
QMutex m_mutex;
};
diff --git a/src/qmmpui/detailsdialog.cpp b/src/qmmpui/detailsdialog.cpp
index 73e9ae879..18d76be8e 100644
--- a/src/qmmpui/detailsdialog.cpp
+++ b/src/qmmpui/detailsdialog.cpp
@@ -26,6 +26,7 @@
#include <qmmp/metadatamanager.h>
#include <qmmp/metadatamodel.h>
#include <qmmp/tagmodel.h>
+#include <qmmp/soundcore.h>
#include "ui_detailsdialog.h"
#include "playlistitem.h"
#include "tageditor_p.h"
@@ -92,6 +93,7 @@ void DetailsDialog:: on_directoryButton_clicked()
void DetailsDialog::printInfo()
{
+ SoundCore *core = SoundCore::instance();
QList <FileInfo *> flist = MetaDataManager::instance()->createPlayList(m_path, true);
QMap <Qmmp::MetaData, QString> metaData;
if(!flist.isEmpty() && QFile::exists(m_item->url()))
@@ -113,6 +115,21 @@ void DetailsDialog::printInfo()
formattedText += formatRow(tr("Track"), metaData[Qmmp::TRACK]);
if(metaData[Qmmp::DISCNUMBER] != "0")
formattedText += formatRow(tr("Disc number"), metaData[Qmmp::DISCNUMBER]);
+ //stream information
+ if(core->state() == Qmmp::Playing && core->url() == metaData.value(Qmmp::URL))
+ {
+ if(!core->streamInfo().isEmpty())
+ {
+ formattedText.append("<tr>");
+ formattedText.append("<td colspan=2>");
+ formattedText.append("<hr>");
+ formattedText.append("</td>");
+ formattedText.append("</tr>");
+
+ foreach(QString key, core->streamInfo().keys())
+ formattedText += formatRow(key, core->streamInfo().value(key));
+ }
+ }
//audio info
if(!m_metaDataModel)
{