0
|
1 |
/* This file is part of the KDE project.
|
|
2 |
|
|
3 |
Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
|
4 |
|
|
5 |
This library is free software: you can redistribute it and/or modify
|
|
6 |
it under the terms of the GNU Lesser General Public License as published by
|
|
7 |
the Free Software Foundation, either version 2.1 or 3 of the License.
|
|
8 |
|
|
9 |
This library is distributed in the hope that it will be useful,
|
|
10 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12 |
GNU Lesser General Public License for more details.
|
|
13 |
|
|
14 |
You should have received a copy of the GNU Lesser General Public License
|
|
15 |
along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
16 |
*/
|
|
17 |
|
|
18 |
#include <QtCore/QFileInfo>
|
|
19 |
#include "quicktimemetadata.h"
|
|
20 |
#include "quicktimevideoplayer.h"
|
|
21 |
|
|
22 |
QT_BEGIN_NAMESPACE
|
|
23 |
|
|
24 |
namespace Phonon
|
|
25 |
{
|
|
26 |
namespace QT7
|
|
27 |
{
|
|
28 |
|
|
29 |
QuickTimeMetaData::QuickTimeMetaData(QuickTimeVideoPlayer *videoPlayer)
|
|
30 |
{
|
|
31 |
m_videoPlayer = videoPlayer;
|
|
32 |
m_movieChanged = false;
|
|
33 |
}
|
|
34 |
|
|
35 |
void QuickTimeMetaData::update()
|
|
36 |
{
|
|
37 |
m_movieChanged = true;
|
|
38 |
m_metaData.clear();
|
|
39 |
}
|
|
40 |
|
|
41 |
#ifdef QUICKTIME_C_API_AVAILABLE
|
|
42 |
|
|
43 |
QString QuickTimeMetaData::stripCopyRightSymbol(const QString &key)
|
|
44 |
{
|
|
45 |
return key.right(key.length()-1);
|
|
46 |
}
|
|
47 |
|
|
48 |
QString QuickTimeMetaData::convertQuickTimeKeyToUserKey(const QString &key)
|
|
49 |
{
|
|
50 |
if (key == QLatin1String("com.apple.quicktime.displayname"))
|
|
51 |
return QLatin1String("nam");
|
|
52 |
else if (key == QLatin1String("com.apple.quicktime.album"))
|
|
53 |
return QLatin1String("alb");
|
|
54 |
else if (key == QLatin1String("com.apple.quicktime.artist"))
|
|
55 |
return QLatin1String("ART");
|
|
56 |
else
|
|
57 |
return QLatin1String("???");
|
|
58 |
}
|
|
59 |
|
|
60 |
OSStatus QuickTimeMetaData::readMetaValue(QTMetaDataRef metaDataRef, QTMetaDataItem item, QTPropertyClass propClass,
|
|
61 |
QTPropertyID id, QTPropertyValuePtr *value, ByteCount *size)
|
|
62 |
{
|
|
63 |
QTPropertyValueType type;
|
|
64 |
ByteCount propSize;
|
|
65 |
UInt32 propFlags;
|
|
66 |
OSStatus err = QTMetaDataGetItemPropertyInfo(metaDataRef, item, propClass, id, &type, &propSize, &propFlags);
|
|
67 |
BACKEND_ASSERT3(err == noErr, "Could not read meta data value size", NORMAL_ERROR, err)
|
|
68 |
|
|
69 |
*value = malloc(propSize);
|
|
70 |
|
|
71 |
err = QTMetaDataGetItemProperty(metaDataRef, item, propClass, id, propSize, *value, size);
|
|
72 |
BACKEND_ASSERT3(err == noErr, "Could not read meta data value", NORMAL_ERROR, err)
|
|
73 |
|
|
74 |
if (type == 'code' || type == 'itsk' || type == 'itlk') {
|
|
75 |
// convert from native endian to big endian
|
|
76 |
OSTypePtr pType = (OSTypePtr)*value;
|
|
77 |
*pType = EndianU32_NtoB(*pType);
|
|
78 |
}
|
|
79 |
|
|
80 |
return err;
|
|
81 |
}
|
|
82 |
|
|
83 |
UInt32 QuickTimeMetaData::getMetaType(QTMetaDataRef metaDataRef, QTMetaDataItem item)
|
|
84 |
{
|
|
85 |
QTPropertyValuePtr value = 0;
|
|
86 |
ByteCount ignore = 0;
|
|
87 |
OSStatus err = readMetaValue(
|
|
88 |
metaDataRef, item, kPropertyClass_MetaDataItem, kQTMetaDataItemPropertyID_DataType, &value, &ignore);
|
|
89 |
BACKEND_ASSERT3(err == noErr, "Could not read meta data type", NORMAL_ERROR, 0)
|
|
90 |
UInt32 type = *((UInt32 *) value);
|
|
91 |
if (value)
|
|
92 |
free(value);
|
|
93 |
return type;
|
|
94 |
}
|
|
95 |
|
|
96 |
QString QuickTimeMetaData::getMetaValue(QTMetaDataRef metaDataRef, QTMetaDataItem item, SInt32 id)
|
|
97 |
{
|
|
98 |
QTPropertyValuePtr value = 0;
|
|
99 |
ByteCount size = 0;
|
|
100 |
OSStatus err = readMetaValue(metaDataRef, item, kPropertyClass_MetaDataItem, id, &value, &size);
|
|
101 |
BACKEND_ASSERT3(err == noErr, "Could not read meta data item", NORMAL_ERROR, QString())
|
|
102 |
BACKEND_ASSERT3(value != 0, "Could not read meta data item", NORMAL_ERROR, QString())
|
|
103 |
|
|
104 |
QString string;
|
|
105 |
UInt32 dataType = getMetaType(metaDataRef, item);
|
|
106 |
switch (dataType){
|
|
107 |
case kQTMetaDataTypeUTF8:
|
|
108 |
case kQTMetaDataTypeMacEncodedText:
|
|
109 |
string = PhononCFString::toQString(CFStringCreateWithBytes(0, (UInt8*)value, size, kCFStringEncodingUTF8, false));
|
|
110 |
break;
|
|
111 |
case kQTMetaDataTypeUTF16BE:
|
|
112 |
string = PhononCFString::toQString(CFStringCreateWithBytes(0, (UInt8*)value, size, kCFStringEncodingUTF16BE, false));
|
|
113 |
break;
|
|
114 |
default:
|
|
115 |
break;
|
|
116 |
}
|
|
117 |
|
|
118 |
if (value)
|
|
119 |
free(value);
|
|
120 |
return string;
|
|
121 |
}
|
|
122 |
|
|
123 |
void QuickTimeMetaData::readFormattedData(QTMetaDataRef metaDataRef, OSType format, QMultiMap<QString, QString> &result)
|
|
124 |
{
|
|
125 |
QTMetaDataItem item = kQTMetaDataItemUninitialized;
|
|
126 |
OSStatus err = QTMetaDataGetNextItem(metaDataRef, format, item, kQTMetaDataKeyFormatWildcard, 0, 0, &item);
|
|
127 |
while (err == noErr){
|
|
128 |
QString key = getMetaValue(metaDataRef, item, kQTMetaDataItemPropertyID_Key);
|
|
129 |
if (format == kQTMetaDataStorageFormatQuickTime)
|
|
130 |
key = convertQuickTimeKeyToUserKey(key);
|
|
131 |
else
|
|
132 |
key = stripCopyRightSymbol(key);
|
|
133 |
|
|
134 |
if (!result.contains(key)){
|
|
135 |
QString val = getMetaValue(metaDataRef, item, kQTMetaDataItemPropertyID_Value);
|
|
136 |
result.insert(key, val);
|
|
137 |
}
|
|
138 |
err = QTMetaDataGetNextItem(metaDataRef, format, item, kQTMetaDataKeyFormatWildcard, 0, 0, &item);
|
|
139 |
}
|
|
140 |
}
|
|
141 |
|
|
142 |
#endif // QUICKTIME_C_API_AVAILABLE
|
|
143 |
|
|
144 |
void QuickTimeMetaData::guessMetaDataForCD()
|
|
145 |
{
|
|
146 |
QString album = QFileInfo(m_videoPlayer->movieCompactDiscPath()).fileName();
|
|
147 |
QString title = QFileInfo(m_videoPlayer->currentTrackPath()).fileName();
|
|
148 |
title = title.left(title.lastIndexOf('.'));
|
|
149 |
m_metaData.insert(QLatin1String("ALBUM"), album);
|
|
150 |
m_metaData.insert(QLatin1String("TITLE"), title);
|
|
151 |
m_metaData.insert(QLatin1String("TRACKNUMBER"), QString::number(m_videoPlayer->currentTrack()));
|
|
152 |
}
|
|
153 |
|
|
154 |
void QuickTimeMetaData::readMetaDataFromMovie()
|
|
155 |
{
|
|
156 |
QMultiMap<QString, QString> metaMap;
|
|
157 |
|
|
158 |
#ifdef QUICKTIME_C_API_AVAILABLE
|
|
159 |
QTMetaDataRef metaDataRef;
|
|
160 |
OSStatus err = QTCopyMovieMetaData([m_videoPlayer->qtMovie() quickTimeMovie], &metaDataRef);
|
|
161 |
BACKEND_ASSERT2(err == noErr, "Could not read QuickTime meta data", NORMAL_ERROR)
|
|
162 |
|
|
163 |
readFormattedData(metaDataRef, kQTMetaDataStorageFormatUserData, metaMap);
|
|
164 |
readFormattedData(metaDataRef, kQTMetaDataStorageFormatQuickTime, metaMap);
|
|
165 |
readFormattedData(metaDataRef, kQTMetaDataStorageFormatiTunes, metaMap);
|
|
166 |
#else
|
|
167 |
NSString *name = [m_videoPlayer->qtMovie() attributeForKey:@"QTMovieDisplayNameAttribute"];
|
|
168 |
metaMap.insert(QLatin1String("nam"), QString::fromUtf8([name UTF8String]));
|
|
169 |
#endif // QUICKTIME_C_API_AVAILABLE
|
|
170 |
|
|
171 |
m_metaData.insert(QLatin1String("ARTIST"), metaMap.value(QLatin1String("ART")));
|
|
172 |
m_metaData.insert(QLatin1String("ALBUM"), metaMap.value(QLatin1String("alb")));
|
|
173 |
m_metaData.insert(QLatin1String("TITLE"), metaMap.value(QLatin1String("nam")));
|
|
174 |
m_metaData.insert(QLatin1String("DATE"), metaMap.value(QLatin1String("day")));
|
|
175 |
m_metaData.insert(QLatin1String("GENRE"), metaMap.value(QLatin1String("gnre")));
|
|
176 |
m_metaData.insert(QLatin1String("TRACKNUMBER"), metaMap.value(QLatin1String("trk")));
|
|
177 |
m_metaData.insert(QLatin1String("DESCRIPTION"), metaMap.value(QLatin1String("des")));
|
|
178 |
}
|
|
179 |
|
|
180 |
void QuickTimeMetaData::readMetaData()
|
|
181 |
{
|
|
182 |
if (!m_videoPlayer)
|
|
183 |
return;
|
|
184 |
|
|
185 |
if (m_videoPlayer->mediaSource().type() == Phonon::MediaSource::Disc)
|
|
186 |
guessMetaDataForCD();
|
|
187 |
else
|
|
188 |
readMetaDataFromMovie();
|
|
189 |
}
|
|
190 |
|
|
191 |
QMultiMap<QString, QString> QuickTimeMetaData::metaData()
|
|
192 |
{
|
|
193 |
if (m_videoPlayer && m_videoPlayer->hasMovie() && m_movieChanged)
|
|
194 |
readMetaData();
|
|
195 |
return m_metaData;
|
|
196 |
}
|
|
197 |
|
|
198 |
}}
|
|
199 |
|
|
200 |
QT_END_NAMESPACE
|