Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qffmpegmediametadata.cpp
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5#include <QDebug>
6#include <QtCore/qdatetime.h>
7#include <qstringlist.h>
8#include <qurl.h>
9#include <qlocale.h>
10
11#include <qloggingcategory.h>
12
14
15static Q_LOGGING_CATEGORY(qLcMetaData, "qt.multimedia.ffmpeg.metadata")
16
17namespace {
18
19struct ffmpegTagToMetaDataKey
20{
21 const char *tag;
23};
24
25constexpr ffmpegTagToMetaDataKey ffmpegTagToMetaDataKey[] = {
26 { "title", QMediaMetaData::Title },
27 { "comment", QMediaMetaData::Comment },
28 { "description", QMediaMetaData::Description },
29 { "genre", QMediaMetaData::Genre },
30 { "date", QMediaMetaData::Date },
31 { "year", QMediaMetaData::Date },
32 { "creation_time", QMediaMetaData::Date },
33
34 { "language", QMediaMetaData::Language },
35
36 { "copyright", QMediaMetaData::Copyright },
37
38 // Music
39 { "album", QMediaMetaData::AlbumTitle },
40 { "album_artist", QMediaMetaData::AlbumArtist },
42 { "track", QMediaMetaData::TrackNumber },
43
44 // Movie
45 { "performer", QMediaMetaData::LeadPerformer },
46
47 { nullptr, QMediaMetaData::Title }
48};
49
50}
51
52static QMediaMetaData::Key tagToKey(const char *tag)
53{
54 const auto *map = ffmpegTagToMetaDataKey;
55 while (map->tag) {
56 if (!strcmp(map->tag, tag))
57 return map->key;
58 ++map;
59 }
60 return QMediaMetaData::Key(-1);
61}
62
63static const char *keyToTag(QMediaMetaData::Key key)
64{
65 const auto *map = ffmpegTagToMetaDataKey;
66 while (map->tag) {
67 if (map->key == key)
68 return map->tag;
69 ++map;
70 }
71 return nullptr;
72}
73
74//internal
75void QFFmpegMetaData::addEntry(QMediaMetaData &metaData, AVDictionaryEntry *entry)
76{
77 qCDebug(qLcMetaData) << " checking:" << entry->key << entry->value;
78 QByteArray tag(entry->key);
80 if (key == QMediaMetaData::Key(-1))
81 return;
82 qCDebug(qLcMetaData) << " adding" << key;
83
84 auto *map = &metaData;
85
86 int metaTypeId = keyType(key).id();
87 switch (metaTypeId) {
88 case qMetaTypeId<QString>():
90 return;
91 case qMetaTypeId<QStringList>():
92 map->insert(key, QString::fromUtf8(entry->value).split(QLatin1Char(',')));
93 return;
94 case qMetaTypeId<QDateTime>(): {
96 if (!qstrcmp(entry->key, "year")) {
98 return;
99 date = QDateTime(QDate(QByteArray(entry->value).toInt(), 1, 1), QTime(0, 0, 0));
100 } else {
101 date = QDateTime::fromString(QString::fromUtf8(entry->value), Qt::ISODate);
102 }
103 map->insert(key, date);
104 return;
105 }
106 case qMetaTypeId<QUrl>():
108 return;
109 case qMetaTypeId<qint64>():
110 map->insert(key, (qint64)QByteArray(entry->value).toLongLong());
111 return;
112 case qMetaTypeId<int>():
113 map->insert(key, QByteArray(entry->value).toInt());
114 return;
115 case qMetaTypeId<qreal>():
116 map->insert(key, (qreal)QByteArray(entry->value).toDouble());
117 return;
118 default:
119 break;
120 }
121 if (metaTypeId == qMetaTypeId<QLocale::Language>()) {
123 }
124}
125
126
128{
129 QMediaMetaData metaData;
130 AVDictionaryEntry *entry = nullptr;
131 while ((entry = av_dict_get(tags, "", entry, AV_DICT_IGNORE_SUFFIX)))
132 addEntry(metaData, entry);
133
134 return metaData;
135}
136
138{
139 const int metaTypeId = keyType(key).id();
140 const QVariant val = metaData.value(key);
141 switch (metaTypeId) {
142 case qMetaTypeId<QString>():
143 return val.toString().toUtf8();
144 case qMetaTypeId<QStringList>():
145 return val.toStringList().join(u",").toUtf8();
146 case qMetaTypeId<QDateTime>():
147 return val.toDateTime().toString(Qt::ISODate).toUtf8();
148 case qMetaTypeId<QUrl>():
149 return val.toUrl().toEncoded();
150 case qMetaTypeId<qint64>():
151 case qMetaTypeId<int>():
152 return QByteArray::number(val.toLongLong());
153 case qMetaTypeId<qreal>():
154 return QByteArray::number(val.toDouble());
155 default:
156 break;
157 }
158 if (metaTypeId == qMetaTypeId<QLocale::Language>())
160 return {};
161}
162
163
164AVDictionary *QFFmpegMetaData::toAVMetaData(const QMediaMetaData &metaData)
165{
166 const QList<Key> keys = metaData.keys();
167 AVDictionary *dict = nullptr;
168 for (const auto &k : keys) {
169 const char *key = ::keyToTag(k);
170 if (!key)
171 continue;
172 QByteArray val = value(metaData, k);
173 if (val.isEmpty())
174 continue;
175 av_dict_set(&dict, key, val.constData(), 0);
176 }
177 return dict;
178}
179
180
181
\inmodule QtCore
Definition qbytearray.h:57
static QByteArray number(int, int base=10)
Returns a byte-array representing the whole number n as text.
\inmodule QtCore\reentrant
Definition qdatetime.h:283
\inmodule QtCore \reentrant
Definition qdatetime.h:29
static QByteArray value(const QMediaMetaData &metaData, QMediaMetaData::Key key)
static AVDictionary * toAVMetaData(const QMediaMetaData &metaData)
static QMediaMetaData fromAVMetaData(const AVDictionary *tags)
static void addEntry(QMediaMetaData &metaData, AVDictionaryEntry *entry)
static QString languageToCode(Language language, LanguageCodeTypes codeTypes=AnyLanguageCode)
Returns the two- or three-letter language code for language, as defined in the ISO 639 standards.
Definition qlocale.cpp:1510
@ ISO639Part2
Definition qlocale.h:1109
static Language codeToLanguage(QStringView languageCode, LanguageCodeTypes codeTypes=AnyLanguageCode) noexcept
Returns the QLocale::Language enum corresponding to the two- or three-letter languageCode,...
Definition qlocale.cpp:1530
iterator insert(const Key &key, const T &value)
Definition qmap.h:688
QList< Key > keys() const
Definition qmap.h:383
Key key(const T &value, const Key &defaultKey=Key()) const
Definition qmap.h:349
\inmodule QtMultimedia
Q_INVOKABLE QVariant value(Key k) const
\variable QMediaMetaData::NumMetaData
Q_INVOKABLE QList< Key > keys() const
\qmlmethod list<Key> QtMultimedia::mediaMetaData::keys() Returns a list of MediaMetaData....
static QMetaType keyType(Key key)
Returns the meta type used to store data for Key key.
Key
Provides meta-data for media files.
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:6018
\inmodule QtCore \reentrant
Definition qdatetime.h:215
static QUrl fromEncoded(QByteArrayView input, ParsingMode mode=TolerantMode)
Parses input and returns the corresponding QUrl.
Definition qurl.cpp:2988
\inmodule QtCore
Definition qvariant.h:65
static auto fromValue(T &&value) noexcept(std::is_nothrow_copy_constructible_v< T > &&Private::CanUseInternalSpace< T >) -> std::enable_if_t< std::conjunction_v< std::is_copy_constructible< T >, std::is_destructible< T > >, QVariant >
Definition qvariant.h:536
QMap< QString, QString > map
[6]
QDate date
[1]
Combined button and popup list for selecting options.
@ ISODate
Q_CORE_EXPORT int qstrcmp(const char *str1, const char *str2)
AudioChannelLayoutTag tag
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
static QMediaMetaData::Key tagToKey(const char *tag)
static const char * keyToTag(QMediaMetaData::Key key)
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
GLuint64 key
GLuint GLfloat * val
GLuint entry
long long qint64
Definition qtypes.h:60
double qreal
Definition qtypes.h:187
\inmodule QtCore \reentrant
Definition qchar.h:18
bool contains(const AT &t) const noexcept
Definition qlist.h:45