From 0e2ffeebe9348f9c609d37e20b26fc8b4ce193d4 Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Thu, 14 Apr 2022 08:04:46 +0300 Subject: [PATCH] kio: implement audio and video meta information extractor via FFmpeg --- CMakeLists.txt | 8 + appveyor.yml | 4 +- cmake/modules/CMakeLists.txt | 1 + cmake/modules/FindFFmpeg.cmake | 45 +++++ kio/kio/kfilemetainfo.cpp | 22 +- kio/metadata/CMakeLists.txt | 26 ++- kio/metadata/kfilemetadata_ffmpeg.cpp | 233 ++++++++++++++++++++++ kio/metadata/kfilemetadata_ffmpeg.desktop | 6 + kio/metadata/kfilemetadata_ffmpeg.h | 37 ++++ 9 files changed, 366 insertions(+), 16 deletions(-) create mode 100644 cmake/modules/FindFFmpeg.cmake create mode 100644 kio/metadata/kfilemetadata_ffmpeg.cpp create mode 100644 kio/metadata/kfilemetadata_ffmpeg.desktop create mode 100644 kio/metadata/kfilemetadata_ffmpeg.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 9387092b..e1bbfb3a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -207,6 +207,14 @@ set_package_properties(Exiv2 PROPERTIES PURPOSE "Exiv2 metadata extraction and image rotation based on the data" ) +macro_optional_find_package(FFmpeg) +set_package_properties(FFmpeg PROPERTIES + DESCRIPTION "A complete, cross-platform solution to record, convert and stream audio and video" + URL "https://ffmpeg.org/" + TYPE RECOMMENDED + PURPOSE "Video 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" diff --git a/appveyor.yml b/appveyor.yml index 1c2eea97..aff3d514 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -21,8 +21,8 @@ build_script: sudo apt-get install -qq cmake katie-dev libenchant-dev \ libmagick++-dev libmpv-dev xorg-dev mesa-common-dev \ libavahi-common-dev libwebp-dev libudev-dev liblzma-dev \ - libexiv2-dev libbz2-dev libacl1-dev libcdio-dev \ - libcurl4-openssl-dev libssl-dev libdbusmenu-katie \ + libexiv2-dev libbz2-dev libacl1-dev libcdio-dev libssl-dev \ + libcurl4-openssl-dev libdbusmenu-katie libavutil-dev libavformat-dev \ media-player-info shared-mime-info media-player-info xdg-utils ccache export PATH="/usr/lib/ccache/:$PATH" diff --git a/cmake/modules/CMakeLists.txt b/cmake/modules/CMakeLists.txt index b6ee2fd2..f3eb52ce 100644 --- a/cmake/modules/CMakeLists.txt +++ b/cmake/modules/CMakeLists.txt @@ -14,6 +14,7 @@ set(cmakeFilesDontInstall FindACL.cmake FindLibCDIO.cmake FindDevinfo.cmake + FindFFmpeg.cmake ) # Explicitly list all files which will be installed. diff --git a/cmake/modules/FindFFmpeg.cmake b/cmake/modules/FindFFmpeg.cmake new file mode 100644 index 00000000..3fa14b5e --- /dev/null +++ b/cmake/modules/FindFFmpeg.cmake @@ -0,0 +1,45 @@ +# Try to find the FFmpeg library, once done this will define: +# +# FFMPEG_FOUND - system has FFmpeg +# FFMPEG_INCLUDES - the FFmpeg include directory +# FFMPEG_LIBRARIES - the libraries needed to use FFmpeg +# +# Copyright (c) 2022 Ivailo Monev +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +find_path(LIBAVFORMAT_INCLUDES + NAMES libavformat/avformat.h + HINTS $ENV{FFMPEGDIR}/include +) + +find_library(LIBAVFORMAT_LIBRARY + NAMES avformat + HINTS $ENV{FFMPEGDIR}/lib +) + +find_path(LIBAVUTIL_INCLUDES + NAMES libavutil/dict.h + HINTS $ENV{FFMPEGDIR}/include +) + +find_library(LIBAVUTIL_LIBRARY + NAMES avformat + HINTS $ENV{FFMPEGDIR}/lib +) + +if (LIBAVFORMAT_INCLUDES AND LIBAVUTIL_INCLUDES) + set(FFMPEG_INCLUDES ${LIBAVFORMAT_INCLUDES} ${LIBAVUTIL_INCLUDES}) +endif() + +if (LIBAVFORMAT_LIBRARY AND LIBAVUTIL_LIBRARY) + set(FFMPEG_LIBRARIES ${LIBAVFORMAT_LIBRARY} ${LIBAVUTIL_LIBRARY}) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(FFmpeg + REQUIRED_VARS FFMPEG_LIBRARIES FFMPEG_INCLUDES +) + +mark_as_advanced(FFMPEG_INCLUDES FFMPEG_LIBRARIES) diff --git a/kio/kio/kfilemetainfo.cpp b/kio/kio/kfilemetainfo.cpp index b26e39da..aa7a81fb 100644 --- a/kio/kio/kfilemetainfo.cpp +++ b/kio/kio/kfilemetainfo.cpp @@ -53,11 +53,11 @@ void KFileMetaInfoPrivate::init(const QString &filename, const KUrl &url, KFileM { m_url = url; + const KMimeType::Ptr filemimetype = KMimeType::findByUrl(url); const KService::List kfmdplugins = KServiceTypeTrader::self()->query("KFileMetaData/Plugin"); foreach (const KService::Ptr &kfmdplugin, kfmdplugins) { KFileMetaDataPlugin *kfmdplugininstance = kfmdplugin->createInstance(); if (kfmdplugininstance) { - const KMimeType::Ptr filemimetype = KMimeType::findByUrl(url); // qDebug() << Q_FUNC_INFO << filemimetype->name() << kfmdplugininstance->mimeTypes(); foreach (const QString &kfmdpluginmime, kfmdplugininstance->mimeTypes()) { if (filemimetype->is(kfmdpluginmime)) { @@ -234,12 +234,22 @@ QString KFileMetaInfo::name(const QString& key) { "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#url", i18nc("@label file URL", "URL") }, { "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/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") }, { "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#keyword", i18nc("@label", "Keyword") }, { "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#description", i18nc("@label", "Description") }, { "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#generator", i18nc("@label Software used to generate content", "Generator") }, + { "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#contentCreated", i18nc("@label creation date", "Created") }, + { "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#musicAlbum", i18nc("@label music album", "Album") }, + { "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#genre", i18nc("@label music genre", "Genre") }, + { "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#performer", i18nc("@label", "Performer") }, + { "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#trackNumber", i18nc("@label music track number", "Track") }, + { "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/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") }, { "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#orientation", i18nc("@label EXIF", "Orientation") }, @@ -260,13 +270,11 @@ QString KFileMetaInfo::name(const QString& key) { "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#pageCount", i18nc("@label", "Page Count") }, { "http://www.semanticdesktop.org/ontologies/2007/03/22/nco#creator", i18nc("@label", "Creator") }, { "http://www.semanticdesktop.org/ontologies/2007/03/22/nmo#Email", i18nc("@label", "Creator E-Mail") }, - { "http://www.semanticdesktop.org/ontologies/2007/03/22/nco#publisher", i18nc("@label", "Publisher") }, { "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#hashValue", i18nc("@label", "Hash Value") }, { "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#hashAlgorithm", i18nc("@label", "Hash Algorithm") }, { "http://www.semanticdesktop.org/ontologies/2007/03/22/nco#country", i18nc("@label", "Country") }, { "http://www.semanticdesktop.org/ontologies/2007/04/02/ncal#summary", i18nc("@label", "Summary") }, { "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#subject", i18nc("@label", "Subject") }, - { "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#contentCreated", i18nc("@label creation date", "Created") }, { "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#contentLastModified", i18nc("@label modification date", "Modified") }, { "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#characterSet", i18nc("@label", "Character Set") }, { "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#lineCount", i18nc("@label number of lines", "Lines") }, @@ -274,10 +282,6 @@ QString KFileMetaInfo::name(const QString& key) { "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/2009/02/19/nmm#musicAlbum", i18nc("@label music album", "Album") }, - { "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#genre", i18nc("@label music genre", "Genre") }, - { "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#trackNumber", i18nc("@label music track number", "Track") }, - { "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#performer", i18nc("@label", "Performer") }, { "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") }, @@ -285,9 +289,7 @@ QString KFileMetaInfo::name(const QString& key) { "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#director", i18nc("@label video director", "Director") }, { "http://www.semanticdesktop.org/ontologies/2007/05/10/nid3#conductor", i18nc("@label", "Conductor") }, { "http://www.semanticdesktop.org/ontologies/2007/05/10/nid3#interpretedBy", i18nc("@label", "Interpreted By") }, - { "http://www.semanticdesktop.org/ontologies/2007/05/10/nid3#composer", i18nc("@label music composer", "Composer") }, { "http://www.semanticdesktop.org/ontologies/2007/05/10/nid3#beatsPerMinute", i18nc("@label", "Beats Per Minute") }, - { "http://www.semanticdesktop.org/ontologies/2007/05/10/nid3#encodedBy", i18nc("@label", "Encoded By") }, { "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") }, @@ -300,8 +302,6 @@ QString KFileMetaInfo::name(const QString& key) { "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#audioCodec", i18nc("@label", "Audio Codec") }, { "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#subtitleCodec", i18nc("@label", "Subtitle Codec") }, { "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#belongsToContainer", i18nc("@label", "Container Format") }, - { "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#averageBitrate", i18nc("@label", "Average Bitrate") }, - { "http://www.semanticdesktop.org/ontologies/2007/05/10/nid3#encoder", i18nc("@label", "Encoder") }, { "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") }, diff --git a/kio/metadata/CMakeLists.txt b/kio/metadata/CMakeLists.txt index 8d348522..11242f25 100644 --- a/kio/metadata/CMakeLists.txt +++ b/kio/metadata/CMakeLists.txt @@ -1,4 +1,4 @@ -set(kfilemetadata_exiv2_SRCS kfilemetadata_exiv2.cpp ) +set(kfilemetadata_exiv2_SRCS kfilemetadata_exiv2.cpp) kde4_add_plugin(kfilemetadata_exiv2 ${kfilemetadata_exiv2_SRCS}) target_link_libraries(kfilemetadata_exiv2 @@ -11,9 +11,29 @@ install( DESTINATION ${KDE4_PLUGIN_INSTALL_DIR} ) -########### install files ############### - install( FILES kfilemetadata_exiv2.desktop DESTINATION ${KDE4_SERVICES_INSTALL_DIR} ) + +if (FFMPEG_FOUND) + include_directories(${FFMPEG_INCLUDES}) + + set(kfilemetadata_ffmpeg_SRCS kfilemetadata_ffmpeg.cpp) + + kde4_add_plugin(kfilemetadata_ffmpeg ${kfilemetadata_ffmpeg_SRCS}) + target_link_libraries(kfilemetadata_ffmpeg + ${KDE4_KIO_LIBS} + ${FFMPEG_LIBRARIES} + ) + + install( + TARGETS kfilemetadata_ffmpeg + DESTINATION ${KDE4_PLUGIN_INSTALL_DIR} + ) + + install( + FILES kfilemetadata_ffmpeg.desktop + DESTINATION ${KDE4_SERVICES_INSTALL_DIR} + ) +endif() diff --git a/kio/metadata/kfilemetadata_ffmpeg.cpp b/kio/metadata/kfilemetadata_ffmpeg.cpp new file mode 100644 index 00000000..c0099883 --- /dev/null +++ b/kio/metadata/kfilemetadata_ffmpeg.cpp @@ -0,0 +1,233 @@ +/* This file is part of the KDE libraries + Copyright (C) 2022 Ivailo Monev + + 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_ffmpeg.h" +#include "kpluginfactory.h" +#include "kmimetype.h" + +#include + +extern "C" { +#include +#include +} + +KFileMetaDataFFmpegPlugin::KFileMetaDataFFmpegPlugin(QObject* parent, const QVariantList &args) + : KFileMetaDataPlugin(parent) +{ + Q_UNUSED(args); +#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(58, 9, 100) + av_register_all(); +#endif +} + +KFileMetaDataFFmpegPlugin::~KFileMetaDataFFmpegPlugin() +{ +} + +QStringList KFileMetaDataFFmpegPlugin::keys() const +{ + static const QStringList result = QStringList() + << QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#musicAlbum") + << QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#artist") + << QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/01/19/nie#comment") + << QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/05/10/nid3#composer") + << QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/01/19/nie#copyright") + << QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/01/19/nie#contentCreated") + << QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/05/10/nid3#encoder") + << QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/05/10/nid3#encodedBy") + << QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#genre") + << QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#performer") + << QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/03/22/nco#publisher") + << QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/01/19/nie#title") + << QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#trackNumber") + << QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#averageBitrate"); + return result; +} + +QStringList KFileMetaDataFFmpegPlugin::mimeTypes() const +{ + QStringList result; + const AVCodecDescriptor* ffmpegcodec = avcodec_descriptor_next(NULL); + while (ffmpegcodec) { + if (ffmpegcodec->mime_types) { + int ffmpegcodeccounter = 0; + while (ffmpegcodec->mime_types[ffmpegcodeccounter]) { + // qDebug() << Q_FUNC_INFO << ffmpegcodec->mime_types[ffmpegcodeccounter]; + result.append(QString::fromLatin1(ffmpegcodec->mime_types[ffmpegcodeccounter])); + ffmpegcodeccounter++; + } + } + ffmpegcodec = avcodec_descriptor_next(ffmpegcodec); + } + // most of the above MIME types are for images or null so manually adding all audio and video + // MIME types + foreach (const KMimeType::Ptr &kmimetype, KMimeType::allMimeTypes()) { + if (kmimetype->name().startsWith("audio/") || kmimetype->name().startsWith("video/")) { + result.append(kmimetype->name()); + } + } + result.removeDuplicates(); + // qDebug() << Q_FUNC_INFO << result; + return result; +} + +QList KFileMetaDataFFmpegPlugin::metaData(const KUrl &url, const KFileMetaInfo::WhatFlags flags) +{ + Q_UNUSED(flags); + QList result; + const QByteArray urlpath = url.toLocalFile().toLocal8Bit(); + AVFormatContext *ffmpegcontext = NULL; + const int ffmpegresult = avformat_open_input(&ffmpegcontext, urlpath.constData(), NULL, NULL); + if (ffmpegresult != 0 || !ffmpegcontext) { + return result; + } + AVDictionaryEntry *ffmpegentry = av_dict_get(ffmpegcontext->metadata, "album", NULL, 0); + if (ffmpegentry) { + result.append( + KFileMetaInfoItem( + QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#musicAlbum"), + QString::fromUtf8(ffmpegentry->value) + ) + ); + } + ffmpegentry = av_dict_get(ffmpegcontext->metadata, "artist", NULL, 0); + if (ffmpegentry) { + result.append( + KFileMetaInfoItem( + QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#artist"), + QString::fromUtf8(ffmpegentry->value) + ) + ); + } + ffmpegentry = av_dict_get(ffmpegcontext->metadata, "comment", NULL, 0); + if (ffmpegentry) { + result.append( + KFileMetaInfoItem( + QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/01/19/nie#comment"), + QString::fromUtf8(ffmpegentry->value) + ) + ); + } + ffmpegentry = av_dict_get(ffmpegcontext->metadata, "composer", NULL, 0); + if (ffmpegentry) { + result.append( + KFileMetaInfoItem( + QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/05/10/nid3#composer"), + QString::fromUtf8(ffmpegentry->value) + ) + ); + } + ffmpegentry = av_dict_get(ffmpegcontext->metadata, "copyright", NULL, 0); + if (ffmpegentry) { + result.append( + KFileMetaInfoItem( + QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/01/19/nie#copyright"), + QString::fromUtf8(ffmpegentry->value) + ) + ); + } + ffmpegentry = av_dict_get(ffmpegcontext->metadata, "date", NULL, 0); + if (ffmpegentry) { + result.append( + KFileMetaInfoItem( + QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/01/19/nie#contentCreated"), + QString::fromUtf8(ffmpegentry->value) + ) + ); + } + ffmpegentry = av_dict_get(ffmpegcontext->metadata, "encoder", NULL, 0); + if (ffmpegentry) { + result.append( + KFileMetaInfoItem( + QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/05/10/nid3#encoder"), + QString::fromUtf8(ffmpegentry->value) + ) + ); + } + ffmpegentry = av_dict_get(ffmpegcontext->metadata, "encoded_by", NULL, 0); + if (ffmpegentry) { + result.append( + KFileMetaInfoItem( + QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/05/10/nid3#encodedBy"), + QString::fromUtf8(ffmpegentry->value) + ) + ); + } + ffmpegentry = av_dict_get(ffmpegcontext->metadata, "genre", NULL, 0); + if (ffmpegentry) { + result.append( + KFileMetaInfoItem( + QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#genre"), + QString::fromUtf8(ffmpegentry->value) + ) + ); + } + ffmpegentry = av_dict_get(ffmpegcontext->metadata, "performer", NULL, 0); + if (ffmpegentry) { + result.append( + KFileMetaInfoItem( + QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#performer"), + QString::fromUtf8(ffmpegentry->value) + ) + ); + } + ffmpegentry = av_dict_get(ffmpegcontext->metadata, "publisher", NULL, 0); + if (ffmpegentry) { + result.append( + KFileMetaInfoItem( + QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/03/22/nco#publisher"), + QString::fromUtf8(ffmpegentry->value) + ) + ); + } + ffmpegentry = av_dict_get(ffmpegcontext->metadata, "title", NULL, 0); + if (ffmpegentry) { + result.append( + KFileMetaInfoItem( + QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/01/19/nie#title"), + QString::fromUtf8(ffmpegentry->value) + ) + ); + } + ffmpegentry = av_dict_get(ffmpegcontext->metadata, "track", NULL, 0); + if (ffmpegentry) { + result.append( + KFileMetaInfoItem( + QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#trackNumber"), + QString::fromUtf8(ffmpegentry->value) + ) + ); + } + ffmpegentry = av_dict_get(ffmpegcontext->metadata, "variant_bitrate", NULL, 0); + if (ffmpegentry) { + result.append( + KFileMetaInfoItem( + QString::fromLatin1("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#averageBitrate"), + QString::fromUtf8(ffmpegentry->value) + ) + ); + } + avformat_free_context(ffmpegcontext); + return result; +} + +K_PLUGIN_FACTORY(KFileMetaDataFFmpegPluginFactory, registerPlugin();) +K_EXPORT_PLUGIN(KFileMetaDataFFmpegPluginFactory("kfilemetadata_ffmpeg")) + +#include "moc_kfilemetadata_ffmpeg.cpp" diff --git a/kio/metadata/kfilemetadata_ffmpeg.desktop b/kio/metadata/kfilemetadata_ffmpeg.desktop new file mode 100644 index 00000000..727e5600 --- /dev/null +++ b/kio/metadata/kfilemetadata_ffmpeg.desktop @@ -0,0 +1,6 @@ +[Desktop Entry] +Type=Service +Name=KFileMetaDataFFmpegPlugin +X-KDE-Library=kfilemetadata_ffmpeg +X-KDE-ServiceTypes=KFileMetaData/Plugin +InitialPreference=1 diff --git a/kio/metadata/kfilemetadata_ffmpeg.h b/kio/metadata/kfilemetadata_ffmpeg.h new file mode 100644 index 00000000..30c0c439 --- /dev/null +++ b/kio/metadata/kfilemetadata_ffmpeg.h @@ -0,0 +1,37 @@ +/* This file is part of the KDE libraries + Copyright (C) 2022 Ivailo Monev + + 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_FFMPEG_H +#define KFILEMETADATA_FFMPEG_H + +#include "kfilemetadata.h" + +class KFileMetaDataFFmpegPlugin : public KFileMetaDataPlugin +{ + Q_OBJECT +public: + KFileMetaDataFFmpegPlugin(QObject* parent, const QVariantList &args); + ~KFileMetaDataFFmpegPlugin(); + + QStringList keys() const final; + QStringList mimeTypes() const final; + + QList metaData(const KUrl &url, const KFileMetaInfo::WhatFlags flags) final; +}; + +#endif // KFILEMETADATA_FFMPEG_H