1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
|
/* This file is part of the KDE project.
Copyright (C) 2007 Trolltech ASA. All rights reserved.
This library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 2.1 or 3 of the License.
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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "quicktimemetadata.h"
#include "backendheader.h"
#include <private/qcore_mac_p.h>
QT_BEGIN_NAMESPACE
namespace Phonon
{
namespace QT7
{
QuickTimeMetaData::QuickTimeMetaData()
{
m_movieRef = 0;
m_movieChanged = false;
}
QuickTimeMetaData::~QuickTimeMetaData()
{
}
void QuickTimeMetaData::setVideo(Movie movieRef)
{
m_movieRef = movieRef;
m_movieChanged = true;
m_metaData.clear();
}
QString QuickTimeMetaData::stripCopyRightSymbol(const QString &key)
{
return key.right(key.length()-1);
}
QString QuickTimeMetaData::convertQuickTimeKeyToUserKey(const QString &key)
{
if (key == QLatin1String("com.apple.quicktime.displayname"))
return QLatin1String("nam");
else if (key == QLatin1String("com.apple.quicktime.album"))
return QLatin1String("alb");
else if (key == QLatin1String("com.apple.quicktime.artist"))
return QLatin1String("ART");
else
return QLatin1String("???");
}
OSStatus QuickTimeMetaData::readMetaValue(QTMetaDataRef metaDataRef, QTMetaDataItem item, QTPropertyClass propClass,
QTPropertyID id, QTPropertyValuePtr *value, ByteCount *size)
{
QTPropertyValueType type;
ByteCount propSize;
UInt32 propFlags;
OSStatus err = QTMetaDataGetItemPropertyInfo(metaDataRef, item, propClass, id, &type, &propSize, &propFlags);
BACKEND_ASSERT3(err == noErr, "Could not read meta data value size", NORMAL_ERROR, err)
*value = malloc(propSize);
err = QTMetaDataGetItemProperty(metaDataRef, item, propClass, id, propSize, *value, size);
BACKEND_ASSERT3(err == noErr, "Could not read meta data value", NORMAL_ERROR, err)
if (type == 'code' || type == 'itsk' || type == 'itlk') {
// convert from native endian to big endian
OSTypePtr pType = (OSTypePtr)*value;
*pType = EndianU32_NtoB(*pType);
}
return err;
}
UInt32 QuickTimeMetaData::getMetaType(QTMetaDataRef metaDataRef, QTMetaDataItem item)
{
QTPropertyValuePtr value = 0;
ByteCount ignore = 0;
OSStatus err = readMetaValue(
metaDataRef, item, kPropertyClass_MetaDataItem, kQTMetaDataItemPropertyID_DataType, &value, &ignore);
BACKEND_ASSERT3(err == noErr, "Could not read meta data type", NORMAL_ERROR, 0)
UInt32 type = *((UInt32 *) value);
if (value)
free(value);
return type;
}
QString QuickTimeMetaData::getMetaValue(QTMetaDataRef metaDataRef, QTMetaDataItem item, SInt32 id)
{
QTPropertyValuePtr value = 0;
ByteCount size = 0;
OSStatus err = readMetaValue(metaDataRef, item, kPropertyClass_MetaDataItem, id, &value, &size);
BACKEND_ASSERT3(err == noErr, "Could not read meta data item", NORMAL_ERROR, QString())
BACKEND_ASSERT3(value != 0, "Could not read meta data item", NORMAL_ERROR, QString())
QString string;
UInt32 dataType = getMetaType(metaDataRef, item);
switch (dataType){
case kQTMetaDataTypeUTF8:
case kQTMetaDataTypeMacEncodedText:
string = QCFString::toQString(CFStringCreateWithBytes(0, (UInt8*)value, size, kCFStringEncodingUTF8, false));
break;
case kQTMetaDataTypeUTF16BE:
string = QCFString::toQString(CFStringCreateWithBytes(0, (UInt8*)value, size, kCFStringEncodingUTF16BE, false));
break;
default:
break;
}
if (value)
free(value);
return string;
}
void QuickTimeMetaData::readFormattedData(QTMetaDataRef metaDataRef, OSType format, QMultiMap<QString, QString> &result)
{
QTMetaDataItem item = kQTMetaDataItemUninitialized;
OSStatus err = QTMetaDataGetNextItem(metaDataRef, format, item, kQTMetaDataKeyFormatWildcard, 0, 0, &item);
while (err == noErr){
QString key = getMetaValue(metaDataRef, item, kQTMetaDataItemPropertyID_Key);
if (format == kQTMetaDataStorageFormatQuickTime)
key = convertQuickTimeKeyToUserKey(key);
else
key = stripCopyRightSymbol(key);
if (!result.contains(key)){
QString val = getMetaValue(metaDataRef, item, kQTMetaDataItemPropertyID_Value);
result.insert(key, val);
}
err = QTMetaDataGetNextItem(metaDataRef, format, item, kQTMetaDataKeyFormatWildcard, 0, 0, &item);
}
}
void QuickTimeMetaData::readMetaData()
{
QTMetaDataRef metaDataRef;
if (!m_movieRef)
return;
OSStatus err = QTCopyMovieMetaData(m_movieRef, &metaDataRef);
BACKEND_ASSERT2(err == noErr, "Could not read QuickTime meta data", NORMAL_ERROR)
QMultiMap<QString, QString> metaMap;
readFormattedData(metaDataRef, kQTMetaDataStorageFormatUserData, metaMap);
readFormattedData(metaDataRef, kQTMetaDataStorageFormatQuickTime, metaMap);
readFormattedData(metaDataRef, kQTMetaDataStorageFormatiTunes, metaMap);
m_metaData.insert(QLatin1String("ARTIST"), metaMap.value(QLatin1String("ART")));
m_metaData.insert(QLatin1String("ALBUM"), metaMap.value(QLatin1String("alb")));
m_metaData.insert(QLatin1String("TITLE"), metaMap.value(QLatin1String("nam")));
m_metaData.insert(QLatin1String("DATE"), metaMap.value(QLatin1String("day")));
m_metaData.insert(QLatin1String("GENRE"), metaMap.value(QLatin1String("gnre")));
m_metaData.insert(QLatin1String("TRACKNUMBER"), metaMap.value(QLatin1String("trk")));
m_metaData.insert(QLatin1String("DESCRIPTION"), metaMap.value(QLatin1String("des")));
}
QMultiMap<QString, QString> QuickTimeMetaData::metaData()
{
if (m_movieRef && m_movieChanged)
readMetaData();
return m_metaData;
}
}}
QT_END_NAMESPACE
|