aboutsummaryrefslogtreecommitdiff
path: root/src/plugins
diff options
context:
space:
mode:
authortrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2016-09-17 16:31:13 +0000
committertrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2016-09-17 16:31:13 +0000
commitb7b22bfdf2fbc820f0d07a74c4bc0929fe990848 (patch)
tree69addb89a1e2e49bd16962c48d3d9afb969e89e9 /src/plugins
parent0b3c85bc145e40a89ee227fbacb367f40e53fd1e (diff)
downloadqmmp-b7b22bfdf2fbc820f0d07a74c4bc0929fe990848.tar.gz
qmmp-b7b22bfdf2fbc820f0d07a74c4bc0929fe990848.tar.bz2
qmmp-b7b22bfdf2fbc820f0d07a74c4bc0929fe990848.zip
archive pluging: enabled metadata support, fixed some issues
git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@6730 90c681e8-e032-0410-971d-27865f9a5e38
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/Input/Input.pro4
-rw-r--r--src/plugins/Input/archive/archive.pro4
-rw-r--r--src/plugins/Input/archive/archiveinputdevice.cpp47
-rw-r--r--src/plugins/Input/archive/archiveinputdevice.h19
-rw-r--r--src/plugins/Input/archive/archivetagreader.cpp74
-rw-r--r--src/plugins/Input/archive/archivetagreader.h30
-rw-r--r--src/plugins/Input/archive/decoder_archive.cpp42
-rw-r--r--src/plugins/Input/archive/decoder_archive.h19
-rw-r--r--src/plugins/Input/archive/decoderarchivefactory.cpp70
9 files changed, 228 insertions, 81 deletions
diff --git a/src/plugins/Input/Input.pro b/src/plugins/Input/Input.pro
index 1b903e9d3..b8933e246 100644
--- a/src/plugins/Input/Input.pro
+++ b/src/plugins/Input/Input.pro
@@ -50,6 +50,8 @@ contains(CONFIG, WILDMIDI_PLUGIN){
SUBDIRS += wildmidi
}
-
+contains(CONFIG, ARCHIVE_PLUGIN){
+ SUBDIRS += archive
+}
}
diff --git a/src/plugins/Input/archive/archive.pro b/src/plugins/Input/archive/archive.pro
index 6c8c84352..700954140 100644
--- a/src/plugins/Input/archive/archive.pro
+++ b/src/plugins/Input/archive/archive.pro
@@ -33,7 +33,7 @@ unix {
QMAKE_LIBDIR += ../../../../lib
LIBS += -lqmmp
- PKGCONFIG += libarchive
+ PKGCONFIG += libarchive taglib
QMAKE_CLEAN =$$PLUGINS_PREFIX/Input/libarc.so
}
@@ -41,5 +41,5 @@ win32 {
# HEADERS += ../../../../src/qmmp/metadatamodel.h \
# ../../../../src/qmmp/decoderfactory.h
QMAKE_LIBDIR += ../../../../bin
- LIBS += -lqmmp0 -larchive
+ LIBS += -lqmmp0 -larchive -ltag
}
diff --git a/src/plugins/Input/archive/archiveinputdevice.cpp b/src/plugins/Input/archive/archiveinputdevice.cpp
index d9017ccda..d03a60a3d 100644
--- a/src/plugins/Input/archive/archiveinputdevice.cpp
+++ b/src/plugins/Input/archive/archiveinputdevice.cpp
@@ -1,3 +1,22 @@
+/***************************************************************************
+ * Copyright (C) 2016 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
#include "archiveinputdevice.h"
ArchiveInputDevice::ArchiveInputDevice(archive *a, archive_entry *e, QObject *parent) : QIODevice(parent)
@@ -20,14 +39,22 @@ bool ArchiveInputDevice::seek(qint64 pos)
{
qint64 r = qMin(qint64(sizeof(tmp)), delta);
r = archive_read_data(m_archive, tmp, r);
- m_buffer.buffer().append(tmp, r);
- delta -= r;
+ if(r > 0)
+ {
+ m_buffer.buffer().append(tmp, r);
+ delta -= r;
+ continue;
+ }
+ else if(r < 0)
+ {
+ qWarning("ArchiveInputDevice: seeking failed; libarchive error: %s", archive_error_string(m_archive));
+ }
+ return false;
}
}
- m_buffer.seek(pos);
- return true;
+ return m_buffer.seek(pos);
}
qint64 ArchiveInputDevice::size() const
@@ -37,11 +64,15 @@ qint64 ArchiveInputDevice::size() const
qint64 ArchiveInputDevice::readData(char *data, qint64 maxSize)
{
- if(m_buffer.atEnd())
+ if(m_buffer.pos() + maxSize > m_buffer.size())
{
- char tmp[maxSize];
- int r = archive_read_data(m_archive, tmp, maxSize);
- m_buffer.buffer().append(tmp, r);
+ qint64 l = m_buffer.pos() + maxSize - m_buffer.size();
+ char tmp[l];
+ int r = archive_read_data(m_archive, tmp, l);
+ if(r > 0)
+ m_buffer.buffer().append(tmp, r);
+ else if(r < 0)
+ qWarning("ArchiveInputDevice: reading failed; libarchive error: %s", archive_error_string(m_archive));
}
return m_buffer.read(data, maxSize);
}
diff --git a/src/plugins/Input/archive/archiveinputdevice.h b/src/plugins/Input/archive/archiveinputdevice.h
index 7e7dd56f7..12010e76c 100644
--- a/src/plugins/Input/archive/archiveinputdevice.h
+++ b/src/plugins/Input/archive/archiveinputdevice.h
@@ -1,3 +1,22 @@
+/***************************************************************************
+ * Copyright (C) 2016 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
#ifndef ARCHIVEINPUTDEVICE_H
#define ARCHIVEINPUTDEVICE_H
diff --git a/src/plugins/Input/archive/archivetagreader.cpp b/src/plugins/Input/archive/archivetagreader.cpp
index e79f4db59..43a05f251 100644
--- a/src/plugins/Input/archive/archivetagreader.cpp
+++ b/src/plugins/Input/archive/archivetagreader.cpp
@@ -1,14 +1,32 @@
+/***************************************************************************
+ * Copyright (C) 2016 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
#include <taglib/tiostream.h>
-#include <taglib/fileref.h>
#include "archivetagreader.h"
class IODeviceStream : public TagLib::IOStream
{
public:
- IODeviceStream(QIODevice *input, const QString &fileName)
+ IODeviceStream(QIODevice *input, const QString &url)
{
m_input = input;
- m_fileName = fileName;
+ m_fileName = url.section("/", -1);
}
virtual ~IODeviceStream() {}
@@ -42,21 +60,18 @@ public:
{
case Beginning:
m_input->seek(offset);
- return;
+ break;
case Current:
m_input->seek(m_input->pos() + offset);
- return;
+ break;
case End:
- m_input->seek(m_input->size() - offset);
- return;
+ m_input->seek(m_input->size() + offset);
+ break;
}
- return;
}
-
-
virtual void clear()
{
- m_input->reset();
+ m_input->seek(0);
TagLib::IOStream::clear();
}
virtual long tell() const
@@ -76,28 +91,39 @@ private:
};
-ArchiveTagReader::ArchiveTagReader(QIODevice *input, const QString &fileName)
+ArchiveTagReader::ArchiveTagReader(QIODevice *input, const QString &url)
{
- m_stream = new IODeviceStream(input, fileName);
+ m_stream = new IODeviceStream(input, url);
+ m_file = new TagLib::FileRef(m_stream);
+ m_url = url;
}
ArchiveTagReader::~ArchiveTagReader()
{
+ delete m_file;
delete m_stream;
}
-/*const QMap<Qmmp::MetaData, QString> ArchiveTagReader::metaData() const
+const QMap<Qmmp::MetaData, QString> ArchiveTagReader::metaData() const
{
- TagLib::FileRef file(m_stream);
QMap<Qmmp::MetaData, QString> m;
- m[Qmmp::ALBUM, QString::fromUtf8(tag->album().toCString(true)).trimmed()];
- m[Qmmp::ARTIST, QString::fromUtf8(tag->artist().toCString(true)).trimmed()];
- m[Qmmp::COMMENT, QString::fromUtf8(tag->comment().toCString(true)).trimmed()];
- m[Qmmp::GENRE, QString::fromUtf8(tag->genre().toCString(true)).trimmed()];
- m[Qmmp::TITLE, QString::fromUtf8(tag->title().toCString(true)).trimmed()];
- m[Qmmp::YEAR, tag->year());
- m[Qmmp::TRACK, tag->track());
-
+ TagLib::Tag *tag = m_file->tag();
+ if(tag)
+ {
+ m[Qmmp::ALBUM] = TStringToQString(tag->album()).trimmed();
+ m[Qmmp::ARTIST] = TStringToQString(tag->artist()).trimmed();
+ m[Qmmp::COMMENT] = TStringToQString(tag->comment()).trimmed();
+ m[Qmmp::GENRE] = TStringToQString(tag->genre()).trimmed();
+ m[Qmmp::TITLE] = TStringToQString(tag->title()).trimmed();
+ m[Qmmp::YEAR] = QString::number(tag->year());
+ m[Qmmp::TRACK] = QString::number(tag->track());
+ }
+ m[Qmmp::URL] = m_url;
return m;
-}*/
+}
+
+TagLib::AudioProperties *ArchiveTagReader::audioProperties() const
+{
+ return m_file->audioProperties();
+}
diff --git a/src/plugins/Input/archive/archivetagreader.h b/src/plugins/Input/archive/archivetagreader.h
index 918f4383f..b8536dbc0 100644
--- a/src/plugins/Input/archive/archivetagreader.h
+++ b/src/plugins/Input/archive/archivetagreader.h
@@ -1,25 +1,47 @@
+/***************************************************************************
+ * Copyright (C) 2016 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
#ifndef ARCHIVETAGREADER_H
#define ARCHIVETAGREADER_H
#include <QIODevice>
#include <QMap>
#include <qmmp/qmmp.h>
+#include <taglib/fileref.h>
+#include <taglib/audioproperties.h>
class IODeviceStream;
class ArchiveTagReader
{
public:
- ArchiveTagReader(QIODevice *input, const QString &fileName);
+ ArchiveTagReader(QIODevice *input, const QString &url);
~ArchiveTagReader();
- //const QMap<Qmmp::MetaData, QString> metaData () const;
-
-
+ const QMap<Qmmp::MetaData, QString> metaData() const;
+ TagLib::AudioProperties *audioProperties() const;
private:
IODeviceStream *m_stream;
+ TagLib::FileRef *m_file;
+ QString m_url;
};
#endif // ARCHIVETAGREADER_H
diff --git a/src/plugins/Input/archive/decoder_archive.cpp b/src/plugins/Input/archive/decoder_archive.cpp
index 24e7f15d5..6d1d43c3d 100644
--- a/src/plugins/Input/archive/decoder_archive.cpp
+++ b/src/plugins/Input/archive/decoder_archive.cpp
@@ -1,6 +1,26 @@
+/***************************************************************************
+ * Copyright (C) 2016 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
#include <QFile>
#include <archive_entry.h>
#include "archiveinputdevice.h"
+#include "archivetagreader.h"
#include "decoder_archive.h"
DecoderArchive::DecoderArchive(const QString &url)
@@ -44,21 +64,12 @@ bool DecoderArchive::initialize()
return false;
}
- QList<DecoderFactory*> filtered;
- foreach (DecoderFactory *fact, Decoder::enabledFactories())
+ //is this file supported by qmmp?
+ QList<DecoderFactory *> filtered = Decoder::findByFileExtension(filePath);
+ foreach (DecoderFactory *f, filtered)
{
- if(fact->properties().noInput)
- continue;
-
- foreach(QString filter, fact->properties().filters)
- {
- QRegExp regexp(filter, Qt::CaseInsensitive, QRegExp::Wildcard);
- if (regexp.exactMatch(filePath))
- {
- filtered.append(fact);
- break;
- }
- }
+ if(f->properties().noInput)
+ filtered.removeAll(f); //remove all factories without streaming input
}
if(filtered.isEmpty())
@@ -130,6 +141,9 @@ bool DecoderArchive::initialize()
qWarning("DecoderArchive: unable to initialize decoder");
return false;
}
+
+ ArchiveTagReader reader(m_input, m_url);
+ addMetaData(reader.metaData());
configure(m_decoder->audioParameters());
return true;
}
diff --git a/src/plugins/Input/archive/decoder_archive.h b/src/plugins/Input/archive/decoder_archive.h
index df88acf15..3c5935e21 100644
--- a/src/plugins/Input/archive/decoder_archive.h
+++ b/src/plugins/Input/archive/decoder_archive.h
@@ -1,3 +1,22 @@
+/***************************************************************************
+ * Copyright (C) 2016 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
#ifndef DECODERARCHIVE_H
#define DECODERARCHIVE_H
diff --git a/src/plugins/Input/archive/decoderarchivefactory.cpp b/src/plugins/Input/archive/decoderarchivefactory.cpp
index f6157503c..b7fa24f85 100644
--- a/src/plugins/Input/archive/decoderarchivefactory.cpp
+++ b/src/plugins/Input/archive/decoderarchivefactory.cpp
@@ -24,6 +24,8 @@
#include <archive.h>
#include <archive_entry.h>
#include "decoder_archive.h"
+#include "archivetagreader.h"
+#include "archiveinputdevice.h"
#include "decoderarchivefactory.h"
// DecoderArchiveFileFactory
@@ -38,9 +40,9 @@ const DecoderProperties DecoderArchiveFactory::properties() const
properties.name = tr("Archive Plugin");
properties.filters << "*.rar" << "*.zip";
properties.description = tr("Archives");
- //properties.contentType = "";
+ properties.contentTypes << "application/zip" << "application/x-rar-compressed";
properties.shortName = "archive";
- properties.hasAbout = false;
+ properties.hasAbout = true;
properties.hasSettings = false;
properties.noInput = true;
properties.protocols << "rar" << "zip";
@@ -52,41 +54,55 @@ Decoder *DecoderArchiveFactory::create(const QString &url, QIODevice *)
return new DecoderArchive(url);
}
-QList<FileInfo *> DecoderArchiveFactory::createPlayList(const QString &fileName, bool useMetaData, QStringList *)
+QList<FileInfo *> DecoderArchiveFactory::createPlayList(const QString &archivePath, bool useMetaData, QStringList *)
{
QList <FileInfo *> list;
+ struct archive_entry *entry = 0;
-
- struct archive *a;
- struct archive_entry *entry;
- int r;
-
- a = archive_read_new();
+ struct archive *a = archive_read_new();
archive_read_support_filter_all(a);
archive_read_support_format_all(a);
- r = archive_read_open_filename(a, fileName.toLocal8Bit().constData(), 10240);
- if (r != ARCHIVE_OK)
+
+ if(archive_read_open_filename(a, archivePath.toLocal8Bit().constData(), 10240) != ARCHIVE_OK)
{
- //exit(1);
+ qWarning("DecoderArchiveFactory: unable to open archive; libarchive error: %s", archive_error_string(a));
return list;
}
while (archive_read_next_header(a, &entry) == ARCHIVE_OK)
{
if(archive_entry_filetype(entry) == AE_IFREG)
{
- QString pathName = QString::fromLocal8Bit(archive_entry_pathname(entry));
- if(!pathName.startsWith("/"))
- pathName.prepend("/");
-
- list << new FileInfo(QString("%1://%2#%3")
- .arg(fileName.section(".", -1)).toLower()
- .arg(fileName)
- .arg(pathName));
- //TODO read tags
+ QString filePath = QString::fromLocal8Bit(archive_entry_pathname(entry));
+ if(!filePath.startsWith("/"))
+ filePath.prepend("/");
+
+ //is this file supported by qmmp?
+ QList<DecoderFactory *> filtered = Decoder::findByFileExtension(filePath);
+ foreach (DecoderFactory *f, filtered)
+ {
+ if(f->properties().noInput)
+ filtered.removeAll(f); //remove all factories without streaming input
+ }
+
+ if(!filtered.isEmpty())
+ {
+ list << new FileInfo(QString("%1://%2#%3")
+ .arg(archivePath.section(".", -1)).toLower()
+ .arg(archivePath)
+ .arg(filePath));
+
+ ArchiveInputDevice dev(a, entry, 0);
+ ArchiveTagReader reader(&dev, list.last()->path());
+
+ if(useMetaData)
+ list.last()->setMetaData(reader.metaData());
+ if(reader.audioProperties())
+ list.last()->setLength(reader.audioProperties()->length());
+ }
}
archive_read_data_skip(a);
}
- r = archive_read_free(a);
+ archive_read_free(a);
return list;
}
@@ -101,12 +117,10 @@ void DecoderArchiveFactory::showSettings(QWidget *)
void DecoderArchiveFactory::showAbout(QWidget *parent)
{
- /*char version [128] ;
- sf_command (NULL, SFC_GET_LIB_VERSION, version, sizeof (version)) ;
- QMessageBox::about (parent, tr("About Sndfile Audio Plugin"),
- tr("Qmmp Sndfile Audio Plugin")+"\n"+
- tr("Compiled against")+" "+QString(version)+"\n" +
- tr("Written by: Ilya Kotov <forkotov02@hotmail.ru>"));*/
+ QMessageBox::about (parent, tr("About Archive Reader Plugin"),
+ tr("Qmmp Archive Reader Plugin")+"\n"+
+ tr("Compiled against %1").arg(ARCHIVE_VERSION_STRING)+"\n" +
+ tr("Written by: Ilya Kotov <forkotov02@hotmail.ru>"));
}
QTranslator *DecoderArchiveFactory::createTranslator(QObject *parent)