diff options
| author | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2016-09-17 18:57:40 +0000 |
|---|---|---|
| committer | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2016-09-17 18:57:40 +0000 |
| commit | 477788d7dd83ecac5485f3d7c927229a9885ec27 (patch) | |
| tree | 583f16900e2c1afa6fd60f9212c7a97e980721a0 /src/plugins | |
| parent | b7b22bfdf2fbc820f0d07a74c4bc0929fe990848 (diff) | |
| download | qmmp-477788d7dd83ecac5485f3d7c927229a9885ec27.tar.gz qmmp-477788d7dd83ecac5485f3d7c927229a9885ec27.tar.bz2 qmmp-477788d7dd83ecac5485f3d7c927229a9885ec27.zip | |
archive plugin: added metadata model
git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@6731 90c681e8-e032-0410-971d-27865f9a5e38
Diffstat (limited to 'src/plugins')
| -rw-r--r-- | src/plugins/Input/archive/archive.pro | 6 | ||||
| -rw-r--r-- | src/plugins/Input/archive/archiveinputdevice.cpp | 51 | ||||
| -rw-r--r-- | src/plugins/Input/archive/archiveinputdevice.h | 7 | ||||
| -rw-r--r-- | src/plugins/Input/archive/archivemetadatamodel.cpp | 56 | ||||
| -rw-r--r-- | src/plugins/Input/archive/archivemetadatamodel.h | 45 | ||||
| -rw-r--r-- | src/plugins/Input/archive/archivetagreader.cpp | 1 | ||||
| -rw-r--r-- | src/plugins/Input/archive/archivetagreader.h | 1 | ||||
| -rw-r--r-- | src/plugins/Input/archive/decoder_archive.cpp | 40 | ||||
| -rw-r--r-- | src/plugins/Input/archive/decoder_archive.h | 2 | ||||
| -rw-r--r-- | src/plugins/Input/archive/decoderarchivefactory.cpp | 29 | ||||
| -rw-r--r-- | src/plugins/Input/archive/decoderarchivefactory.h | 3 |
11 files changed, 195 insertions, 46 deletions
diff --git a/src/plugins/Input/archive/archive.pro b/src/plugins/Input/archive/archive.pro index 700954140..19cd3a301 100644 --- a/src/plugins/Input/archive/archive.pro +++ b/src/plugins/Input/archive/archive.pro @@ -4,13 +4,15 @@ HEADERS += \ archiveinputdevice.h \ decoderarchivefactory.h \ decoder_archive.h \ - archivetagreader.h + archivetagreader.h \ + archivemetadatamodel.h SOURCES += \ archiveinputdevice.cpp \ decoderarchivefactory.cpp \ decoder_archive.cpp \ - archivetagreader.cpp + archivetagreader.cpp \ + archivemetadatamodel.cpp TARGET=$$PLUGINS_PREFIX/Input/archive diff --git a/src/plugins/Input/archive/archiveinputdevice.cpp b/src/plugins/Input/archive/archiveinputdevice.cpp index d03a60a3d..795766ada 100644 --- a/src/plugins/Input/archive/archiveinputdevice.cpp +++ b/src/plugins/Input/archive/archiveinputdevice.cpp @@ -17,14 +17,65 @@ * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ + +#include <QRegExp> #include "archiveinputdevice.h" +ArchiveInputDevice::ArchiveInputDevice(const QString &url, QObject *parent) : QIODevice(parent) +{ + m_archive = 0; + m_entry = 0; + QString filePath = url.section("#", -1); + QString archivePath = url; + archivePath.remove(QRegExp("^.+://")); + archivePath.remove(QRegExp("#.+$")); + + m_archive = archive_read_new(); + archive_read_support_filter_all(m_archive); + archive_read_support_format_all(m_archive); + + int r = archive_read_open_filename(m_archive, archivePath.toLocal8Bit().constData(), 10240); + if (r != ARCHIVE_OK) + { + qWarning("ArchiveInputDevice: unable to open file '%s', libarchive error: %s", + qPrintable(archivePath), archive_error_string(m_archive)); + return; + } + + while (archive_read_next_header(m_archive, &m_entry) == ARCHIVE_OK) + { + QString pathName = QString::fromLocal8Bit(archive_entry_pathname(m_entry)); + if(!pathName.startsWith("/")) + pathName.prepend("/"); + + if(archive_entry_filetype(m_entry) == AE_IFREG && filePath == pathName) + { + open(QIODevice::ReadOnly); + m_buffer.open(QBuffer::ReadWrite); + break; + } + archive_read_data_skip(m_archive); + } + m_close_libarchive = true; +} + ArchiveInputDevice::ArchiveInputDevice(archive *a, archive_entry *e, QObject *parent) : QIODevice(parent) { m_archive = a; m_entry = e; open(QIODevice::ReadOnly); m_buffer.open(QBuffer::ReadWrite); + m_close_libarchive = false; +} + +ArchiveInputDevice::~ArchiveInputDevice() +{ + if(m_close_libarchive && m_archive) + { + archive_read_close(m_archive); + archive_read_free(m_archive); + m_archive = 0; + } } bool ArchiveInputDevice::seek(qint64 pos) diff --git a/src/plugins/Input/archive/archiveinputdevice.h b/src/plugins/Input/archive/archiveinputdevice.h index 12010e76c..c70fc9793 100644 --- a/src/plugins/Input/archive/archiveinputdevice.h +++ b/src/plugins/Input/archive/archiveinputdevice.h @@ -17,6 +17,7 @@ * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ + #ifndef ARCHIVEINPUTDEVICE_H #define ARCHIVEINPUTDEVICE_H @@ -29,7 +30,9 @@ class ArchiveInputDevice : public QIODevice { Q_OBJECT public: - ArchiveInputDevice(struct archive *a, struct archive_entry *e, QObject *parent); + ArchiveInputDevice(const QString &url, QObject *parent = 0); + ArchiveInputDevice(struct archive *a, struct archive_entry *e, QObject *parent = 0); + virtual ~ArchiveInputDevice(); bool seek(qint64 pos); qint64 size() const; @@ -42,7 +45,7 @@ private: struct archive *m_archive; struct archive_entry *m_entry; QBuffer m_buffer; - + bool m_close_libarchive; }; #endif // ARCHIVEINPUTDEVICE_H diff --git a/src/plugins/Input/archive/archivemetadatamodel.cpp b/src/plugins/Input/archive/archivemetadatamodel.cpp new file mode 100644 index 000000000..02ee77770 --- /dev/null +++ b/src/plugins/Input/archive/archivemetadatamodel.cpp @@ -0,0 +1,56 @@ +/*************************************************************************** + * 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" +#include "archivetagreader.h" +#include "archivemetadatamodel.h" + +ArchiveMetaDataModel::ArchiveMetaDataModel(const QString &url, QObject *parent) : + MetaDataModel(parent) +{ + m_reader = 0; + m_input = 0; + m_input = new ArchiveInputDevice(url); + if(m_input->isOpen()) + m_reader = new ArchiveTagReader(m_input, url); +} + +ArchiveMetaDataModel::~ArchiveMetaDataModel() +{ + if(m_reader) + delete m_reader; + if(m_input) + delete m_input; +} + +QHash<QString, QString> ArchiveMetaDataModel::audioProperties() +{ + QHash <QString, QString> ap; + if(m_reader && m_reader->audioProperties()) + { + TagLib::AudioProperties *p = m_reader->audioProperties(); + ap.insert(tr("Length"), QString("%1:%2").arg(p->length()/60).arg(p->length()%60, 2, 10, QChar('0'))); + ap.insert(tr("Sample rate"), QString("%1 " + tr("Hz")).arg(p->sampleRate())); + ap.insert(tr("Channels"), QString("%1").arg(p->channels())); + ap.insert(tr("Bitrate"), QString("%1 " + tr("kbps")).arg(p->bitrate())); + ap.insert(tr("File size"), QString("%1 "+tr("KB")).arg(m_input->size()/1024)); + } + return ap; +} diff --git a/src/plugins/Input/archive/archivemetadatamodel.h b/src/plugins/Input/archive/archivemetadatamodel.h new file mode 100644 index 000000000..309c3b671 --- /dev/null +++ b/src/plugins/Input/archive/archivemetadatamodel.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * 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 ARCHIVEMETADATAMODEL_H +#define ARCHIVEMETADATAMODEL_H + +#include <QObject> +#include <qmmp/metadatamodel.h> + +class ArchiveInputDevice; +class ArchiveTagReader; + +class ArchiveMetaDataModel : public MetaDataModel +{ + Q_OBJECT +public: + explicit ArchiveMetaDataModel(const QString &url, QObject *parent = 0); + virtual ~ArchiveMetaDataModel(); + + QHash<QString, QString> audioProperties(); + +private: + ArchiveInputDevice *m_input; + ArchiveTagReader *m_reader; + +}; + +#endif // ARCHIVEMETADATAMODEL_H diff --git a/src/plugins/Input/archive/archivetagreader.cpp b/src/plugins/Input/archive/archivetagreader.cpp index 43a05f251..7497ddaf3 100644 --- a/src/plugins/Input/archive/archivetagreader.cpp +++ b/src/plugins/Input/archive/archivetagreader.cpp @@ -17,6 +17,7 @@ * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ + #include <taglib/tiostream.h> #include "archivetagreader.h" diff --git a/src/plugins/Input/archive/archivetagreader.h b/src/plugins/Input/archive/archivetagreader.h index b8536dbc0..f1314af40 100644 --- a/src/plugins/Input/archive/archivetagreader.h +++ b/src/plugins/Input/archive/archivetagreader.h @@ -17,6 +17,7 @@ * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ + #ifndef ARCHIVETAGREADER_H #define ARCHIVETAGREADER_H diff --git a/src/plugins/Input/archive/decoder_archive.cpp b/src/plugins/Input/archive/decoder_archive.cpp index 6d1d43c3d..07fdd5ddb 100644 --- a/src/plugins/Input/archive/decoder_archive.cpp +++ b/src/plugins/Input/archive/decoder_archive.cpp @@ -17,6 +17,7 @@ * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ + #include <QFile> #include <archive_entry.h> #include "archiveinputdevice.h" @@ -26,7 +27,6 @@ DecoderArchive::DecoderArchive(const QString &url) { m_url = url; - m_archive = 0; m_decoder = 0; m_input = 0; } @@ -43,12 +43,6 @@ DecoderArchive::~DecoderArchive() delete m_input; m_input = 0; } - if(m_archive) - { - archive_read_close(m_archive); - archive_read_free(m_archive); - m_archive = 0; - } } bool DecoderArchive::initialize() @@ -78,37 +72,11 @@ bool DecoderArchive::initialize() return false; } - m_archive = archive_read_new(); - archive_read_support_filter_all(m_archive); - archive_read_support_format_all(m_archive); - - int r = archive_read_open_filename(m_archive, archivePath.toLocal8Bit().constData(), 10240); - if (r != ARCHIVE_OK) - { - qWarning("DecoderArchive: unable to open file '%s', error code: %d", qPrintable(archivePath), r); - return false; - } - - struct archive_entry *entry = 0; - - while (archive_read_next_header(m_archive, &entry) == ARCHIVE_OK) - { - QString pathName = QString::fromLocal8Bit(archive_entry_pathname(entry)); - if(!pathName.startsWith("/")) - pathName.prepend("/"); - - if(archive_entry_filetype(entry) == AE_IFREG && filePath == pathName) - { - m_input = new ArchiveInputDevice(m_archive, entry, 0); - break; - } - archive_read_data_skip(m_archive); - } + m_input = new ArchiveInputDevice(m_url); - if(!m_input) + if(!m_input->isOpen()) { - qWarning("DecoderArchive: unable to find file '%s' inside archive '%s'", qPrintable(filePath), - qPrintable(archivePath)); + qWarning("DecoderArchive: unable to open archive"); return false; } diff --git a/src/plugins/Input/archive/decoder_archive.h b/src/plugins/Input/archive/decoder_archive.h index 3c5935e21..028cf7d14 100644 --- a/src/plugins/Input/archive/decoder_archive.h +++ b/src/plugins/Input/archive/decoder_archive.h @@ -17,6 +17,7 @@ * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ + #ifndef DECODERARCHIVE_H #define DECODERARCHIVE_H @@ -40,7 +41,6 @@ public: private: QString m_url; - struct archive *m_archive; Decoder *m_decoder; QIODevice *m_input; diff --git a/src/plugins/Input/archive/decoderarchivefactory.cpp b/src/plugins/Input/archive/decoderarchivefactory.cpp index b7fa24f85..126d5734b 100644 --- a/src/plugins/Input/archive/decoderarchivefactory.cpp +++ b/src/plugins/Input/archive/decoderarchivefactory.cpp @@ -17,6 +17,7 @@ * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ + #include <QRegExp> #include <QMessageBox> #include <QTranslator> @@ -26,9 +27,10 @@ #include "decoder_archive.h" #include "archivetagreader.h" #include "archiveinputdevice.h" +#include "archivemetadatamodel.h" #include "decoderarchivefactory.h" -// DecoderArchiveFileFactory +// DecoderArchiveFactory bool DecoderArchiveFactory::canDecode(QIODevice *) const { return false; @@ -54,7 +56,7 @@ Decoder *DecoderArchiveFactory::create(const QString &url, QIODevice *) return new DecoderArchive(url); } -QList<FileInfo *> DecoderArchiveFactory::createPlayList(const QString &archivePath, bool useMetaData, QStringList *) +QList<FileInfo *> DecoderArchiveFactory::createPlayList(const QString &path, bool useMetaData, QStringList *) { QList <FileInfo *> list; struct archive_entry *entry = 0; @@ -63,6 +65,19 @@ QList<FileInfo *> DecoderArchiveFactory::createPlayList(const QString &archivePa archive_read_support_filter_all(a); archive_read_support_format_all(a); + QString archivePath, requiredFilePath; + if(path.contains("://")) + { + requiredFilePath = path.section("#", -1); + archivePath = path; + archivePath.remove(QRegExp("^.+://")); + archivePath.remove(QRegExp("#.+$")); + } + else + { + archivePath = path; + } + if(archive_read_open_filename(a, archivePath.toLocal8Bit().constData(), 10240) != ARCHIVE_OK) { qWarning("DecoderArchiveFactory: unable to open archive; libarchive error: %s", archive_error_string(a)); @@ -76,6 +91,12 @@ QList<FileInfo *> DecoderArchiveFactory::createPlayList(const QString &archivePa if(!filePath.startsWith("/")) filePath.prepend("/"); + if(!requiredFilePath.isEmpty() && filePath != requiredFilePath) + { + archive_read_data_skip(a); + continue; + } + //is this file supported by qmmp? QList<DecoderFactory *> filtered = Decoder::findByFileExtension(filePath); foreach (DecoderFactory *f, filtered) @@ -107,9 +128,9 @@ QList<FileInfo *> DecoderArchiveFactory::createPlayList(const QString &archivePa return list; } -MetaDataModel* DecoderArchiveFactory::createMetaDataModel(const QString&, QObject *) +MetaDataModel* DecoderArchiveFactory::createMetaDataModel(const QString &path, QObject *parent) { - return 0; + return new ArchiveMetaDataModel(path, parent); } void DecoderArchiveFactory::showSettings(QWidget *) diff --git a/src/plugins/Input/archive/decoderarchivefactory.h b/src/plugins/Input/archive/decoderarchivefactory.h index 31d3f8b45..adc4426f4 100644 --- a/src/plugins/Input/archive/decoderarchivefactory.h +++ b/src/plugins/Input/archive/decoderarchivefactory.h @@ -17,6 +17,7 @@ * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ + #ifndef DECODERARCHIVEFACTORY_H #define DECODERARCHIVEFACTORY_H @@ -40,7 +41,7 @@ public: bool canDecode(QIODevice *) const; const DecoderProperties properties() const; Decoder *create(const QString &url, QIODevice *); - QList<FileInfo *> createPlayList(const QString &fileName, bool useMetaData, QStringList *); + QList<FileInfo *> createPlayList(const QString &path, bool useMetaData, QStringList *); MetaDataModel* createMetaDataModel(const QString &path, QObject *parent = 0); void showSettings(QWidget *parent); void showAbout(QWidget *parent); |
