diff options
| author | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2016-09-17 16:31:13 +0000 |
|---|---|---|
| committer | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2016-09-17 16:31:13 +0000 |
| commit | b7b22bfdf2fbc820f0d07a74c4bc0929fe990848 (patch) | |
| tree | 69addb89a1e2e49bd16962c48d3d9afb969e89e9 /src/plugins | |
| parent | 0b3c85bc145e40a89ee227fbacb367f40e53fd1e (diff) | |
| download | qmmp-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.pro | 4 | ||||
| -rw-r--r-- | src/plugins/Input/archive/archive.pro | 4 | ||||
| -rw-r--r-- | src/plugins/Input/archive/archiveinputdevice.cpp | 47 | ||||
| -rw-r--r-- | src/plugins/Input/archive/archiveinputdevice.h | 19 | ||||
| -rw-r--r-- | src/plugins/Input/archive/archivetagreader.cpp | 74 | ||||
| -rw-r--r-- | src/plugins/Input/archive/archivetagreader.h | 30 | ||||
| -rw-r--r-- | src/plugins/Input/archive/decoder_archive.cpp | 42 | ||||
| -rw-r--r-- | src/plugins/Input/archive/decoder_archive.h | 19 | ||||
| -rw-r--r-- | src/plugins/Input/archive/decoderarchivefactory.cpp | 70 |
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) |
