-install(FILES banner.png timeline_nothumbs.png timeline_athumbs.png timeline_vthumbs.png timeline_avthumbs.png metadata.properties blacklisted_effects.txt blacklisted_transitions.txt encodingprofiles.rc DESTINATION ${DATA_INSTALL_DIR}/kdenlive )
+install(FILES banner.png timeline_nothumbs.png timeline_athumbs.png timeline_vthumbs.png timeline_avthumbs.png metadata.properties blacklisted_effects.txt blacklisted_transitions.txt encodingprofiles.rc meta_ffmpeg.png meta_libav.png meta_magiclantern.png DESTINATION ${DATA_INSTALL_DIR}/kdenlive )
install( FILES kdenliveeffectscategory.rc DESTINATION ${CONFIG_INSTALL_DIR} )
install (FILES kdenlive.xpm DESTINATION share/pixmaps)
install (FILES kdenlive.menu DESTINATION share/menu RENAME kdenlive)
connect(m_view.clip_full_luma, SIGNAL(toggled(bool)), this, SLOT(slotModified()));
// Check for Metadata
- QMap<QString, QString> meta = m_clip->metadata();
- QMap<QString, QString>::const_iterator i = meta.constBegin();
+ QMap<QString, QStringList> meta = m_clip->metadata();
+ QMap<QString, QStringList>::const_iterator i = meta.constBegin();
while (i != meta.constEnd()) {
- QTreeWidgetItem *metaitem = new QTreeWidgetItem(m_view.metadata_list);
+ QStringList values = i.value();
+ QString parentName;
+ QString iconName;
+ if (values.count() > 1 && !values.at(1).isEmpty()) parentName = values.at(1);
+ else {
+ if (KdenliveSettings::ffmpegpath().endsWith("avconv")) {
+ parentName = i18n("Libav");
+ iconName = "meta_libav.png";
+ }
+ else {
+ parentName = i18n("FFmpeg");
+ iconName = "meta_ffmpeg.png";
+ }
+ }
+ QTreeWidgetItem *parent = NULL;
+ QList <QTreeWidgetItem *> matches = m_view.metadata_list->findItems(parentName, Qt::MatchExactly);
+ if (!matches.isEmpty()) parent = matches.at(0);
+ else {
+ if (parentName == "Magic Lantern") iconName = "meta_magiclantern.png";
+ parent = new QTreeWidgetItem(m_view.metadata_list, QStringList() << parentName);
+ if (!iconName.isEmpty()) {
+ KIcon icon(KStandardDirs::locate("appdata", iconName));
+ parent->setIcon(0, icon);
+ }
+ }
+ QTreeWidgetItem *metaitem = NULL;
+ if (parent) {
+ metaitem = new QTreeWidgetItem(parent);
+ parent->setExpanded(true);
+ }
+ else metaitem = new QTreeWidgetItem(m_view.metadata_list);
metaitem->setText(0, i.key()); //i18n(i.key().section('.', 2, 3).toUtf8().data()));
- metaitem->setText(1, i.value());
+ metaitem->setText(1, values.at(0));
++i;
}
for (int i = 0; i < attributes.count(); i++) {
QString name = attributes.item(i).nodeName();
if (name.startsWith("meta.attr.")) {
- m_metadata.insert(name.section('.', 2), attributes.item(i).nodeValue());
+ m_metadata.insert(name.section('.', 2), QStringList() << attributes.item(i).nodeValue());
} else m_properties.insert(name, attributes.item(i).nodeValue());
}
QDomNodeList metas = xml.elementsByTagName("metaproperty");
for (int i = 0; i < metas.count(); i++) {
QDomElement e = metas.item(i).toElement();
if (!e.isNull()) {
- m_metadata.insert(e.attribute("name").section('.', 2), e.firstChild().nodeValue());
+ m_metadata.insert(e.attribute("name").section('.', 2), QStringList() << e.firstChild().nodeValue() << e.attribute("tool"));
}
}
if (!i.value().isEmpty()) clip.setAttribute(i.key(), i.value());
}
- QMapIterator<QString, QString> j(m_metadata);
+ QMapIterator<QString, QStringList> j(m_metadata);
// Metadata name can have special chars so we cannot pass it as simple attribute
while (j.hasNext()) {
j.next();
if (!j.value().isEmpty()) {
QDomElement property = doc.createElement("metaproperty");
property.setAttribute("name", "meta.attr." + j.key());
- QDomText value = doc.createTextNode(j.value());
+ QStringList values = j.value();
+ QDomText value = doc.createTextNode(values.at(0));
+ if (values.count() > 1) property.setAttribute("tool", values.at(1));
property.appendChild(value);
clip.appendChild(property);
}
if (refreshProducer) slotRefreshProducer();
}
-void DocClipBase::setMetadata(QMap <QString, QString> properties)
+void DocClipBase::setMetadata(QMap <QString, QString> properties, QString tool)
{
QMapIterator<QString, QString> i(properties);
while (i.hasNext()) {
if (i.value().isEmpty() && m_metadata.contains(i.key())) {
m_metadata.remove(i.key());
} else {
- m_metadata.insert(i.key(), i.value());
+ m_metadata.insert(i.key(), QStringList() << i.value() << tool);
}
}
}
-QMap <QString, QString> DocClipBase::metadata() const
+QMap <QString, QStringList> DocClipBase::metadata() const
{
return m_metadata;
}
/** Cache for every audio Frame with 10 Bytes */
/** format is frame -> channel ->bytes */
QMap<int, QMap<int, QByteArray> > audioFrameCache;
+ /** Returns all current properties for this clip */
+ QMap <QString, QString> properties() const;
+ /** Return the current values for a set of properties */
+ QMap <QString, QString> currentProperties(QMap <QString, QString> props);
+ QMap <QString, QStringList> metadata() const;
private: // Private attributes
/** The number of times this clip is used in the project - the number of references to this clip
/** Holds clip infos like fps, size,... */
QMap <QString, QString> m_properties;
/** Holds clip metadata like author, copyright,... */
- QMap <QString, QString> m_metadata;
+ QMap <QString, QStringList> m_metadata;
/** Holds clip analysis data that can be used later to create markers or keyframes */
QMap <QString, QString> m_analysisdata;
void setClipThumbFrame(const uint &ix);
uint getClipThumbFrame() const;
void setProperties(QMap <QString, QString> properties);
- void setMetadata(QMap <QString, QString> properties);
- /** Returns all current properties for this clip */
- QMap <QString, QString> properties() const;
- /** Return the current values for a set of properties */
- QMap <QString, QString> currentProperties(QMap <QString, QString> props);
- QMap <QString, QString> metadata() const;
+ void setMetadata(QMap <QString, QString> properties, QString tool = QString());
void slotExtractImage(QList <int> frames);
signals:
<default>false</default>
</entry>
+ <entry name="use_magicLantern" type="Bool">
+ <label>Get h264 metadata using exiftool.</label>
+ <default>false</default>
+ </entry>
+
<entry name="title_duration" type="String">
<label>Default title clip duration.</label>
<default>00:00:05:00</default>
void ProjectList::extractMetadata(DocClipBase *clip)
{
QMap <QString, QString> props = clip->properties();
- if (props.contains("exiftool")) {
- // metadata was already extracted
- return;
+ if (KdenliveSettings::use_exiftool() && !props.contains("exiftool")) {
+ QString codecid = props.value("videocodecid").simplified();
+ if (codecid == "h264") {
+ QProcess p;
+ QStringList args;
+ args << "-g" << "-args" << clip->fileURL().encodedPathAndQuery();
+ p.start("exiftool", args);
+ p.waitForFinished();
+ QString res = p.readAllStandardOutput();
+ QStringList list = res.split("\n");
+ QMap <QString, QString> meta;
+ foreach(QString tagline, list) {
+ if (!tagline.startsWith("-H264")) continue;
+ QString tag = tagline.section(':', 1);
+ if (tag.startsWith("ImageWidth") || tag.startsWith("ImageHeight")) continue;
+ meta.insert(tag.section('=', 0, 0), tag.section('=', 1));
+ }
+ clip->setProperty("exiftool", "1");
+ if (!meta.isEmpty()) {
+ clip->setMetadata(meta, "ExifTool");
+ //checkCamcorderFilters(clip, meta);
+ }
+ }
}
- QString codecid = props.value("videocodecid").simplified();
- if (codecid == "h264") {
- QProcess p;
- QStringList args;
- args << "-g" << "-args" << clip->fileURL().encodedPathAndQuery();
- p.start("exiftool", args);
- p.waitForFinished();
- QString res = p.readAllStandardOutput();
- QStringList list = res.split("\n");
+ if (KdenliveSettings::use_magicLantern() && !props.contains("magiclantern")) {
QMap <QString, QString> meta;
- foreach(QString tagline, list) {
- if (!tagline.startsWith("-H264")) continue;
- QString tag = tagline.section(':', 1);
- if (tag.startsWith("ImageWidth") || tag.startsWith("ImageHeight")) continue;
- meta.insert(tag.section('=', 0, 0), tag.section('=', 1));
+ QString url = clip->fileURL().path();
+ url = url.section('.', 0, -2) + ".LOG";
+ if (QFile::exists(url)) {
+ QFile file(url);
+ if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ while (!file.atEnd()) {
+ QString line = file.readLine().simplified();
+ if (line.startsWith('#') || line.isEmpty() || !line.contains(':')) continue;
+ if (line.startsWith("CSV data")) break;
+ meta.insert(line.section(':', 0, 0).simplified(), line.section(':', 1).simplified());
+ }
+ }
}
- clip->setProperty("exiftool", "1");
- if (!meta.isEmpty()) {
- clip->setMetadata(meta);
- //checkCamcorderFilters(clip, meta);
+ url = url.section('.', 0, -2) + ".THM";
+ if (QFile::exists(url) && KdenliveSettings::use_exiftool()) {
+ // Read the exif metadata embeded in the THM file
+ QProcess p;
+ QStringList args;
+ args << "-g" << "-args" << url;
+ p.start("exiftool", args);
+ p.waitForFinished();
+ QString res = p.readAllStandardOutput();
+ QStringList list = res.split("\n");
+ foreach(QString tagline, list) {
+ if (tagline.startsWith("-File") || tagline.startsWith("-ExifTool")) continue;
+ QString tag = tagline.section(':', 1).simplified();
+ if (tag.startsWith("ImageWidth") || tag.startsWith("ImageHeight")) continue;
+ if (!tag.section('=', 0, 0).isEmpty() && !tag.section('=', 1).simplified().isEmpty())
+ meta.insert(tag.section('=', 0, 0), tag.section('=', 1).simplified());
+ }
}
+
+ if (!meta.isEmpty())
+ clip->setMetadata(meta, "Magic Lantern");
+ clip->setProperty("magiclantern", "1");
}
}
}
item->setProperties(properties, metadata);
clip->setProducer(producer, replace);
- if (KdenliveSettings::use_exiftool()) extractMetadata(clip);
+ extractMetadata(clip);
m_render->processingDone(clipId);
// Proxy stuff
void RenderWidget::errorMessage(const QString &message)
{
if (!message.isEmpty()) {
- kDebug()<<"// ERROR MESS: "<<message;
#if KDE_IS_VERSION(4,7,0)
m_infoMessage->setMessageType(KMessageWidget::Warning);
m_infoMessage->setText(message);
<x>0</x>
<y>0</y>
<width>323</width>
- <height>556</height>
+ <height>557</height>
</rect>
</property>
<property name="windowTitle">
<bool>false</bool>
</property>
<property name="itemsExpandable">
- <bool>false</bool>
+ <bool>true</bool>
</property>
<property name="sortingEnabled">
<bool>false</bool>
<property name="topMargin">
<number>0</number>
</property>
- <item row="11" column="0" colspan="3">
+ <item row="4" column="0" colspan="2">
+ <widget class="QCheckBox" name="kcfg_usekuiserver">
+ <property name="text">
+ <string>Use KDE job tracking for render jobs</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QCheckBox" name="kcfg_checkfirstprojectclip">
+ <property name="text">
+ <string>Check if first added clip matches project profile</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="3">
+ <widget class="QCheckBox" name="kcfg_crashrecovery">
+ <property name="text">
+ <string>Crash recovery (automatic backup)</string>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="0">
+ <widget class="QCheckBox" name="kcfg_automultistreams">
+ <property name="text">
+ <string>Automatically import all streams in multi stream clips</string>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0">
+ <widget class="QCheckBox" name="kcfg_disable_effect_parameters">
+ <property name="text">
+ <string>Disable parameters when the effect is disabled</string>
+ </property>
+ </widget>
+ </item>
+ <item row="9" column="0">
+ <widget class="QCheckBox" name="kcfg_bypasscodeccheck">
+ <property name="text">
+ <string>Bypass codec verification</string>
+ </property>
+ </widget>
+ </item>
+ <item row="13" column="0">
+ <widget class="QCheckBox" name="kcfg_autoimagesequence">
+ <property name="text">
+ <string>Automatically import image sequences</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0">
+ <widget class="QCheckBox" name="kcfg_projectloading_avformatnovalidate">
+ <property name="text">
+ <string>Do not validate the video files when loading a project (faster)</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QCheckBox" name="kcfg_on_monitor_effects">
+ <property name="text">
+ <string>Use on-monitor effects</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" colspan="3">
+ <widget class="QCheckBox" name="kcfg_activatetabs">
+ <property name="text">
+ <string>Open projects in new tabs</string>
+ </property>
+ </widget>
+ </item>
+ <item row="10" column="0">
+ <widget class="QCheckBox" name="kcfg_use_exiftool">
+ <property name="text">
+ <string>Get clip metadata with exiftool</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" colspan="3">
+ <widget class="QCheckBox" name="kcfg_openlastproject">
+ <property name="text">
+ <string>Open last project on startup</string>
+ </property>
+ </widget>
+ </item>
+ <item row="12" column="0" colspan="3">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Default Durations</string>
</layout>
</widget>
</item>
- <item row="9" column="0">
- <widget class="QCheckBox" name="kcfg_bypasscodeccheck">
- <property name="text">
- <string>Bypass codec verification</string>
- </property>
- </widget>
- </item>
- <item row="5" column="0">
- <widget class="QCheckBox" name="kcfg_on_monitor_effects">
- <property name="text">
- <string>Use on-monitor effects</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0" colspan="3">
- <widget class="QCheckBox" name="kcfg_crashrecovery">
- <property name="text">
- <string>Crash recovery (automatic backup)</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0" colspan="2">
- <widget class="QCheckBox" name="kcfg_checkfirstprojectclip">
- <property name="text">
- <string>Check if first added clip matches project profile</string>
- </property>
- </widget>
- </item>
- <item row="0" column="0" colspan="3">
- <widget class="QCheckBox" name="kcfg_openlastproject">
- <property name="text">
- <string>Open last project on startup</string>
- </property>
- </widget>
- </item>
- <item row="12" column="0">
- <widget class="QCheckBox" name="kcfg_autoimagesequence">
- <property name="text">
- <string>Automatically import image sequences</string>
- </property>
- </widget>
- </item>
- <item row="13" column="0">
+ <item row="14" column="0">
<widget class="QCheckBox" name="kcfg_autoimagetransparency">
<property name="text">
<string>Transparent background for imported images</string>
</property>
</widget>
</item>
- <item row="14" column="0" colspan="3">
+ <item row="15" column="0" colspan="3">
<spacer>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</spacer>
</item>
- <item row="4" column="0" colspan="2">
- <widget class="QCheckBox" name="kcfg_usekuiserver">
+ <item row="11" column="0">
+ <widget class="QCheckBox" name="kcfg_use_magicLantern">
<property name="text">
- <string>Use KDE job tracking for render jobs</string>
- </property>
- </widget>
- </item>
- <item row="8" column="0">
- <widget class="QCheckBox" name="kcfg_automultistreams">
- <property name="text">
- <string>Automatically import all streams in multi stream clips</string>
- </property>
- </widget>
- </item>
- <item row="7" column="0">
- <widget class="QCheckBox" name="kcfg_disable_effect_parameters">
- <property name="text">
- <string>Disable parameters when the effect is disabled</string>
- </property>
- </widget>
- </item>
- <item row="6" column="0">
- <widget class="QCheckBox" name="kcfg_projectloading_avformatnovalidate">
- <property name="text">
- <string>Do not validate the video files when loading a project (faster)</string>
- </property>
- </widget>
- </item>
- <item row="3" column="0" colspan="3">
- <widget class="QCheckBox" name="kcfg_activatetabs">
- <property name="text">
- <string>Open projects in new tabs</string>
- </property>
- </widget>
- </item>
- <item row="10" column="0">
- <widget class="QCheckBox" name="kcfg_use_exiftool">
- <property name="text">
- <string>Get clip metadata with exiftool</string>
+ <string>Get clip metadata created by Magic Lantern</string>
</property>
</widget>
</item>