mirror of
https://bitbucket.org/smil3y/kdelibs.git
synced 2025-02-23 10:22:48 +00:00
kio: implement audio and video meta information extractor via TagLib
TODO: elide meta information values or this may happen: https://ibb.co/MZGv4Vz
This commit is contained in:
parent
5e6e38e9a6
commit
6197c25884
7 changed files with 303 additions and 5 deletions
|
@ -215,6 +215,14 @@ set_package_properties(FFmpeg PROPERTIES
|
|||
PURPOSE "Video metadata extraction"
|
||||
)
|
||||
|
||||
macro_optional_find_package(Taglib)
|
||||
set_package_properties(Taglib PROPERTIES
|
||||
DESCRIPTION "TagLib Audio Meta-Data Library"
|
||||
URL "https://taglib.org/"
|
||||
TYPE RECOMMENDED
|
||||
PURPOSE "Audio metadata extraction"
|
||||
)
|
||||
|
||||
macro_optional_find_package(OpenSSL)
|
||||
set_package_properties(OpenSSL PROPERTIES
|
||||
DESCRIPTION "Robust, commercial-grade, full-featured toolkit for general-purpose cryptography and secure communication"
|
||||
|
|
|
@ -23,7 +23,8 @@ build_script:
|
|||
libavahi-common-dev libwebp-dev libudev-dev liblzma-dev \
|
||||
libexiv2-dev libcdio-dev libssl-dev libcurl4-openssl-dev \
|
||||
libdbusmenu-katie libavcodec-dev libavutil-dev libavformat-dev \
|
||||
media-player-info shared-mime-info media-player-info xdg-utils ccache
|
||||
libtag1-dev media-player-info shared-mime-info media-player-info \
|
||||
xdg-utils ccache
|
||||
|
||||
export PATH="/usr/lib/ccache/:$PATH"
|
||||
|
||||
|
|
|
@ -235,6 +235,9 @@ QString KFileMetaInfo::name(const QString& key)
|
|||
{ "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#width", i18nc("@label", "Width") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#height", i18nc("@label", "Height") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#averageBitrate", i18nc("@label", "Average Bitrate") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#sampleRate", i18nc("@label", "Sample Rate") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#channels", i18nc("@label", "Channels") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#duration", i18nc("@label", "Duration") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#copyright", i18nc("@label", "Copyright") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#comment", i18nc("@label", "Comment") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#title", i18nc("@label music title", "Title") },
|
||||
|
@ -249,6 +252,7 @@ QString KFileMetaInfo::name(const QString& key)
|
|||
{ "http://www.semanticdesktop.org/ontologies/2007/05/10/nid3#composer", i18nc("@label music composer", "Composer") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/05/10/nid3#encoder", i18nc("@label", "Encoder") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/05/10/nid3#encodedBy", i18nc("@label", "Encoded By") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/05/10/nid3#originalReleaseYear", i18nc("@label", "Original Release Year") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/03/22/nco#publisher", i18nc("@label", "Publisher") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#make", i18nc("@label EXIF", "Manufacturer") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#model", i18nc("@label EXIF", "Model") },
|
||||
|
@ -281,7 +285,6 @@ QString KFileMetaInfo::name(const QString& key)
|
|||
{ "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#wordCount", i18nc("@label number of words", "Words") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#characterCount", i18nc("@label", "Character Count") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/04/02/ncal#sequence", i18nc("@label", "Revision") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#duration", i18nc("@label", "Duration") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/03/22/nco#Contact", i18nc("@label", "Contact") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#disclaimer", i18nc("@label", "Disclaimer") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/05/10/nid3#textWriter", i18nc("@label", "Text Writer") },
|
||||
|
@ -292,7 +295,6 @@ QString KFileMetaInfo::name(const QString& key)
|
|||
{ "http://www.semanticdesktop.org/ontologies/2007/05/10/nid3#beatsPerMinute", i18nc("@label", "Beats Per Minute") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/05/10/nid3#originalArtist", i18nc("@label", "Original Artist") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/05/10/nid3#originalTextWriter", i18nc("@label", "Original Text Writer") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/05/10/nid3#originalReleaseYear", i18nc("@label", "Original Release Year") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/05/10/nid3#SynchronizedText", i18nc("@label", "Lyrics") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/05/10/nid3#licensee", i18nc("@label", "Licensee") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/05/10/nid3#InvolvedPerson", i18nc("@label", "Musician Credits") },
|
||||
|
@ -304,8 +306,6 @@ QString KFileMetaInfo::name(const QString& key)
|
|||
{ "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#belongsToContainer", i18nc("@label", "Container Format") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/05/10/nid3#uniqueFileIdentifier", i18nc("@label", "URI") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/04/02/ncal#UnionOfEventJournalTodo", i18nc("@label", "Grouping") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#channels", i18nc("@label", "Channels") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#sampleRate", i18nc("@label", "Sample Rate") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#audioBitDepth", i18nc("@label", "Audio Bit Depth") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#audioBitRate", i18nc("@label", "Audio Bit Rate") },
|
||||
{ "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#videoBitDepth", i18nc("@label", "Video Bit Depth") },
|
||||
|
|
|
@ -37,3 +37,25 @@ if (FFMPEG_FOUND)
|
|||
DESTINATION ${KDE4_SERVICES_INSTALL_DIR}
|
||||
)
|
||||
endif()
|
||||
|
||||
if (TAGLIB_FOUND)
|
||||
include_directories(${TAGLIB_INCLUDES})
|
||||
|
||||
set(kfilemetadata_taglib_SRCS kfilemetadata_taglib.cpp)
|
||||
|
||||
kde4_add_plugin(kfilemetadata_taglib ${kfilemetadata_taglib_SRCS})
|
||||
target_link_libraries(kfilemetadata_taglib
|
||||
${KDE4_KIO_LIBS}
|
||||
${TAGLIB_LIBRARIES}
|
||||
)
|
||||
|
||||
install(
|
||||
TARGETS kfilemetadata_taglib
|
||||
DESTINATION ${KDE4_PLUGIN_INSTALL_DIR}
|
||||
)
|
||||
|
||||
install(
|
||||
FILES kfilemetadata_taglib.desktop
|
||||
DESTINATION ${KDE4_SERVICES_INSTALL_DIR}
|
||||
)
|
||||
endif()
|
||||
|
|
224
kio/metadata/kfilemetadata_taglib.cpp
Normal file
224
kio/metadata/kfilemetadata_taglib.cpp
Normal file
|
@ -0,0 +1,224 @@
|
|||
/* This file is part of the KDE libraries
|
||||
Copyright (C) 2022 Ivailo Monev <xakepa10@gmail.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License version 2, as published by the Free Software Foundation.
|
||||
|
||||
This library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public License
|
||||
along with this library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "kfilemetadata_taglib.h"
|
||||
#include "kpluginfactory.h"
|
||||
#include "kmimetype.h"
|
||||
#include "kglobal.h"
|
||||
#include "klocale.h"
|
||||
#include "kdebug.h"
|
||||
|
||||
#include <taglib/fileref.h>
|
||||
#include <taglib/tag.h>
|
||||
|
||||
KFileMetaDataTagLibPlugin::KFileMetaDataTagLibPlugin(QObject* parent, const QVariantList &args)
|
||||
: KFileMetaDataPlugin(parent)
|
||||
{
|
||||
Q_UNUSED(args);
|
||||
}
|
||||
|
||||
KFileMetaDataTagLibPlugin::~KFileMetaDataTagLibPlugin()
|
||||
{
|
||||
}
|
||||
|
||||
QStringList KFileMetaDataTagLibPlugin::keys() const
|
||||
{
|
||||
static const QStringList result = QStringList()
|
||||
<< QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/01/19/nie#title")
|
||||
<< QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#artist")
|
||||
<< QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#musicAlbum")
|
||||
<< QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/01/19/nie#comment")
|
||||
<< QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#genre")
|
||||
<< QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/05/10/nid3#originalReleaseYear")
|
||||
<< QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#trackNumber")
|
||||
<< QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#duration")
|
||||
<< QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#averageBitrate")
|
||||
<< QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#sampleRate")
|
||||
<< QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#channels");
|
||||
return result;
|
||||
}
|
||||
|
||||
QStringList KFileMetaDataTagLibPlugin::mimeTypes() const
|
||||
{
|
||||
static const QStringList result = QStringList()
|
||||
<< QString::fromLatin1("audio/x-ape")
|
||||
<< QString::fromLatin1("application/vnd.ms-asf")
|
||||
<< QString::fromLatin1("video/x-ms-asf")
|
||||
<< QString::fromLatin1("audio/x-flac")
|
||||
<< QString::fromLatin1("audio/flac")
|
||||
<< QString::fromLatin1("audio/x-flac+ogg")
|
||||
<< QString::fromLatin1("audio/x-oggflac")
|
||||
<< QString::fromLatin1("audio/x-it")
|
||||
<< QString::fromLatin1("audio/x-mod")
|
||||
<< QString::fromLatin1("audio/mp4")
|
||||
<< QString::fromLatin1("video/mp4")
|
||||
<< QString::fromLatin1("audio/x-musepack")
|
||||
<< QString::fromLatin1("audio/mpeg")
|
||||
<< QString::fromLatin1("audio/x-mpeg")
|
||||
<< QString::fromLatin1("video/mpeg")
|
||||
<< QString::fromLatin1("video/x-mpeg")
|
||||
<< QString::fromLatin1("audio/ogg")
|
||||
<< QString::fromLatin1("audio/x-ogg")
|
||||
<< QString::fromLatin1("video/ogg")
|
||||
<< QString::fromLatin1("video/x-ogg")
|
||||
<< QString::fromLatin1("audio/x-vorbis+ogg")
|
||||
<< QString::fromLatin1("audio/x-flac+ogg")
|
||||
<< QString::fromLatin1("audio/x-oggflac")
|
||||
<< QString::fromLatin1("audio/x-opus+ogg")
|
||||
<< QString::fromLatin1("video/x-theora+ogg")
|
||||
<< QString::fromLatin1("video/x-ogm+ogg")
|
||||
<< QString::fromLatin1("audio/x-riff")
|
||||
<< QString::fromLatin1("audio/x-s3m")
|
||||
<< QString::fromLatin1("audio/x-tta")
|
||||
<< QString::fromLatin1("audio/wav")
|
||||
<< QString::fromLatin1("audio/vnd.wave")
|
||||
<< QString::fromLatin1("audio/x-wav")
|
||||
<< QString::fromLatin1("audio/x-wavpack")
|
||||
<< QString::fromLatin1("audio/x-xm");
|
||||
return result;
|
||||
}
|
||||
|
||||
QList<KFileMetaInfoItem> KFileMetaDataTagLibPlugin::metaData(const KUrl &url, const KFileMetaInfo::WhatFlags flags)
|
||||
{
|
||||
Q_UNUSED(flags);
|
||||
QList<KFileMetaInfoItem> result;
|
||||
const QByteArray urlpath = url.toLocalFile().toLocal8Bit();
|
||||
TagLib::FileRef taglibfile(urlpath);
|
||||
if (taglibfile.isNull()) {
|
||||
kWarning() << "Could not open" << urlpath;
|
||||
return result;
|
||||
}
|
||||
TagLib::Tag *taglibtag = taglibfile.tag();
|
||||
if (!taglibtag) {
|
||||
kDebug() << "Null tag for" << urlpath;
|
||||
} else {
|
||||
const QString taglibtitle = QString::fromStdString(taglibtag->title().to8Bit(true));
|
||||
if (!taglibtitle.isEmpty()) {
|
||||
result.append(
|
||||
KFileMetaInfoItem(
|
||||
QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/01/19/nie#title"),
|
||||
taglibtitle
|
||||
)
|
||||
);
|
||||
}
|
||||
const QString taglibartist = QString::fromStdString(taglibtag->artist().to8Bit(true));
|
||||
if (!taglibartist.isEmpty()) {
|
||||
result.append(
|
||||
KFileMetaInfoItem(
|
||||
QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#artist"),
|
||||
taglibartist
|
||||
)
|
||||
);
|
||||
}
|
||||
const QString taglibalbum = QString::fromStdString(taglibtag->album().to8Bit(true));
|
||||
if (!taglibalbum.isEmpty()) {
|
||||
result.append(
|
||||
KFileMetaInfoItem(
|
||||
QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#musicAlbum"),
|
||||
taglibalbum
|
||||
)
|
||||
);
|
||||
}
|
||||
const QString taglibcomment = QString::fromStdString(taglibtag->comment().to8Bit(true));
|
||||
if (!taglibcomment.isEmpty()) {
|
||||
result.append(
|
||||
KFileMetaInfoItem(
|
||||
QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/01/19/nie#comment"),
|
||||
taglibcomment
|
||||
)
|
||||
);
|
||||
}
|
||||
const QString taglibgenre = QString::fromStdString(taglibtag->genre().to8Bit(true));
|
||||
if (!taglibgenre.isEmpty()) {
|
||||
result.append(
|
||||
KFileMetaInfoItem(
|
||||
QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#genre"),
|
||||
taglibgenre
|
||||
)
|
||||
);
|
||||
}
|
||||
const QString taglibyear = QString::number(taglibtag->year());
|
||||
if (!taglibyear.isEmpty() && taglibtag->year() > 0) {
|
||||
result.append(
|
||||
KFileMetaInfoItem(
|
||||
QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/05/10/nid3#originalReleaseYear"),
|
||||
taglibyear
|
||||
)
|
||||
);
|
||||
}
|
||||
const QString taglibtrack = QString::number(taglibtag->track());
|
||||
if (!taglibtrack.isEmpty() && taglibtag->track() > 0) {
|
||||
result.append(
|
||||
KFileMetaInfoItem(
|
||||
QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#trackNumber"),
|
||||
taglibtrack
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
TagLib::AudioProperties *taglibaudio = taglibfile.audioProperties();
|
||||
if (!taglibaudio) {
|
||||
kDebug() << "Null audio properties for" << urlpath;
|
||||
} else {
|
||||
const QString tagliblength = KGlobal::locale()->formatTime(
|
||||
QTime().addSecs(taglibaudio->length()),
|
||||
true, true
|
||||
);
|
||||
if (!tagliblength.isEmpty() && taglibaudio->length() > 0) {
|
||||
result.append(
|
||||
KFileMetaInfoItem(
|
||||
QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#duration"),
|
||||
tagliblength
|
||||
)
|
||||
);
|
||||
}
|
||||
const QString taglibbitrate = i18n("%1 kb/s", taglibaudio->bitrate());
|
||||
if (!taglibbitrate.isEmpty() && taglibaudio->bitrate() > 0) {
|
||||
result.append(
|
||||
KFileMetaInfoItem(
|
||||
QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#averageBitrate"),
|
||||
taglibbitrate
|
||||
)
|
||||
);
|
||||
}
|
||||
const QString taglibsamplerate = i18n("%1 Hz", taglibaudio->sampleRate());
|
||||
if (!taglibsamplerate.isEmpty() && taglibaudio->sampleRate() > 0) {
|
||||
result.append(
|
||||
KFileMetaInfoItem(
|
||||
QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#sampleRate"),
|
||||
taglibsamplerate
|
||||
)
|
||||
);
|
||||
}
|
||||
const QString taglibchannels = QString::number(taglibaudio->channels());
|
||||
if (!taglibchannels.isEmpty() && taglibaudio->channels() > 0) {
|
||||
result.append(
|
||||
KFileMetaInfoItem(
|
||||
QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#channels"),
|
||||
taglibchannels
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
K_PLUGIN_FACTORY(KFileMetaDataTagLibPluginFactory, registerPlugin<KFileMetaDataTagLibPlugin>();)
|
||||
K_EXPORT_PLUGIN(KFileMetaDataTagLibPluginFactory("kfilemetadata_taglib"))
|
||||
|
||||
#include "moc_kfilemetadata_taglib.cpp"
|
6
kio/metadata/kfilemetadata_taglib.desktop
Normal file
6
kio/metadata/kfilemetadata_taglib.desktop
Normal file
|
@ -0,0 +1,6 @@
|
|||
[Desktop Entry]
|
||||
Type=Service
|
||||
Name=KFileMetaDataTagLibPlugin
|
||||
X-KDE-Library=kfilemetadata_taglib
|
||||
X-KDE-ServiceTypes=KFileMetaData/Plugin
|
||||
InitialPreference=1
|
37
kio/metadata/kfilemetadata_taglib.h
Normal file
37
kio/metadata/kfilemetadata_taglib.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/* This file is part of the KDE libraries
|
||||
Copyright (C) 2022 Ivailo Monev <xakepa10@gmail.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License version 2, as published by the Free Software Foundation.
|
||||
|
||||
This library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public License
|
||||
along with this library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef KFILEMETADATA_TAGLIB_H
|
||||
#define KFILEMETADATA_TAGLIB_H
|
||||
|
||||
#include "kfilemetadata.h"
|
||||
|
||||
class KFileMetaDataTagLibPlugin : public KFileMetaDataPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
KFileMetaDataTagLibPlugin(QObject* parent, const QVariantList &args);
|
||||
~KFileMetaDataTagLibPlugin();
|
||||
|
||||
QStringList keys() const final;
|
||||
QStringList mimeTypes() const final;
|
||||
|
||||
QList<KFileMetaInfoItem> metaData(const KUrl &url, const KFileMetaInfo::WhatFlags flags) final;
|
||||
};
|
||||
|
||||
#endif // KFILEMETADATA_TAGLIB_H
|
Loading…
Add table
Reference in a new issue