Commit 75feb1d7 authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

Scene split: allow selecting markers category and create subclips

parent 383b454c
Pipeline #62860 passed with stage
in 8 minutes and 14 seconds
......@@ -41,10 +41,13 @@
#include <klocalizedstring.h>
#include <project/projectmanager.h>
SceneSplitTask::SceneSplitTask(const ObjectId &owner, double threshold, QObject* object)
SceneSplitTask::SceneSplitTask(const ObjectId &owner, double threshold, int markersCategory, bool addSubclips, int minDuration, QObject* object)
: AbstractTask(owner, AbstractTask::ANALYSECLIPJOB, object)
, m_jobDuration(0)
, m_threshold(threshold)
, m_markersType(markersCategory)
, m_subClips(addSubclips)
, m_minInterval(minDuration)
, m_jobProcess(nullptr)
{
}
......@@ -55,6 +58,8 @@ void SceneSplitTask::start(QObject* object, bool force)
Ui::SceneCutDialog_UI view;
view.setupUi(d);
view.threshold->setValue(KdenliveSettings::scenesplitthreshold());
view.add_markers->setChecked(KdenliveSettings::scenesplitmarkers());
view.cut_scenes->setChecked(KdenliveSettings::scenesplitsubclips());
// Set up categories
static std::array<QColor, 9> markerTypes = pCore->projectManager()->getGuideModel()->markerTypes;
QPixmap pixmap(32,32);
......@@ -68,7 +73,14 @@ void SceneSplitTask::start(QObject* object, bool force)
return;
}
int threshold = view.threshold->value();
bool addMarkers = view.add_markers->isChecked();
bool addSubclips = view.cut_scenes->isChecked();
int markersCategory = addMarkers ? view.marker_type->currentIndex() : -1;
int minDuration = view.minDuration->value();
KdenliveSettings::setScenesplitthreshold(threshold);
KdenliveSettings::setScenesplitmarkers(view.add_markers->isChecked());
KdenliveSettings::setScenesplitsubclips(view.cut_scenes->isChecked());
std::vector<QString> binIds = pCore->bin()->selectedClipsIds(true);
for (auto & id : binIds) {
SceneSplitTask* task = nullptr;
......@@ -82,12 +94,12 @@ void SceneSplitTask::start(QObject* object, bool force)
}
owner = ObjectId(ObjectType::BinClip, binData.first().toInt());
auto binClip = pCore->projectItemModel()->getClipByBinID(binData.first());
task = new SceneSplitTask(owner, threshold / 100., binClip.get());
task = new SceneSplitTask(owner, threshold / 100., markersCategory, addSubclips, minDuration, binClip.get());
} else {
owner = ObjectId(ObjectType::BinClip, id.toInt());
auto binClip = pCore->projectItemModel()->getClipByBinID(id);
task = new SceneSplitTask(owner, threshold / 100., binClip.get());
task = new SceneSplitTask(owner, threshold / 100., markersCategory, addSubclips, minDuration, binClip.get());
}
// See if there is already a task for this MLT service and resource.
if (task && pCore->taskManager.hasPendingJob(owner, AbstractTask::ANALYSECLIPJOB)) {
......@@ -128,6 +140,7 @@ void SceneSplitTask::run()
return;
}
m_jobDuration = int(binClip->duration().seconds());
int producerDuration = binClip->frameDuration();
//QStringList parameters = {QStringLiteral("-loglevel"),QStringLiteral("info"),QStringLiteral("-i"),source,QStringLiteral("-filter:v"),QString("scdet"),QStringLiteral("-f"),QStringLiteral("null"),QStringLiteral("-")};
QStringList parameters = {QStringLiteral("-y"),QStringLiteral("-loglevel"),QStringLiteral("info"),QStringLiteral("-i"),source,QStringLiteral("-filter:v"),QString("select='gt(scene,0.1)',showinfo"),QStringLiteral("-vsync"),QStringLiteral("vfr"),QStringLiteral("-r"),QStringLiteral("50")};
#ifdef Q_OS_WIN
......@@ -162,56 +175,59 @@ void SceneSplitTask::run()
if (result && !m_isCanceled) {
qDebug()<<"========================\n\nGOR RESULTS: "<<m_results<<"\n\n=========";
auto binClip = pCore->projectItemModel()->getClipByBinID(QString::number(m_owner.second));
//if (m_markersType >= 0) {
// Build json data for markers
QJsonArray list;
int ix = 1;
int lastCut = 0;
for (auto &marker : m_results) {
int pos = GenTime(marker).frames(pCore->getCurrentFps());
/*
if (m_minInterval > 0 && ix > 1 && pos - lastCut < m_minInterval) {
continue;
}*/
lastCut = pos;
QJsonObject currentMarker;
currentMarker.insert(QLatin1String("pos"), QJsonValue(pos));
currentMarker.insert(QLatin1String("comment"), QJsonValue(i18n("Scene %1", ix)));
currentMarker.insert(QLatin1String("type"), QJsonValue(0)); //m_markersType));
list.push_back(currentMarker);
ix++;
if (m_markersType >= 0) {
// Build json data for markers
QJsonArray list;
int ix = 1;
int lastCut = 0;
for (auto &marker : m_results) {
int pos = GenTime(marker).frames(pCore->getCurrentFps());
if (m_minInterval > 0 && ix > 1 && pos - lastCut < m_minInterval) {
continue;
}
lastCut = pos;
QJsonObject currentMarker;
currentMarker.insert(QLatin1String("pos"), QJsonValue(pos));
currentMarker.insert(QLatin1String("comment"), QJsonValue(i18n("Scene %1", ix)));
currentMarker.insert(QLatin1String("type"), QJsonValue(m_markersType));
list.push_back(currentMarker);
ix++;
}
QJsonDocument json(list);
QMetaObject::invokeMethod(m_object, "importJsonMarkers", Q_ARG(const QString&,QString(json.toJson())));
}
QJsonDocument json(list);
QMetaObject::invokeMethod(m_object, "importJsonMarkers", Q_ARG(const QString&,QString(json.toJson())));
//binClip->getMarkerModel()->importFromJson(QString(json.toJson()), true, undo, redo);
//}
/*if (QFileInfo(destUrl).size() == 0) {
QFile::remove(destUrl);
// File was not created
m_errorMessage.append(i18n("Failed to create file."));
} else {
QString id = QString::number(m_owner.second);
auto binClip = pCore->projectItemModel()->getClipByBinID(id);
if (m_replaceProducer && binClip) {
QMap <QString, QString> sourceProps;
QMap <QString, QString> newProps;
sourceProps.insert(QStringLiteral("resource"), binClip->url());
sourceProps.insert(QStringLiteral("kdenlive:clipname"), binClip->clipName());
newProps.insert(QStringLiteral("resource"), destUrl);
newProps.insert(QStringLiteral("kdenlive:clipname"), QFileInfo(destUrl).fileName());
pCore->bin()->slotEditClipCommand(id, sourceProps, newProps);
} else {
QString folder = QStringLiteral("-1");
if (binClip) {
auto containingFolder = std::static_pointer_cast<ProjectFolder>(binClip->parent());
if (containingFolder) {
folder = containingFolder->clipId();
}
if (m_subClips) {
// Create zones
int ix = 1;
int lastCut = 0;
QJsonArray list;
QJsonDocument json;
for (double &marker : m_results) {
int pos = GenTime(marker).frames(pCore->getCurrentFps());
if (pos <= lastCut + 1 || pos - lastCut < m_minInterval) {
continue;
}
QMetaObject::invokeMethod(pCore->window(), "addProjectClip", Qt::QueuedConnection, Q_ARG(const QString&,destUrl), Q_ARG(const QString&,folder));
//id = ClipCreator::createClipFromFile(destUrl, folderId, pCore->projectItemModel());
QJsonObject currentZone;
currentZone.insert(QLatin1String("name"), QJsonValue(i18n("Scene %1", ix)));
currentZone.insert(QLatin1String("in"), QJsonValue(lastCut));
currentZone.insert(QLatin1String("out"), QJsonValue(pos - 1));
list.push_back(currentZone);
lastCut = pos;
ix++;
}
if (lastCut < producerDuration) {
QJsonObject currentZone;
currentZone.insert(QLatin1String("name"), QJsonValue(i18n("Scene %1", ix)));
currentZone.insert(QLatin1String("in"), QJsonValue(lastCut));
currentZone.insert(QLatin1String("out"), QJsonValue(producerDuration));
list.push_back(currentZone);
}
}*/
json.setArray(list);
if (!json.isEmpty()) {
QString dataMap(json.toJson());
QMetaObject::invokeMethod(pCore->projectItemModel().get(), "loadSubClips", Q_ARG(const QString&,QString::number(m_owner.second)), Q_ARG(const QString&,dataMap));
}
}
} else {
// Proxy process crashed
m_errorMessage.append(QString::fromUtf8(m_jobProcess->readAll()));
......
......@@ -28,7 +28,7 @@ class QProcess;
class SceneSplitTask : public AbstractTask
{
public:
SceneSplitTask(const ObjectId &owner, double threshold, QObject* object);
SceneSplitTask(const ObjectId &owner, double threshold, int markersCategory, bool addSubclips, int minDuration, QObject* object);
static void start(QObject* object, bool force = false);
protected:
......@@ -41,6 +41,9 @@ private slots:
private:
int m_jobDuration;
double m_threshold;
int m_markersType;
bool m_subClips;
int m_minInterval;
std::unique_ptr<QProcess> m_jobProcess;
QString m_errorMessage;
QString m_logDetails;
......
......@@ -33,7 +33,15 @@
<group name="jobs">
<entry name="scenesplitthreshold" type="Int">
<label>Scene split detection threshold.</label>
<default>30</default>
<default>30</default>
</entry>
<entry name="scenesplitmarkers" type="Bool">
<label>Add markers on Scene split.</label>
<default>true</default>
</entry>
<entry name="scenesplitsubclips" type="Bool">
<label>Add subclips on Scene split.</label>
<default>false</default>
</entry>
</group>
<group name="misc">
......
......@@ -6,38 +6,31 @@
<rect>
<x>0</x>
<y>0</y>
<width>368</width>
<height>250</height>
<width>366</width>
<height>194</height>
</rect>
</property>
<property name="windowTitle">
<string>Scene Cut</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<item row="4" column="0" colspan="2">
<widget class="QLabel" name="label">
<property name="text">
<string>Change threshold</string>
</property>
</widget>
</item>
<item row="8" column="0" colspan="5">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
<string>Minimum scene length</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="5">
<widget class="QCheckBox" name="cut_scenes">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Cut scenes</string>
<string>Change threshold</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QSpinBox" name="threshold"/>
</item>
<item row="1" column="2" colspan="3">
<widget class="QComboBox" name="marker_type">
<property name="sizePolicy">
......@@ -48,20 +41,7 @@
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QSlider" name="horizontalSlider">
<property name="minimum">
<number>1</number>
</property>
<property name="value">
<number>30</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="7" column="0">
<item row="5" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
......@@ -74,38 +54,37 @@
</property>
</spacer>
</item>
<item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="add_markers">
<property name="text">
<string>Add clip markers</string>
<item row="6" column="0" colspan="5">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="checked">
<bool>true</bool>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="6" column="0" colspan="2">
<widget class="QLabel" name="label">
<item row="2" column="0" colspan="5">
<widget class="QCheckBox" name="cut_scenes">
<property name="text">
<string>Minimum scene length</string>
<string>Cut scenes</string>
</property>
</widget>
</item>
<item row="4" column="0" colspan="5">
<widget class="QCheckBox" name="zone_only">
<property name="text">
<string>Analyze only selected zone</string>
<item row="0" column="1" colspan="2">
<widget class="QSlider" name="horizontalSlider">
<property name="minimum">
<number>1</number>
</property>
</widget>
</item>
<item row="3" column="0" colspan="5">
<widget class="QCheckBox" name="store_data">
<property name="text">
<string>Save result in clip metadata</string>
<property name="value">
<number>30</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="6" column="2">
<item row="4" column="2">
<widget class="QSpinBox" name="minDuration">
<property name="suffix">
<string> frames</string>
......@@ -115,8 +94,15 @@
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QSpinBox" name="threshold"/>
<item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="add_markers">
<property name="text">
<string>Add clip markers</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment