35 { AVMetadataCommonIdentifierTitle, AVMetadataIdentifieriTunesMetadataSongName,
36 AVMetadataIdentifierQuickTimeMetadataTitle,
37 AVMetadataIdentifierID3MetadataTitleDescription,
38 nil, AVMetadata3GPUserDataKeyTitle },
40 { AVMetadataCommonIdentifierAuthor,AVMetadataIdentifieriTunesMetadataAuthor,
41 AVMetadataIdentifierQuickTimeMetadataAuthor, nil,
42 AVMetadataQuickTimeUserDataKeyAuthor, AVMetadata3GPUserDataKeyAuthor },
44 { nil, AVMetadataIdentifieriTunesMetadataUserComment,
45 AVMetadataIdentifierQuickTimeMetadataComment, AVMetadataIdentifierID3MetadataComments,
46 AVMetadataQuickTimeUserDataKeyComment, nil },
48 { AVMetadataCommonIdentifierDescription,AVMetadataIdentifieriTunesMetadataDescription,
49 AVMetadataIdentifierQuickTimeMetadataDescription, nil,
50 AVMetadataQuickTimeUserDataKeyDescription, AVMetadata3GPUserDataKeyDescription },
52 { nil, AVMetadataIdentifieriTunesMetadataUserGenre,
53 AVMetadataIdentifierQuickTimeMetadataGenre, nil,
54 AVMetadataQuickTimeUserDataKeyGenre, AVMetadata3GPUserDataKeyGenre },
56 { AVMetadataCommonIdentifierCreationDate, AVMetadataIdentifieriTunesMetadataReleaseDate,
57 AVMetadataIdentifierQuickTimeMetadataCreationDate, AVMetadataIdentifierID3MetadataDate,
58 AVMetadataQuickTimeUserDataKeyCreationDate, AVMetadataISOUserDataKeyDate },
60 { AVMetadataCommonIdentifierLanguage, nil, nil, AVMetadataIdentifierID3MetadataLanguage, nil, nil },
62 { AVMetadataCommonIdentifierPublisher, AVMetadataIdentifieriTunesMetadataPublisher,
63 AVMetadataIdentifierQuickTimeMetadataPublisher, AVMetadataIdentifierID3MetadataPublisher, nil, nil },
65 { AVMetadataCommonIdentifierCopyrights, AVMetadataIdentifieriTunesMetadataCopyright,
66 AVMetadataIdentifierQuickTimeMetadataCopyright, AVMetadataIdentifierID3MetadataCopyright,
67 AVMetadataQuickTimeUserDataKeyCopyright, AVMetadataISOUserDataKeyCopyright },
69 { nil, nil, nil, AVMetadataIdentifierID3MetadataOfficialAudioSourceWebpage, nil, nil },
71 { nil, nil, nil, AVMetadataIdentifierID3MetadataLength, nil, nil },
73 { AVMetadataCommonIdentifierType, nil, nil, AVMetadataIdentifierID3MetadataContentType, nil, nil },
75 { nil, nil, nil, AVMetadataIdentifierID3MetadataFileType, nil, nil },
77 { nil, nil, nil, nil, nil, nil },
79 { nil, nil, nil, nil, nil, nil },
81 { nil, nil, nil, nil, nil, nil },
83 { nil, nil, nil, nil, nil, nil },
85 { nil, nil, AVMetadataIdentifierQuickTimeMetadataCameraFrameReadoutTime, nil, nil, nil },
87 { AVMetadataCommonIdentifierAlbumName, AVMetadataIdentifieriTunesMetadataAlbum,
88 AVMetadataIdentifierQuickTimeMetadataAlbum, AVMetadataIdentifierID3MetadataAlbumTitle,
89 AVMetadataQuickTimeUserDataKeyAlbum, AVMetadata3GPUserDataKeyAlbumAndTrack },
91 { nil, AVMetadataIdentifieriTunesMetadataAlbumArtist, nil, nil,
92 AVMetadataQuickTimeUserDataKeyArtist, AVMetadata3GPUserDataKeyPerformer },
94 { AVMetadataCommonIdentifierArtist, AVMetadataIdentifieriTunesMetadataArtist,
95 AVMetadataIdentifierQuickTimeMetadataArtist, nil, nil, nil },
97 { nil, AVMetadataIdentifieriTunesMetadataTrackNumber,
98 nil, AVMetadataIdentifierID3MetadataTrackNumber, nil, nil },
100 { nil, AVMetadataIdentifieriTunesMetadataComposer,
101 AVMetadataIdentifierQuickTimeMetadataComposer, AVMetadataIdentifierID3MetadataComposer, nil, nil },
103 { nil, AVMetadataIdentifieriTunesMetadataPerformer,
104 AVMetadataIdentifierQuickTimeMetadataPerformer, AVMetadataIdentifierID3MetadataLeadPerformer, nil, nil },
106 { nil, nil, nil, AVMetadataIdentifierID3MetadataAttachedPicture, nil, nil },
108 { AVMetadataCommonIdentifierArtwork, AVMetadataIdentifieriTunesMetadataCoverArt,
109 AVMetadataIdentifierQuickTimeMetadataArtwork, nil, nil, nil },
111 { nil, nil, AVMetadataIdentifierQuickTimeMetadataVideoOrientation, nil, nil, nil },
113 { nil, nil, nil, nil, nil, nil },
115 { nil, nil, nil, nil, nil, nil }
137 static_assert(
sizeof(keyToAVMetaDataID) /
sizeof(AVMetadataIDs) == QMediaMetaData::NumMetaData);
142 AVMetadataKey commonKey = item.commonKey;
143 if (commonKey.length != 0) {
144 if ([commonKey isEqualToString:AVMetadataCommonKeyTitle]) {
145 return QMediaMetaData::Title;
146 }
else if ([commonKey isEqualToString:AVMetadataCommonKeyDescription]) {
147 return QMediaMetaData::Description;
148 }
else if ([commonKey isEqualToString:AVMetadataCommonKeyPublisher]) {
149 return QMediaMetaData::Publisher;
150 }
else if ([commonKey isEqualToString:AVMetadataCommonKeyCreationDate]) {
151 return QMediaMetaData::Date;
152 }
else if ([commonKey isEqualToString:AVMetadataCommonKeyType]) {
153 return QMediaMetaData::MediaType;
154 }
else if ([commonKey isEqualToString:AVMetadataCommonKeyLanguage]) {
155 return QMediaMetaData::Language;
156 }
else if ([commonKey isEqualToString:AVMetadataCommonKeyCopyrights]) {
157 return QMediaMetaData::Copyright;
158 }
else if ([commonKey isEqualToString:AVMetadataCommonKeyAlbumName]) {
159 return QMediaMetaData::AlbumTitle;
160 }
else if ([commonKey isEqualToString:AVMetadataCommonKeyAuthor]) {
161 return QMediaMetaData::Author;
162 }
else if ([commonKey isEqualToString:AVMetadataCommonKeyArtist]) {
163 return QMediaMetaData::ContributingArtist;
169 enum keySpaces { iTunes, QuickTime, QuickTimeUserData, IsoUserData, ID3, Other } itemKeySpace;
170 itemKeySpace = Other;
171 AVMetadataKeySpace keySpace = [item keySpace];
172 AVMetadataIdentifier identifier = [item identifier];
174 if ([keySpace isEqualToString:AVMetadataKeySpaceiTunes]) {
175 itemKeySpace = iTunes;
176 }
else if ([keySpace isEqualToString:AVMetadataKeySpaceQuickTimeMetadata]) {
177 itemKeySpace = QuickTime;
178 }
else if ([keySpace isEqualToString:AVMetadataKeySpaceQuickTimeUserData]) {
179 itemKeySpace = QuickTimeUserData;
180 }
else if ([keySpace isEqualToString:AVMetadataKeySpaceISOUserData]) {
181 itemKeySpace = IsoUserData;
182 }
else if (([keySpace isEqualToString:AVMetadataKeySpaceID3])) {
186 for (
int key = 0; key < QMediaMetaData::NumMetaData; key++) {
187 AVMetadataIdentifier idForKey = nil;
188 switch (itemKeySpace) {
190 idForKey = keyToAVMetaDataID[key].iTunes;
193 idForKey = keyToAVMetaDataID[key].quickTime;
196 idForKey = keyToAVMetaDataID[key].ID3;
198 case QuickTimeUserData:
199 idForKey = keyToAVMetaDataID[key].quickTimeUserData;
202 idForKey = keyToAVMetaDataID[key].isoUserData;
208 if ([identifier isEqualToString:idForKey])
209 return QMediaMetaData::Key(key);
248 QMediaMetaData metadata = fromAVMetadata([asset metadata]);
249 if ([asset.mediaType isEqualToString:AVMediaTypeAudio]) {
250 if (metadata.value(QMediaMetaData::Language).isNull()) {
251 auto *languageCode = asset.languageCode;
255 auto id = CFLocaleCreateCanonicalLanguageIdentifierFromString(kCFAllocatorDefault,
256 (__bridge CFStringRef)languageCode);
257 QString lang = QString::fromCFString(id);
259 metadata.insert(QMediaMetaData::Language, QLocale::codeToLanguage(lang));
263 if ([asset.mediaType isEqualToString:AVMediaTypeVideo]) {
265 if (metadata.value(QMediaMetaData::Orientation).isNull()) {
266 QtVideo::Rotation angle = QtVideo::Rotation::None;
268 AVFMediaPlayer::videoOrientationForAssetTrack(asset, angle, mirrored);
270 metadata.insert(QMediaMetaData::Orientation,
int(angle));
274 if (metadata.value(QMediaMetaData::HasHdrContent).isNull()) {
275 auto hasHdrContent =
false;
277 NSArray *formatDescriptions = [asset formatDescriptions];
278 for (id formatDescription in formatDescriptions) {
279 NSDictionary *extensions = (__bridge NSDictionary *)CMFormatDescriptionGetExtensions((CMFormatDescriptionRef)formatDescription);
280 NSString *transferFunction = extensions[(__bridge NSString *)kCMFormatDescriptionExtension_TransferFunction];
281 if ([transferFunction isEqualToString:(__bridge NSString *)kCVImageBufferTransferFunction_SMPTE_ST_2084_PQ]) {
282 hasHdrContent =
true;
287 metadata.insert(QMediaMetaData::HasHdrContent, hasHdrContent);
296 AVMetadataIdentifier identifier = toIdentifier(key, keySpace);
297 if (!identifier.length)
300 AVMutableMetadataItem *item = [AVMutableMetadataItem metadataItem];
301 item.keySpace = keySpace;
302 item.identifier = identifier;
305 case QMediaMetaData::ThumbnailImage:
306 case QMediaMetaData::CoverArtImage: {
307#if defined(Q_OS_MACOS)
308 QImage img = value.value<QImage>();
311 QBuffer buffer(&arr);
312 buffer.open(QIODevice::WriteOnly);
314 NSData *data = arr.toNSData();
315 NSImage *nsImg = [[NSImage alloc] initWithData:data];
322 case QMediaMetaData::FileFormat: {
323 QMediaFormat::FileFormat qtFormat = value.value<QMediaFormat::FileFormat>();
324 AVFileType avFormat = QDarwinFormatInfo::avFileTypeForContainerFormat(qtFormat);
325 item.value = avFormat;
328 case QMediaMetaData::Language: {
329 QString lang = QLocale::languageToCode(value.value<QLocale::Language>());
331 item.value = lang.toNSString();
334 case QMediaMetaData::Orientation: {
336 int rotation = value.toInt(&ok);
338 item.value = [NSNumber numberWithInt:rotation];
341 switch (value.typeId()) {
342 case QMetaType::QString: {
343 item.value = value.toString().toNSString();
346 case QMetaType::Int: {
347 item.value = [NSNumber numberWithInt:value.toInt()];
350 case QMetaType::LongLong: {
351 item.value = [NSNumber numberWithLongLong:value.toLongLong()];
354 case QMetaType::Double: {
355 item.value = [NSNumber numberWithDouble:value.toDouble()];
358 case QMetaType::QDate:
359 case QMetaType::QDateTime: {
360 item.value = value.toDateTime().toNSDate();
363 case QMetaType::QUrl: {
364 item.value = value.toUrl().toNSURL();