36 { AVMetadataCommonIdentifierTitle, AVMetadataIdentifieriTunesMetadataSongName,
37 AVMetadataIdentifierQuickTimeMetadataTitle,
38 AVMetadataIdentifierID3MetadataTitleDescription,
39 nil, AVMetadata3GPUserDataKeyTitle },
41 { AVMetadataCommonIdentifierAuthor,AVMetadataIdentifieriTunesMetadataAuthor,
42 AVMetadataIdentifierQuickTimeMetadataAuthor, nil,
43 AVMetadataQuickTimeUserDataKeyAuthor, AVMetadata3GPUserDataKeyAuthor },
45 { nil, AVMetadataIdentifieriTunesMetadataUserComment,
46 AVMetadataIdentifierQuickTimeMetadataComment, AVMetadataIdentifierID3MetadataComments,
47 AVMetadataQuickTimeUserDataKeyComment, nil },
49 { AVMetadataCommonIdentifierDescription,AVMetadataIdentifieriTunesMetadataDescription,
50 AVMetadataIdentifierQuickTimeMetadataDescription, nil,
51 AVMetadataQuickTimeUserDataKeyDescription, AVMetadata3GPUserDataKeyDescription },
53 { nil, AVMetadataIdentifieriTunesMetadataUserGenre,
54 AVMetadataIdentifierQuickTimeMetadataGenre, nil,
55 AVMetadataQuickTimeUserDataKeyGenre, AVMetadata3GPUserDataKeyGenre },
57 { AVMetadataCommonIdentifierCreationDate, AVMetadataIdentifieriTunesMetadataReleaseDate,
58 AVMetadataIdentifierQuickTimeMetadataCreationDate, AVMetadataIdentifierID3MetadataDate,
59 AVMetadataQuickTimeUserDataKeyCreationDate, AVMetadataISOUserDataKeyDate },
61 { AVMetadataCommonIdentifierLanguage, nil, nil, AVMetadataIdentifierID3MetadataLanguage, nil, nil },
63 { AVMetadataCommonIdentifierPublisher, AVMetadataIdentifieriTunesMetadataPublisher,
64 AVMetadataIdentifierQuickTimeMetadataPublisher, AVMetadataIdentifierID3MetadataPublisher, nil, nil },
66 { AVMetadataCommonIdentifierCopyrights, AVMetadataIdentifieriTunesMetadataCopyright,
67 AVMetadataIdentifierQuickTimeMetadataCopyright, AVMetadataIdentifierID3MetadataCopyright,
68 AVMetadataQuickTimeUserDataKeyCopyright, AVMetadataISOUserDataKeyCopyright },
70 { nil, nil, nil, AVMetadataIdentifierID3MetadataOfficialAudioSourceWebpage, nil, nil },
72 { nil, nil, nil, AVMetadataIdentifierID3MetadataLength, nil, nil },
74 { AVMetadataCommonIdentifierType, nil, nil, AVMetadataIdentifierID3MetadataContentType, nil, nil },
76 { nil, nil, nil, AVMetadataIdentifierID3MetadataFileType, nil, nil },
78 { nil, nil, nil, nil, nil, nil },
80 { nil, nil, nil, nil, nil, nil },
82 { nil, nil, nil, nil, nil, nil },
84 { nil, nil, nil, nil, nil, nil },
86 { nil, nil, AVMetadataIdentifierQuickTimeMetadataCameraFrameReadoutTime, nil, nil, nil },
88 { AVMetadataCommonIdentifierAlbumName, AVMetadataIdentifieriTunesMetadataAlbum,
89 AVMetadataIdentifierQuickTimeMetadataAlbum, AVMetadataIdentifierID3MetadataAlbumTitle,
90 AVMetadataQuickTimeUserDataKeyAlbum, AVMetadata3GPUserDataKeyAlbumAndTrack },
92 { nil, AVMetadataIdentifieriTunesMetadataAlbumArtist, nil, nil,
93 AVMetadataQuickTimeUserDataKeyArtist, AVMetadata3GPUserDataKeyPerformer },
95 { AVMetadataCommonIdentifierArtist, AVMetadataIdentifieriTunesMetadataArtist,
96 AVMetadataIdentifierQuickTimeMetadataArtist, nil, nil, nil },
98 { nil, AVMetadataIdentifieriTunesMetadataTrackNumber,
99 nil, AVMetadataIdentifierID3MetadataTrackNumber, nil, nil },
101 { nil, AVMetadataIdentifieriTunesMetadataComposer,
102 AVMetadataIdentifierQuickTimeMetadataComposer, AVMetadataIdentifierID3MetadataComposer, nil, nil },
104 { nil, AVMetadataIdentifieriTunesMetadataPerformer,
105 AVMetadataIdentifierQuickTimeMetadataPerformer, AVMetadataIdentifierID3MetadataLeadPerformer, nil, nil },
107 { nil, nil, nil, AVMetadataIdentifierID3MetadataAttachedPicture, nil, nil },
109 { AVMetadataCommonIdentifierArtwork, AVMetadataIdentifieriTunesMetadataCoverArt,
110 AVMetadataIdentifierQuickTimeMetadataArtwork, nil, nil, nil },
112 { nil, nil, AVMetadataIdentifierQuickTimeMetadataVideoOrientation, nil, nil, nil },
114 { nil, nil, nil, nil, nil, nil },
116 { nil, nil, nil, nil, nil, nil }
138 static_assert(
sizeof(keyToAVMetaDataID) /
sizeof(AVMetadataIDs) == QMediaMetaData::NumMetaData);
143 AVMetadataKey commonKey = item.commonKey;
144 if (commonKey.length != 0) {
145 if ([commonKey isEqualToString:AVMetadataCommonKeyTitle]) {
146 return QMediaMetaData::Title;
147 }
else if ([commonKey isEqualToString:AVMetadataCommonKeyDescription]) {
148 return QMediaMetaData::Description;
149 }
else if ([commonKey isEqualToString:AVMetadataCommonKeyPublisher]) {
150 return QMediaMetaData::Publisher;
151 }
else if ([commonKey isEqualToString:AVMetadataCommonKeyCreationDate]) {
152 return QMediaMetaData::Date;
153 }
else if ([commonKey isEqualToString:AVMetadataCommonKeyType]) {
154 return QMediaMetaData::MediaType;
155 }
else if ([commonKey isEqualToString:AVMetadataCommonKeyLanguage]) {
156 return QMediaMetaData::Language;
157 }
else if ([commonKey isEqualToString:AVMetadataCommonKeyCopyrights]) {
158 return QMediaMetaData::Copyright;
159 }
else if ([commonKey isEqualToString:AVMetadataCommonKeyAlbumName]) {
160 return QMediaMetaData::AlbumTitle;
161 }
else if ([commonKey isEqualToString:AVMetadataCommonKeyAuthor]) {
162 return QMediaMetaData::Author;
163 }
else if ([commonKey isEqualToString:AVMetadataCommonKeyArtist]) {
164 return QMediaMetaData::ContributingArtist;
170 enum keySpaces { iTunes, QuickTime, QuickTimeUserData, IsoUserData, ID3, Other } itemKeySpace;
171 itemKeySpace = Other;
172 AVMetadataKeySpace keySpace = [item keySpace];
173 AVMetadataIdentifier identifier = [item identifier];
175 if ([keySpace isEqualToString:AVMetadataKeySpaceiTunes]) {
176 itemKeySpace = iTunes;
177 }
else if ([keySpace isEqualToString:AVMetadataKeySpaceQuickTimeMetadata]) {
178 itemKeySpace = QuickTime;
179 }
else if ([keySpace isEqualToString:AVMetadataKeySpaceQuickTimeUserData]) {
180 itemKeySpace = QuickTimeUserData;
181 }
else if ([keySpace isEqualToString:AVMetadataKeySpaceISOUserData]) {
182 itemKeySpace = IsoUserData;
183 }
else if (([keySpace isEqualToString:AVMetadataKeySpaceID3])) {
187 for (
int key = 0; key < QMediaMetaData::NumMetaData; key++) {
188 AVMetadataIdentifier idForKey = nil;
189 switch (itemKeySpace) {
191 idForKey = keyToAVMetaDataID[key].iTunes;
194 idForKey = keyToAVMetaDataID[key].quickTime;
197 idForKey = keyToAVMetaDataID[key].ID3;
199 case QuickTimeUserData:
200 idForKey = keyToAVMetaDataID[key].quickTimeUserData;
203 idForKey = keyToAVMetaDataID[key].isoUserData;
209 if ([identifier isEqualToString:idForKey])
210 return QMediaMetaData::Key(key);
249 QMediaMetaData metadata = fromAVMetadata([asset metadata]);
250 if ([asset.mediaType isEqualToString:AVMediaTypeAudio]) {
251 if (metadata.value(QMediaMetaData::Language).isNull()) {
252 auto *languageCode = asset.languageCode;
256 QCFString lang = CFLocaleCreateCanonicalLanguageIdentifierFromString(
257 kCFAllocatorDefault, (__bridge CFStringRef)languageCode);
258 metadata.insert(QMediaMetaData::Language, QLocale::codeToLanguage(QString{ lang }));
262 if ([asset.mediaType isEqualToString:AVMediaTypeVideo]) {
264 if (metadata.value(QMediaMetaData::Orientation).isNull()) {
265 QtVideo::Rotation angle = QtVideo::Rotation::None;
267 AVFMediaPlayer::videoOrientationForAssetTrack(asset, angle, mirrored);
269 metadata.insert(QMediaMetaData::Orientation,
int(angle));
273 if (metadata.value(QMediaMetaData::HasHdrContent).isNull()) {
274 auto hasHdrContent =
false;
276 NSArray *formatDescriptions = [asset formatDescriptions];
277 for (id formatDescription in formatDescriptions) {
278 NSDictionary *extensions = (__bridge NSDictionary *)CMFormatDescriptionGetExtensions((CMFormatDescriptionRef)formatDescription);
279 NSString *transferFunction = extensions[(__bridge NSString *)kCMFormatDescriptionExtension_TransferFunction];
280 if ([transferFunction isEqualToString:(__bridge NSString *)kCVImageBufferTransferFunction_SMPTE_ST_2084_PQ]) {
281 hasHdrContent =
true;
286 metadata.insert(QMediaMetaData::HasHdrContent, hasHdrContent);
295 AVMetadataIdentifier identifier = toIdentifier(key, keySpace);
296 if (!identifier.length)
299 AVMutableMetadataItem *item = [AVMutableMetadataItem metadataItem];
300 item.keySpace = keySpace;
301 item.identifier = identifier;
304 case QMediaMetaData::ThumbnailImage:
305 case QMediaMetaData::CoverArtImage: {
306#if defined(Q_OS_MACOS)
307 QImage img = value.value<QImage>();
310 QBuffer buffer(&arr);
311 buffer.open(QIODevice::WriteOnly);
313 NSData *data = arr.toNSData();
314 NSImage *nsImg = [[NSImage alloc] initWithData:data];
321 case QMediaMetaData::FileFormat: {
322 QMediaFormat::FileFormat qtFormat = value.value<QMediaFormat::FileFormat>();
323 AVFileType avFormat = QDarwinFormatInfo::avFileTypeForContainerFormat(qtFormat);
324 item.value = avFormat;
327 case QMediaMetaData::Language: {
328 QString lang = QLocale::languageToCode(value.value<QLocale::Language>());
330 item.value = lang.toNSString();
333 case QMediaMetaData::Orientation: {
335 int rotation = value.toInt(&ok);
337 item.value = [NSNumber numberWithInt:rotation];
340 switch (value.typeId()) {
341 case QMetaType::QString: {
342 item.value = value.toString().toNSString();
345 case QMetaType::Int: {
346 item.value = [NSNumber numberWithInt:value.toInt()];
349 case QMetaType::LongLong: {
350 item.value = [NSNumber numberWithLongLong:value.toLongLong()];
353 case QMetaType::Double: {
354 item.value = [NSNumber numberWithDouble:value.toDouble()];
357 case QMetaType::QDate:
358 case QMetaType::QDateTime: {
359 item.value = value.toDateTime().toNSDate();
362 case QMetaType::QUrl: {
363 item.value = value.toUrl().toNSURL();