aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2008-09-26 17:10:51 +0000
committertrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2008-09-26 17:10:51 +0000
commit76095a46370939213ceffca85129baa3d9bac0d4 (patch)
treef71b49e6f0c1cdcc2cf378610f90b439943a95ec
parent525d822bec49c9952388b71ffd7c293528b31c24 (diff)
downloadqmmp-76095a46370939213ceffca85129baa3d9bac0d4.tar.gz
qmmp-76095a46370939213ceffca85129baa3d9bac0d4.tar.bz2
qmmp-76095a46370939213ceffca85129baa3d9bac0d4.zip
enabled in-stream metadata support
git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@562 90c681e8-e032-0410-971d-27865f9a5e38
-rw-r--r--src/plugins/Input/mad/decoder_mad.cpp4
-rw-r--r--src/plugins/Input/mad/tagextractor.cpp30
-rw-r--r--src/plugins/Input/mad/tagextractor.h8
-rw-r--r--src/qmmp/downloader.cpp11
-rw-r--r--src/qmmp/downloader.h1
-rw-r--r--src/qmmp/fileinfo.cpp10
-rw-r--r--src/qmmp/fileinfo.h2
-rw-r--r--src/qmmp/qmmp.h2
-rw-r--r--src/qmmp/soundcore.cpp16
-rw-r--r--src/qmmp/soundcore.h28
-rw-r--r--src/qmmp/statehandler.cpp20
-rw-r--r--src/qmmp/statehandler.h11
-rw-r--r--src/qmmp/streamreader.cpp6
-rw-r--r--src/qmmp/streamreader.h5
-rw-r--r--src/ui/mainwindow.cpp40
-rw-r--r--src/ui/mainwindow.h1
-rw-r--r--src/ui/playlistitem.cpp18
-rw-r--r--src/ui/playlistitem.h3
18 files changed, 137 insertions, 79 deletions
diff --git a/src/plugins/Input/mad/decoder_mad.cpp b/src/plugins/Input/mad/decoder_mad.cpp
index 2cd8567a0..395506c33 100644
--- a/src/plugins/Input/mad/decoder_mad.cpp
+++ b/src/plugins/Input/mad/decoder_mad.cpp
@@ -111,9 +111,7 @@ bool DecoderMAD::initialize()
if (input()->isSequential ()) //for streams only
{
TagExtractor extractor(input());
- FileTag tag = extractor.id3v2tag();
- // if (!tag.isEmpty())
-// dispatch(extractor.id3v2tag());
+ StateHandler::instance()->dispatch(extractor.id3v2tag());
}
mad_stream_init(&stream);
diff --git a/src/plugins/Input/mad/tagextractor.cpp b/src/plugins/Input/mad/tagextractor.cpp
index dab104ab2..1385c8a85 100644
--- a/src/plugins/Input/mad/tagextractor.cpp
+++ b/src/plugins/Input/mad/tagextractor.cpp
@@ -39,7 +39,7 @@ TagExtractor::~TagExtractor()
{
}
-const FileTag &TagExtractor::id3v2tag()
+const QMap<Qmmp::MetaData, QString> TagExtractor::id3v2tag()
{
QByteArray array = m_d->peek(2048);
int offset = array.indexOf("ID3");
@@ -72,20 +72,20 @@ const FileTag &TagExtractor::id3v2tag()
if (!codec)
codec = QTextCodec::codecForName ("UTF-8");
- m_tag.setValue(FileTag::ALBUM,
- codec->toUnicode(album.toCString(utf)).trimmed());
- m_tag.setValue(FileTag::ARTIST,
- codec->toUnicode(artist.toCString(utf)).trimmed());
- m_tag.setValue(FileTag::COMMENT,
- codec->toUnicode(comment.toCString(utf)).trimmed());
- m_tag.setValue(FileTag::GENRE,
- codec->toUnicode(genre.toCString(utf)).trimmed());
- m_tag.setValue(FileTag::TITLE,
- codec->toUnicode(title.toCString(utf)).trimmed());
- m_tag.setValue(FileTag::YEAR,
- taglib_tag.year());
- m_tag.setValue(FileTag::TRACK,
- taglib_tag.track());
+ m_tag.insert(Qmmp::ALBUM,
+ codec->toUnicode(album.toCString(utf)).trimmed());
+ m_tag.insert(Qmmp::ARTIST,
+ codec->toUnicode(artist.toCString(utf)).trimmed());
+ m_tag.insert(Qmmp::COMMENT,
+ codec->toUnicode(comment.toCString(utf)).trimmed());
+ m_tag.insert(Qmmp::GENRE,
+ codec->toUnicode(genre.toCString(utf)).trimmed());
+ m_tag.insert(Qmmp::TITLE,
+ codec->toUnicode(title.toCString(utf)).trimmed());
+ m_tag.insert(Qmmp::YEAR,
+ QString::number(taglib_tag.year()));
+ m_tag.insert(Qmmp::TRACK,
+ QString::number(taglib_tag.track()));
return m_tag;
diff --git a/src/plugins/Input/mad/tagextractor.h b/src/plugins/Input/mad/tagextractor.h
index a814dc5b9..707719535 100644
--- a/src/plugins/Input/mad/tagextractor.h
+++ b/src/plugins/Input/mad/tagextractor.h
@@ -20,13 +20,15 @@
#ifndef TAGEXTRACTOR_H
#define TAGEXTRACTOR_H
+#include <QMap>
+
#include <taglib/tag.h>
#include <taglib/fileref.h>
#include <taglib/id3v1tag.h>
#include <taglib/id3v2tag.h>
#include <taglib/id3v2header.h>
-#include <qmmp/filetag.h>
+#include <qmmp/qmmp.h>
class QIODevice;
class QBuffer;
@@ -42,10 +44,10 @@ public:
~TagExtractor();
-const FileTag &id3v2tag();
+ const QMap<Qmmp::MetaData, QString> id3v2tag();
private:
- FileTag m_tag;
+ QMap<Qmmp::MetaData, QString> m_tag;
QIODevice *m_d;
};
diff --git a/src/qmmp/downloader.cpp b/src/qmmp/downloader.cpp
index 9b51d90f5..88d3fe1b3 100644
--- a/src/qmmp/downloader.cpp
+++ b/src/qmmp/downloader.cpp
@@ -22,10 +22,13 @@
#include <QStringList>
#include <QSettings>
#include <QDir>
+#include <QMap>
#include <stdint.h>
#include <stdlib.h>
#include "constants.h"
+#include "qmmp.h"
+#include "statehandler.h"
#include "downloader.h"
//curl callbacks
@@ -301,7 +304,7 @@ void Downloader::checkBuffer()
}
else if (!m_ready)
{
- emit bufferingProgress(100*m_stream.buf_fill/BUFFER_SIZE);
+ emit bufferingProgress(100 * m_stream.buf_fill / BUFFER_SIZE);
qApp->processEvents();
}
@@ -347,7 +350,11 @@ void Downloader::parseICYMetaData(char *data)
line = line.right(line.size() - line.indexOf("=") - 1).trimmed();
m_title = line.remove("'");
if (!m_title.isEmpty())
- emit titleChanged ();
+ {
+ QMap<Qmmp::MetaData, QString> metaData;
+ metaData.insert(Qmmp::TITLE, m_title);
+ StateHandler::instance()->dispatch(metaData);
+ }
break;
}
}
diff --git a/src/qmmp/downloader.h b/src/qmmp/downloader.h
index ae5b13608..94f5a2547 100644
--- a/src/qmmp/downloader.h
+++ b/src/qmmp/downloader.h
@@ -63,7 +63,6 @@ public:
bool isReady();
signals:
- void titleChanged();
void readyRead();
void bufferingProgress(int);
diff --git a/src/qmmp/fileinfo.cpp b/src/qmmp/fileinfo.cpp
index 5b03c3456..4cb0811ac 100644
--- a/src/qmmp/fileinfo.cpp
+++ b/src/qmmp/fileinfo.cpp
@@ -72,6 +72,16 @@ const QString FileInfo::metaData (Qmmp::MetaData key) const
return m_metaData[key];
}
+const QMap<Qmmp::MetaData, QString> FileInfo::metaData () const
+{
+ return m_metaData;
+}
+
+void FileInfo::setMetaData(const QMap<Qmmp::MetaData, QString> &metaData)
+{
+ m_metaData = metaData;
+}
+
bool FileInfo::isEmpty()
{
return m_metaData.isEmpty(); //TODO add correct test
diff --git a/src/qmmp/fileinfo.h b/src/qmmp/fileinfo.h
index 4ae56137d..367c34a5c 100644
--- a/src/qmmp/fileinfo.h
+++ b/src/qmmp/fileinfo.h
@@ -38,11 +38,13 @@ public:
const qint64 length () const;
const QString metaData (Qmmp::MetaData key) const;
+ const QMap<Qmmp::MetaData, QString> metaData () const;
bool isEmpty();
void setLength(qint64 length);
void setMetaData(Qmmp::MetaData key, const QString &value);
void setMetaData(Qmmp::MetaData key, int value);
+ void setMetaData(const QMap <Qmmp::MetaData, QString> &metaData);
private:
QMap <Qmmp::MetaData, QString> m_metaData;
diff --git a/src/qmmp/qmmp.h b/src/qmmp/qmmp.h
index bb469afae..c9c830071 100644
--- a/src/qmmp/qmmp.h
+++ b/src/qmmp/qmmp.h
@@ -26,7 +26,7 @@
class Qmmp
{
public:
- enum State {Playing = 0, Paused, Stopped, Buffering, NormalError, FatalError };
+ enum State {Playing = 0, Paused, Stopped, Buffering, NormalError, FatalError};
enum MetaData {TITLE = 0, ARTIST, ALBUM, COMMENT, GENRE, YEAR, TRACK};
};
diff --git a/src/qmmp/soundcore.cpp b/src/qmmp/soundcore.cpp
index d438fc543..e53be7259 100644
--- a/src/qmmp/soundcore.cpp
+++ b/src/qmmp/soundcore.cpp
@@ -94,7 +94,11 @@ bool SoundCore::play(const QString &source)
qDebug("SoundCore: cannot open input");
stop();
m_handler->dispatch(Qmmp::NormalError);
+ return FALSE;
}
+ FileInfo *finfo = m_factory->getFileInfo(m_url.toLocalFile ());
+ m_handler->dispatch(finfo->metaData());
+ delete finfo;
return decode();
}
else
@@ -109,8 +113,6 @@ bool SoundCore::play(const QString &source)
{
m_input = new StreamReader(source, this);
connect(m_input, SIGNAL(bufferingProgress(int)), SIGNAL(bufferingProgress(int)));
- connect(m_input, SIGNAL(titleChanged(const QString&)),
- SIGNAL(titleChanged(const QString&)));
connect(m_input, SIGNAL(readyRead()),SLOT(decode()));
qobject_cast<StreamReader *>(m_input)->downloadFile();
return TRUE;
@@ -322,6 +324,16 @@ Qmmp::State SoundCore::state() const
return m_handler->state();
}
+QMap <Qmmp::MetaData, QString> SoundCore::metaData()
+{
+ return m_handler->metaData();
+}
+
+QString SoundCore::metaData(Qmmp::MetaData key)
+{
+ return m_handler->metaData(key);
+}
+
bool SoundCore::decode()
{
if (!m_factory)
diff --git a/src/qmmp/soundcore.h b/src/qmmp/soundcore.h
index db8dc3616..00bf876e7 100644
--- a/src/qmmp/soundcore.h
+++ b/src/qmmp/soundcore.h
@@ -44,14 +44,6 @@ public:
~SoundCore();
/*!
- * Returns the current state.
- *
- * \return the state of the object.
- */
-
- Qmmp::State state() const;
-
- /*!
* Returns length in seconds
*/
qint64 length() const;
@@ -86,6 +78,18 @@ public:
int precision();
int channels();
+ /*!
+ * Returns the current state.
+ *
+ * \return the state of the object.
+ */
+ Qmmp::State state() const;
+
+ QMap <Qmmp::MetaData, QString> metaData();
+
+ QString metaData(Qmmp::MetaData key);
+
+
/*!
* Returns a pointer to the SoundCore instance.
@@ -128,14 +132,6 @@ public slots:
signals:
/*!
- * This signal is emited when the title of the stream changes.
- * The argument \b title is the new title of the stream.
- * Signal emits with the shoutcast server stream only.
- * For another servers use decoderStateChanged()
- */
- void titleChanged(const QString& title);
-
- /*!
* This signal is emited when the stream reader fills it's buffer.
* The argument \b progress indicates the current percentage of buffering completed
*/
diff --git a/src/qmmp/statehandler.cpp b/src/qmmp/statehandler.cpp
index eeffb01bd..ad71ea17a 100644
--- a/src/qmmp/statehandler.cpp
+++ b/src/qmmp/statehandler.cpp
@@ -80,12 +80,18 @@ void StateHandler::dispatch(qint64 elapsed,
m_mutex.unlock();
}
-void StateHandler::dispatch(QMap<QString, QString> metaData)
+void StateHandler::dispatch(const QMap<Qmmp::MetaData, QString> &metaData)
{
m_mutex.lock();
- if (m_metaData != metaData)
+ QMap<Qmmp::MetaData, QString> tmp = metaData;
+ foreach(QString value, tmp.values()) //remove empty keys
{
- m_metaData = metaData;
+ if (value.isEmpty())
+ tmp.remove(tmp.key(value));
+ }
+ if (m_metaData != tmp)
+ {
+ m_metaData = tmp;
emit metaDataChanged ();
}
m_mutex.unlock();
@@ -110,6 +116,7 @@ void StateHandler::dispatch(const Qmmp::State &state)
m_frequency = 0;
m_precision = 0;
m_channels = 0;
+ m_metaData.clear();
}
emit stateChanged(state);
}
@@ -146,11 +153,16 @@ Qmmp::State StateHandler::state()
return m_state;
}
-QMap<QString, QString> StateHandler::metaData()
+QMap<Qmmp::MetaData, QString> StateHandler::metaData()
{
return m_metaData;
}
+QString StateHandler::metaData(Qmmp::MetaData key)
+{
+ return m_metaData.value(key);
+}
+
StateHandler *StateHandler::instance()
{
return m_instance;
diff --git a/src/qmmp/statehandler.h b/src/qmmp/statehandler.h
index b800f2d4d..8d755a35c 100644
--- a/src/qmmp/statehandler.h
+++ b/src/qmmp/statehandler.h
@@ -44,18 +44,18 @@ public:
int precision,
int channels);
- void dispatch(QMap<QString, QString> metaData);
+ void dispatch(const QMap<Qmmp::MetaData, QString> &metaData);
void dispatch(const Qmmp::State &state);
qint64 elapsed();
- qint64 totalTime();
int bitrate();
int frequency();
int precision();
int channels();
Qmmp::State state();
- QMap <QString, QString> metaData();
+ QMap <Qmmp::MetaData, QString> metaData();
+ QString metaData(Qmmp::MetaData key);
/*!
* Returns a pointer to the StateHandler instance.
@@ -64,7 +64,6 @@ public:
signals:
void elapsedChanged(qint64 time);
- //void totalTimeChanged(qint64 time);
void bitrateChanged(int bitrate);
void frequencyChanged(int frequency);
void precisionChanged(int precision);
@@ -74,10 +73,10 @@ signals:
void finished();
private:
- qint64 m_elapsed, m_totalTime;
+ qint64 m_elapsed;
int m_bitrate, m_frequency, m_precision, m_channels;
static StateHandler* m_instance;
- QMap <QString, QString> m_metaData;
+ QMap <Qmmp::MetaData, QString> m_metaData;
Qmmp::State m_state;
QMutex m_mutex;
diff --git a/src/qmmp/streamreader.cpp b/src/qmmp/streamreader.cpp
index 68746fcea..6c9a9835a 100644
--- a/src/qmmp/streamreader.cpp
+++ b/src/qmmp/streamreader.cpp
@@ -27,7 +27,6 @@ StreamReader::StreamReader(const QString &name, QObject *parent)
: QIODevice(parent)
{
m_downloader = new Downloader(this, name);
- connect(m_downloader, SIGNAL(titleChanged()),SLOT(updateTitle()));
connect(m_downloader, SIGNAL(readyRead()), SIGNAL(readyRead()));
connect(m_downloader, SIGNAL(bufferingProgress(int)), SIGNAL(bufferingProgress(int)));
}
@@ -124,11 +123,6 @@ void StreamReader::downloadFile()
m_downloader->start();
}
-void StreamReader::updateTitle()
-{
- emit titleChanged(m_downloader->title());
-}
-
const QString &StreamReader::contentType()
{
m_downloader->mutex()->lock ();
diff --git a/src/qmmp/streamreader.h b/src/qmmp/streamreader.h
index 5126be61e..d69a04dc6 100644
--- a/src/qmmp/streamreader.h
+++ b/src/qmmp/streamreader.h
@@ -63,7 +63,6 @@ public:
void downloadFile();
signals:
- void titleChanged(const QString&);
void readyRead();
void bufferingProgress(int);
@@ -71,10 +70,6 @@ protected:
qint64 readData(char*, qint64);
qint64 writeData(const char*, qint64);
-
-private slots:
- void updateTitle();
-
private:
//void downloadFile();
void fillBuffer();
diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp
index e456183ed..e2e3709ce 100644
--- a/src/ui/mainwindow.cpp
+++ b/src/ui/mainwindow.cpp
@@ -148,8 +148,7 @@ MainWindow::MainWindow(const QStringList& args, BuiltinCommandLineOption* option
connect(m_core, SIGNAL(stateChanged(Qmmp::State)), SLOT(showState(Qmmp::State)));
connect(m_core, SIGNAL(elapsedChanged(qint64)),m_playlist, SLOT(setTime(qint64)));
connect(m_core, SIGNAL(elapsedChanged(qint64)),m_titlebar, SLOT(setTime(qint64)));
-
-
+ connect(m_core, SIGNAL(metaDataChanged()),SLOT(showMetaData()));
updateEQ();
@@ -208,7 +207,7 @@ void MainWindow::play()
}
else
{
- //find out the reason why the playback failed
+ //find out the reason why playback failed
switch ((int) m_core->state())
{
case Qmmp::FatalError:
@@ -333,13 +332,13 @@ void MainWindow::showState(Qmmp::State state)
case Qmmp::Playing:
{
m_generalHandler->setState(General::Playing);
- if (m_playListModel->currentItem())
+ /*if (m_playListModel->currentItem())
{
SongInfo info = *m_playListModel->currentItem();
if (info.isEmpty())
info.setValue(SongInfo::TITLE, m_playlist->currentItem()->text());
m_generalHandler->setSongInfo(info);
- }
+ }*/
if (m_playlist->listWidget())
m_playlist->listWidget()->updateList(); //removes progress message from TextScroller
break;
@@ -456,6 +455,37 @@ void MainWindow::showState(Qmmp::State state)
}
}*/
+void MainWindow::showMetaData()
+{
+ qDebug("===== metadata ======");
+ qDebug("ARTIST = %s", qPrintable(m_core->metaData(Qmmp::TITLE)));
+ qDebug("TITLE = %s", qPrintable(m_core->metaData(Qmmp::ARTIST)));
+ qDebug("ALBUM = %s", qPrintable(m_core->metaData(Qmmp::ALBUM)));
+ qDebug("COMMENT = %s", qPrintable(m_core->metaData(Qmmp::COMMENT)));
+ qDebug("GENRE = %s", qPrintable(m_core->metaData(Qmmp::GENRE)));
+ qDebug("YEAR = %s", qPrintable(m_core->metaData(Qmmp::YEAR)));
+ qDebug("TRACK = %s", qPrintable(m_core->metaData(Qmmp::TRACK)));
+ qDebug("== end of metadata ==");
+
+ if (m_playlist->currentItem())
+ {
+ SongInfo info;
+ info.setValue(SongInfo::TITLE, m_core->metaData(Qmmp::TITLE));
+ info.setValue(SongInfo::ARTIST, m_core->metaData(Qmmp::ARTIST));
+ info.setValue(SongInfo::ALBUM, m_core->metaData(Qmmp::ALBUM));
+ info.setValue(SongInfo::COMMENT, m_core->metaData(Qmmp::COMMENT));
+ info.setValue(SongInfo::GENRE, m_core->metaData(Qmmp::GENRE));
+ info.setValue(SongInfo::YEAR, m_core->metaData(Qmmp::YEAR).toUInt());
+ info.setValue(SongInfo::TRACK, m_core->metaData(Qmmp::TRACK).toUInt());
+ //info.setValue(SongInfo::LENGTH, st.tag()->length());
+ info.setValue(SongInfo::STREAM, !QFile::exists(m_playlist->currentItem()->path()));
+ info.setValue(SongInfo::PATH, m_playlist->currentItem()->path());
+ m_generalHandler->setSongInfo(info);
+ m_playlist->currentItem()->updateMetaData(m_core->metaData());
+ m_playlist->listWidget()->updateList();
+ }
+}
+
void MainWindow::changeTitle(const QString &title)
{
if (m_playlist->currentItem())
diff --git a/src/ui/mainwindow.h b/src/ui/mainwindow.h
index 3a2a7a52f..515ab685c 100644
--- a/src/ui/mainwindow.h
+++ b/src/ui/mainwindow.h
@@ -96,6 +96,7 @@ private slots:
//void showOutputState(const OutputState&);
//void showDecoderState(const DecoderState&);
void showState(Qmmp::State state);
+ void showMetaData();
void changeTitle(const QString&);
void clear();
void startSeek();
diff --git a/src/ui/playlistitem.cpp b/src/ui/playlistitem.cpp
index 6d30d4180..0759e3354 100644
--- a/src/ui/playlistitem.cpp
+++ b/src/ui/playlistitem.cpp
@@ -58,6 +58,8 @@ PlayListItem::PlayListItem(const QString& path) : SongInfo(), m_flag(FREE)
PlayListItem::~PlayListItem()
{
+ if (m_info)
+ delete m_info;
}
void PlayListItem::setSelected(bool yes)
@@ -90,17 +92,15 @@ PlayListItem::FLAGS PlayListItem::flag() const
return m_flag;
}
-/*void PlayListItem::updateTags(const FileTag *tag)
+void PlayListItem::updateMetaData(const QMap <Qmmp::MetaData, QString> &metaData)
{
- if (m_info)
- {
- delete m_info;
- m_info = 0;
- }
- if (!tag->isEmpty())
- m_info = new FileTag(*tag);
+ if (!m_info)
+ m_info = new FileInfo();
+
+ m_info->setMetaData(metaData);
+ m_use_meta = TRUE;
readMetadata();
-}*/
+}
void PlayListItem::updateTags()
{
diff --git a/src/ui/playlistitem.h b/src/ui/playlistitem.h
index 6e028b202..818bc7eeb 100644
--- a/src/ui/playlistitem.h
+++ b/src/ui/playlistitem.h
@@ -21,6 +21,7 @@
#define PLAYLISTITEM_H
#include <qmmpui/songinfo.h>
+#include <qmmp/qmmp.h>
class FileInfo;
/**
@@ -52,7 +53,7 @@ public:
const QString text() const;
void setText(const QString &title);
//modify functions
- //void updateTags(const FileTag *tag);
+ void updateMetaData(const QMap <Qmmp::MetaData, QString> &metaData);
void updateTags();
private: