m_view.clip_thumb->setHidden(true);
}
- KFileItem f(KFileItem::Unknown, KFileItem::Unknown, url, true);
- m_view.clip_filesize->setText(KIO::convertSize(f.size()));
+ if (t != SLIDESHOW && t != COLOR) {
+ KFileItem f(KFileItem::Unknown, KFileItem::Unknown, url, true);
+ m_view.clip_filesize->setText(KIO::convertSize(f.size()));
+ } else {
+ m_view.clip_filesize->setHidden(true);
+ m_view.label_size->setHidden(true);
+ }
m_view.clip_duration->setText(tc.getTimecode(m_clip->duration()));
if (t != IMAGE && t != COLOR && t != TEXT) m_view.clip_duration->setReadOnly(true);
else connect(m_view.clip_duration, SIGNAL(editingFinished()), this, SLOT(slotCheckMaxLength()));
props["ttl"] = QString::number(duration);
props["out"] = QString::number(duration * m_count);
}
- if (duration * m_count != m_old_props.value("out").toInt()) {
+ if (duration * m_count - 1 != m_old_props.value("out").toInt()) {
m_clipNeedsRefresh = true;
- props["out"] = QString::number(duration * m_count);
+ props["out"] = QString::number(duration * m_count - 1);
}
if (m_view.slide_fade->isChecked()) {
int luma_duration;
#include <KFileDialog>
-ClipTranscode::ClipTranscode(KUrl::List urls, const QString ¶ms, QWidget * parent) :
+ClipTranscode::ClipTranscode(KUrl::List urls, const QString ¶ms, const QString &description, QWidget * parent) :
QDialog(parent), m_urls(urls)
{
setFont(KGlobalSettings::toolBarFont());
label_profile->setHidden(true);
profile_list->setHidden(true);
ffmpeg_params->setPlainText(params.simplified());
+ if (!description.isEmpty()) {
+ transcode_info->setText(description);
+ } else transcode_info->setHidden(true);
} else {
// load Profiles
KSharedConfigPtr config = KSharedConfig::openConfig("kdenlivetranscodingrc");
// read the entries
QMap< QString, QString > profiles = transConfig.entryMap();
QMapIterator<QString, QString> i(profiles);
- connect(profile_list, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdateParams(int)));
while (i.hasNext()) {
i.next();
- profile_list->addItem(i.key(), i.value());
+ QStringList data = i.value().split(";", QString::SkipEmptyParts);
+ profile_list->addItem(i.key(), data.at(0));
+ profile_list->setItemData(profile_list->count() - 1, data.at(1), Qt::UserRole + 1);
}
+ connect(profile_list, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdateParams(int)));
+ slotUpdateParams(0);
}
connect(button_start, SIGNAL(clicked()), this, SLOT(slotStartTransCode()));
if (ix != -1) {
QString params = profile_list->itemData(ix).toString();
ffmpeg_params->setPlainText(params.simplified());
+ QString desc = profile_list->itemData(ix, Qt::UserRole + 1).toString();
+ if (!desc.isEmpty()) {
+ transcode_info->setText(desc);
+ transcode_info->setHidden(false);
+ } else transcode_info->setHidden(true);
}
if (urls_list->count() == 0) {
QString newFile = ffmpeg_params->toPlainText().simplified().section(' ', -1).replace("%1", fileName);
Q_OBJECT
public:
- ClipTranscode(KUrl::List urls, const QString ¶ms, QWidget * parent = 0);
+ ClipTranscode(KUrl::List urls, const QString ¶ms, const QString &description, QWidget * parent = 0);
~ClipTranscode();
#include <QCryptographicHash>
+#include <cstdio>
+
DocClipBase::DocClipBase(ClipManager *clipManager, QDomElement xml, const QString &id) :
QObject(),
m_audioFrameCache(),
return m_cutZones;
}
+bool DocClipBase::hasVideoCodec(const QString &codec) const
+{
+ Mlt::Producer *prod = NULL;
+ if (m_baseTrackProducers.count() == 0) return false;
+ for (int i = 0; i < m_baseTrackProducers.count(); i++) {
+ if (m_baseTrackProducers.at(i) != NULL) {
+ prod = m_baseTrackProducers.at(i);
+ break;
+ }
+ }
+
+ if (!prod) return false;
+ int default_video = prod->get_int("video_index");
+ char property[200];
+ snprintf(property, sizeof(property), "meta.media.%d.codec.name", default_video);
+ return prod->get(property) == codec;
+}
+
+bool DocClipBase::hasAudioCodec(const QString &codec) const
+{
+ Mlt::Producer *prod = NULL;
+ if (m_baseTrackProducers.count() == 0) return false;
+ for (int i = 0; i < m_baseTrackProducers.count(); i++) {
+ if (m_baseTrackProducers.at(i) != NULL) {
+ prod = m_baseTrackProducers.at(i);
+ break;
+ }
+ }
+ if (!prod) return false;
+ int default_video = prod->get_int("audio_index");
+ char property[200];
+ snprintf(property, sizeof(property), "meta.media.%d.codec.name", default_video);
+ return prod->get(property) == codec;
+}
+
QList <CutZoneInfo> cutZones() const;
void updateCutZone(int oldin, int oldout, int in, int out, QString desc = QString());
+ bool hasVideoCodec(const QString &codec) const;
+ bool hasAudioCodec(const QString &codec) const;
+
private: // Private attributes
/** The number of times this clip is used in the project - the number of references to this clip
Comment[uk]=Розпочато обробку проекту
Action=Popup
+[Event/ErrorMessage]
+Name=Error
+Comment=An error occured in Kdenlive
+Action=Sound
+Sound=KDE-Sys-Warning.ogg
[Transcoding]
-DNxHD 1920x1080 50i/25p 185 Mb/s=-s 1920x1080 -r pal -b 185000k -threads 2 -vcodec dnxhd -acodec copy %1.mov
-DNxHD 1920x1080 50i/25p 120 Mb/s=-s 1920x1080 -r pal -b 120000k -threads 2 -vcodec dnxhd -acodec copy %1.mov
-DNxHD 1920x1080 60i/30p 220 Mb/s=-s 1920x1080 -r ntsc -b 220000k -threads 2 -vcodec dnxhd -acodec copy %1.mov
-DNxHD 1920x1080 60i/30p 145 Mb/s=-s 1920x1080 -r ntsc -b 145000k -threads 2 -vcodec dnxhd -acodec copy %1.mov
-Fix MPEG-1=-sameq -acodec copy -vcodec mpeg1video %1.mpg
-Fix Ogg Theora=-sameq -vcodec libtheora -acodec copy %1.ogv
-Remux MPEG-2 PS/VOB=-vcodec copy -acodec copy %1.mpg
-Lossless Matroska=-sn -vcodec huffyuv -acodec flac %1.mkv
+DNxHD 1920x1080 50i/25p 185 Mb/s=-s 1920x1080 -r pal -b 185000k -threads 2 -vcodec dnxhd -acodec copy %1.mov;High quality encoding
+DNxHD 1920x1080 50i/25p 120 Mb/s=-s 1920x1080 -r pal -b 120000k -threads 2 -vcodec dnxhd -acodec copy %1.mov;High quality encoding
+DNxHD 1920x1080 60i/30p 220 Mb/s=-s 1920x1080 -r ntsc -b 220000k -threads 2 -vcodec dnxhd -acodec copy %1.mov;High quality encoding
+DNxHD 1920x1080 60i/30p 145 Mb/s=-s 1920x1080 -r ntsc -b 145000k -threads 2 -vcodec dnxhd -acodec copy %1.mov;High quality encoding
+Fix MPEG-1=-sameq -acodec copy -vcodec mpeg1video %1.mpg;Fix unplayable MPEG-1 files;vcodec=mpeg1video
+Fix Ogg Theora=-sameq -vcodec libtheora -acodec copy %1.ogv;Fix unplayable OGG Theora files;vcodec=theora
+Remux MPEG-2 PS/VOB=-vcodec copy -acodec copy %1.mpg;Fix audio sync in MPEG-2 vob files;vcodec=mpeg2video
+Lossless Matroska=-sn -vcodec huffyuv -acodec flac %1.mkv;High quality lossless encoding
if (description.isEmpty()) description = clip->getProperty("description");
else newprops.insert("templatetext", description);
//newprops.insert("xmldata", m_projectList->generateTemplateXml(newtemplate, description).toString());
-
- EditClipCommand *command = new EditClipCommand(m_projectList, clip->getId(), clip->properties(), newprops, true);
- m_activeDocument->commandStack()->push(command);
+ if (!newprops.isEmpty()) {
+ EditClipCommand *command = new EditClipCommand(m_projectList, clip->getId(), clip->properties(), newprops, true);
+ m_activeDocument->commandStack()->push(command);
+ }
}
+ delete dia;
return;
}
QString path = clip->getProperty("resource");
ClipProperties dia(clip, m_activeDocument->timecode(), m_activeDocument->fps(), this);
connect(&dia, SIGNAL(addMarker(const QString &, GenTime, QString)), m_activeTimeline->projectView(), SLOT(slotAddClipMarker(const QString &, GenTime, QString)));
if (dia.exec() == QDialog::Accepted) {
- EditClipCommand *command = new EditClipCommand(m_projectList, clip->getId(), clip->properties(), dia.properties(), true);
+ QMap <QString, QString> newprops = dia.properties();
+ if (newprops.isEmpty()) return;
+ EditClipCommand *command = new EditClipCommand(m_projectList, clip->getId(), clip->properties(), newprops, true);
m_activeDocument->commandStack()->push(command);
if (dia.needsTimelineRefresh()) {
QMapIterator<QString, QString> i(profiles);
while (i.hasNext()) {
i.next();
+ QStringList data = i.value().split(";", QString::SkipEmptyParts);
QAction *a = transMenu->addAction(i.key());
- a->setData(i.value());
+ a->setData(data);
+ if (data.count() > 1) {
+ a->setToolTip(data.at(1));
+ }
connect(a, SIGNAL(triggered()), this, SLOT(slotTranscode()));
}
}
void MainWindow::slotTranscode(KUrl::List urls)
{
QString params;
+ QString desc;
+ QString condition;
if (urls.isEmpty()) {
- urls.append(m_projectList->currentClipUrl());
QAction *action = qobject_cast<QAction *>(sender());
- params = action->data().toString();
+ QStringList data = action->data().toStringList();
+ params = data.at(0);
+ if (data.count() > 1) desc = data.at(1);
+ if (data.count() > 2) condition = data.at(2);
+ urls << m_projectList->getConditionalUrls(condition);
+ urls.removeAll(KUrl());
}
- if (urls.isEmpty()) return;
- ClipTranscode *d = new ClipTranscode(urls, params);
+ if (urls.isEmpty()) {
+ m_messageLabel->setMessage(i18n("No clip to transcode"), ErrorMessage);
+ return;
+ }
+ ClipTranscode *d = new ClipTranscode(urls, params, desc);
connect(d, SIGNAL(addClip(KUrl)), this, SLOT(slotAddProjectClip(KUrl)));
d->show();
//QProcess::startDetached("ffmpeg", parameters);
return item->clipUrl().path();
}
+KUrl::List ProjectList::getConditionalUrls(const QString &condition) const
+{
+ KUrl::List result;
+ ProjectItem *item;
+ QList<QTreeWidgetItem *> list = m_listView->selectedItems();
+ for (int i = 0; i < list.count(); i++) {
+ if (list.at(i)->type() == PROJECTFOLDERTYPE) continue;
+ if (list.at(i)->type() == PROJECTSUBCLIPTYPE) {
+ // subitem
+ item = static_cast <ProjectItem*>(list.at(i)->parent());
+ } else item = static_cast <ProjectItem*>(list.at(i));
+ if (item == NULL) continue;
+ if (item->type() == COLOR || item->type() == SLIDESHOW || item->type() == TEXT) continue;
+ DocClipBase *clip = item->referencedClip();
+ if (!condition.isEmpty()) {
+ if (condition.startsWith("vcodec") && !clip->hasVideoCodec(condition.section("=", 1, 1))) continue;
+ else if (condition.startsWith("acodec") && !clip->hasAudioCodec(condition.section("=", 1, 1))) continue;
+ }
+ result.append(item->clipUrl());
+ }
+ return result;
+}
+
void ProjectList::regenerateTemplate(const QString &id)
{
ProjectItem *clip = getItemById(id);
void setupMenu(QMenu *addMenu, QAction *defaultAction);
void setupGeneratorMenu(QMenu *addMenu, QMenu *transcodeMenu);
QString currentClipUrl() const;
+ KUrl::List getConditionalUrls(const QString &condition) const;
void reloadClipThumbnails();
QDomDocument generateTemplateXml(QString data, const QString &replaceString);
void cleanup();
#include <kiconloader.h>
#include <kicon.h>
#include <klocale.h>
+#include <KNotification>
#include <QFontMetrics>
#include <QPainter>
MessageType type)
{
if ((text == m_text) && (type == m_type)) {
+ if (type == ErrorMessage) KNotification::event("ErrorMessage", m_text);
return;
}
m_timer.start(100);
m_state = Illuminate;
m_closeButton->hide();
+ KNotification::event("ErrorMessage", m_text);
break;
case MltError:
<item row="1" column="1" colspan="2">
<widget class="KUrlRequester" name="dest_url"/>
</item>
- <item row="4" column="0" colspan="3">
+ <item row="5" column="0" colspan="3">
<widget class="QLabel" name="label_3">
<property name="text">
<string>FFmpeg parameters</string>
</property>
</widget>
</item>
- <item row="5" column="0" colspan="3">
+ <item row="6" column="0" colspan="3">
<widget class="QTextEdit" name="ffmpeg_params">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Maximum">
</property>
</widget>
</item>
- <item row="6" column="0">
+ <item row="7" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Job status</string>
</property>
</widget>
</item>
- <item row="7" column="0" colspan="3">
+ <item row="8" column="0" colspan="3">
<widget class="QTextEdit" name="log_text">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
</property>
</widget>
</item>
- <item row="10" column="2">
+ <item row="11" column="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
- <item row="10" column="0">
+ <item row="11" column="0">
<widget class="QPushButton" name="button_start">
<property name="text">
<string>Start</string>
</property>
</widget>
</item>
- <item row="8" column="0" colspan="2">
+ <item row="9" column="0" colspan="2">
<widget class="QCheckBox" name="auto_add">
<property name="text">
<string>Add clip to project</string>
</property>
</widget>
</item>
- <item row="8" column="2">
+ <item row="9" column="2">
<widget class="QCheckBox" name="auto_close">
<property name="text">
<string>Close after transcode</string>
</property>
</widget>
</item>
- <item row="10" column="1">
+ <item row="11" column="1">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
+ <item row="4" column="0" colspan="3">
+ <widget class="QLabel" name="transcode_info">
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
<customwidgets>