diff options
| author | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2012-02-11 14:14:06 +0000 |
|---|---|---|
| committer | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2012-02-11 14:14:06 +0000 |
| commit | e6c43e75ffbcd605b47201c70046ac2f1842c171 (patch) | |
| tree | ac0dfff70bf86fdc8cb7d4e0c5ffec992e19b199 | |
| parent | 48c4a5cff471076bb4d2cb5e1dd417adfe657f11 (diff) | |
| download | qmmp-e6c43e75ffbcd605b47201c70046ac2f1842c171.tar.gz qmmp-e6c43e75ffbcd605b47201c70046ac2f1842c171.tar.bz2 qmmp-e6c43e75ffbcd605b47201c70046ac2f1842c171.zip | |
added full icy metadata output (Closes issue 120)(Closes issue 470)
git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@2596 90c681e8-e032-0410-971d-27865f9a5e38
| -rw-r--r-- | src/plugins/Transports/http/httpinputfactory.cpp | 2 | ||||
| -rw-r--r-- | src/plugins/Transports/http/httpstreamreader.cpp | 1 | ||||
| -rw-r--r-- | src/plugins/Transports/http/httpstreamreader.h | 4 | ||||
| -rw-r--r-- | src/qmmp/inputsource.cpp | 19 | ||||
| -rw-r--r-- | src/qmmp/inputsource.h | 20 | ||||
| -rw-r--r-- | src/qmmp/qmmpaudioengine.cpp | 3 | ||||
| -rw-r--r-- | src/qmmp/qmmpevents.cpp | 17 | ||||
| -rw-r--r-- | src/qmmp/qmmpevents_p.h | 25 | ||||
| -rw-r--r-- | src/qmmp/soundcore.cpp | 17 | ||||
| -rw-r--r-- | src/qmmp/soundcore.h | 14 | ||||
| -rw-r--r-- | src/qmmp/statehandler.cpp | 24 | ||||
| -rw-r--r-- | src/qmmp/statehandler.h | 23 | ||||
| -rw-r--r-- | src/qmmpui/detailsdialog.cpp | 17 |
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) { |
