[graphics/krita/krita/5.0] plugins/dockers/recorder: Update the recorder with master

Halla Rempt null at kde.org
Tue Nov 2 17:24:11 GMT 2021


Git commit 928a46439f227749f12a4d27d5fa0c66c075c376 by Halla Rempt.
Committed on 02/11/2021 at 17:23.
Pushed by rempt into branch 'krita/5.0'.

Update the recorder with master

It was impossible to correctly merge patches to the recorder from
master to 5.0, so make sure we have all the changes. This does add
string changes, but the original strings are so obviously wrong
that they amounted to bugs.

CCMAIL:kimageshop at kde.org

M  +36   -14   plugins/dockers/recorder/recorder_export.cpp
M  +1    -0    plugins/dockers/recorder/recorder_export.h
M  +191  -145  plugins/dockers/recorder/recorder_export.ui
M  +20   -10   plugins/dockers/recorder/recorder_export_config.cpp
M  +3    -0    plugins/dockers/recorder/recorder_export_config.h
M  +12   -11   plugins/dockers/recorder/recorder_profile_settings.ui
M  +2    -2    plugins/dockers/recorder/recorderdocker.ui
M  +2    -2    plugins/dockers/recorder/recorderdocker_dock.cpp

https://invent.kde.org/graphics/krita/commit/928a46439f227749f12a4d27d5fa0c66c075c376

diff --git a/plugins/dockers/recorder/recorder_export.cpp b/plugins/dockers/recorder/recorder_export.cpp
index d3187b942e..33dae04c45 100644
--- a/plugins/dockers/recorder/recorder_export.cpp
+++ b/plugins/dockers/recorder/recorder_export.cpp
@@ -62,6 +62,7 @@ public:
     QString videoFileName;
     QString videoFilePath;
     int framesCount = 0;
+    int lastFrameSec = 5;
 
     QScopedPointer<KisFFMpegWrapper> ffmpeg;
     RecorderDirectoryCleaner *cleaner = nullptr;
@@ -94,7 +95,7 @@ public:
             );
         } else {
             ui->editFfmpegPath->setText(i18nc("This text is displayed instead of path to external tool in case of external tool is not found", "[NOT FOUND]"));
-            action->setToolTip(i18n("FFMpeg executable location couldn't be detected, please install it or select its location manually"));
+            action->setToolTip(i18n("FFmpeg executable location couldn't be detected, please install it or select its location manually"));
         }
         ui->buttonBox->button(QDialogButtonBox::Save)->setEnabled(success);
     }
@@ -230,7 +231,7 @@ public:
         settings.batchMode = true; //TODO: Consider renaming to 'silent' mode, meaning no window for extra window handling...
 
         ffmpeg->startNonBlocking(settings);
-        ui->labelStatus->setText(i18nc("Status for the export of the video record", "Starting FFMpeg..."));
+        ui->labelStatus->setText(i18nc("Status for the export of the video record", "Starting FFmpeg..."));
         ui->buttonCancelExport->setEnabled(false);
         ui->progressExport->setValue(0);
     }
@@ -250,21 +251,23 @@ public:
                .replace("$HEIGHT", QString::number(outSize.height()))
                .replace("$FRAMES", QString::number(framesCount))
                .replace("$INPUT_DIR", settings.inputDirectory)
+               .replace("$LAST_FRAME_SEC", QString::number(lastFrameSec))
                .replace("$EXT", RecorderFormatInfo::fileExtension(settings.format));
     }
 
     void updateVideoDuration()
     {
-        long ms = framesCount * 1000L / (inputFps ? inputFps : 30);
+        long ms = (framesCount * 1000L / (inputFps ? inputFps : 30)) + (lastFrameSec * 1000L);
         ui->labelVideoDuration->setText(formatDuration(ms));
     }
 
     QString formatDuration(long durationMs)
     {
         QString result;
-        const long ms = (durationMs % 1000) / 100;
-        if (ms != 0)
-            result += "." % QString::number(ms);
+        const long ms = (durationMs % 1000) / 10;
+
+        result += QString(".%1").arg(ms, 2, 10, QLatin1Char('0'));
+
         long duration = durationMs / 1000;
         const long seconds = duration % 60;
         result = QString("%1%2").arg(seconds, 2, 10, QLatin1Char('0')).arg(result);
@@ -302,6 +305,7 @@ RecorderExport::RecorderExport(QWidget *parent)
     connect(d->ui->buttonBrowseDirectory, SIGNAL(clicked()), SLOT(onButtonBrowseDirectoryClicked()));
     connect(d->ui->spinInputFps, SIGNAL(valueChanged(int)), SLOT(onSpinInputFpsValueChanged(int)));
     connect(d->ui->spinFps, SIGNAL(valueChanged(int)), SLOT(onSpinFpsValueChanged(int)));
+    connect(d->ui->spinLastFrameSec, SIGNAL(valueChanged(int)), SLOT(onLastFrameSecValueChanged(int)));
     connect(d->ui->checkResize, SIGNAL(toggled(bool)), SLOT(onCheckResizeToggled(bool)));
     connect(d->ui->spinScaleWidth, SIGNAL(valueChanged(int)), SLOT(onSpinScaleWidthValueChanged(int)));
     connect(d->ui->spinScaleHeight, SIGNAL(valueChanged(int)), SLOT(onSpinScaleHeightValueChanged(int)));
@@ -391,7 +395,12 @@ void RecorderExport::reject()
 
 void RecorderExport::onButtonBrowseDirectoryClicked()
 {
-    QDesktopServices::openUrl(QUrl::fromLocalFile(d->settings.inputDirectory));
+    if (d->framesCount != 0) {
+        QDesktopServices::openUrl(QUrl::fromLocalFile(d->settings.inputDirectory));
+    } else {
+        QMessageBox::warning(this, windowTitle(), i18nc("Can't browse frames of recording because no frames have been recorded", "No frames to browse."));
+        return;
+    }
 }
 
 void RecorderExport::onSpinInputFpsValueChanged(int value)
@@ -407,6 +416,13 @@ void RecorderExport::onSpinFpsValueChanged(int value)
     RecorderExportConfig(false).setFps(value);
 }
 
+void RecorderExport::onLastFrameSecValueChanged(int value)
+{
+    d->lastFrameSec = value;
+    RecorderExportConfig(false).setLastFrameSec(value);
+    d->updateVideoDuration();
+}
+
 void RecorderExport::onCheckResizeToggled(bool checked)
 {
     d->resize = checked;
@@ -449,7 +465,7 @@ void RecorderExport::onButtonBrowseFfmpegClicked()
     dialog.setFilter(QDir::Executable | QDir::Files);
 
     const QString &file = dialog.getOpenFileName(this,
-                          i18n("Select FFMpeg Executable File"),
+                          i18n("Select FFmpeg Executable File"),
                           d->ffmpegPath);
     if (!file.isEmpty()) {
         d->ffmpegPath = file;
@@ -509,13 +525,19 @@ void RecorderExport::onButtonBrowseExportClicked()
 void RecorderExport::onButtonExportClicked()
 {
     if (QFile::exists(d->videoFilePath)) {
-        if (QMessageBox::question(this, windowTitle(),
-                                  i18n("The video file is already exists. Do you wish to overwrite?"))
-            != QMessageBox::Yes) {
+        if (d->framesCount != 0) {
+            if (QMessageBox::question(this, windowTitle(),
+                                      i18n("The video file already exists. Do you wish to overwrite it?"))
+                != QMessageBox::Yes) {
+                return;
+            }
+        } else {
+            QMessageBox::warning(this, windowTitle(), i18n("No frames to export."));
             return;
         }
     }
 
+
     d->ui->stackedWidget->setCurrentIndex(ExportPageIndex::PageProgress);
     d->startExport();
 }
@@ -550,7 +572,7 @@ void RecorderExport::onFFMpegFinished()
 void RecorderExport::onFFMpegFinishedWithError(QString error)
 {
     d->ui->stackedWidget->setCurrentIndex(ExportPageIndex::PageSettings);
-    QMessageBox::critical(this, windowTitle(), i18n("Export failed. FFMpeg message:") % "\n\n" % error);
+    QMessageBox::critical(this, windowTitle(), i18n("Export failed. FFmpeg message:") % "\n\n" % error);
     d->cleanupFFMpeg();
 }
 
@@ -573,8 +595,8 @@ void RecorderExport::onButtonRemoveSnapshotsClicked()
 {
     const QString confirmation(i18n("The recordings for this document will be deleted"
                                     " and you will not be able to export a timelapse for it again"
-                                    " (the already exported timelapses will be preserved though)."
-                                    "\nDo you wish to continue?"));
+                                    ". Note that already exported timelapses will still be preserved."
+                                    "\n\nDo you wish to continue?"));
     if (QMessageBox::question(this, windowTitle(), confirmation) != QMessageBox::Yes)
         return;
 
diff --git a/plugins/dockers/recorder/recorder_export.h b/plugins/dockers/recorder/recorder_export.h
index 2d33f8b2d4..4404e770db 100644
--- a/plugins/dockers/recorder/recorder_export.h
+++ b/plugins/dockers/recorder/recorder_export.h
@@ -38,6 +38,7 @@ private Q_SLOTS:
     void onButtonBrowseDirectoryClicked();
     void onSpinInputFpsValueChanged(int value);
     void onSpinFpsValueChanged(int value);
+    void onLastFrameSecValueChanged(int value);
     void onCheckResizeToggled(bool checked);
     void onSpinScaleWidthValueChanged(int value);
     void onSpinScaleHeightValueChanged(int value);
diff --git a/plugins/dockers/recorder/recorder_export.ui b/plugins/dockers/recorder/recorder_export.ui
index 5e1d304d2b..cbf15ea3ec 100644
--- a/plugins/dockers/recorder/recorder_export.ui
+++ b/plugins/dockers/recorder/recorder_export.ui
@@ -10,7 +10,7 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>395</width>
+    <width>405</width>
     <height>347</height>
    </rect>
   </property>
@@ -86,47 +86,29 @@
          <property name="rightMargin">
           <number>9</number>
          </property>
-         <item row="7" column="2">
-          <widget class="QPushButton" name="buttonBrowseExport">
-           <property name="toolTip">
-            <string>Select a file to export timelapse video</string>
-           </property>
+         <item row="7" column="0">
+          <widget class="QLabel" name="labelFfmpegLocation">
            <property name="text">
-            <string/>
+            <string>FFmpeg:</string>
            </property>
-           <property name="icon">
-            <iconset theme="folder">
-             <normaloff>.</normaloff>.</iconset>
-           </property>
-          </widget>
-         </item>
-         <item row="5" column="2">
-          <widget class="QPushButton" name="buttonBrowseFfmpeg">
-           <property name="toolTip">
-            <string>Setup ffmpeg executable location</string>
-           </property>
-           <property name="text">
-            <string/>
+           <property name="alignment">
+            <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
            </property>
-           <property name="icon">
-            <iconset theme="folder">
-             <normaloff>.</normaloff>.</iconset>
+           <property name="buddy">
+            <cstring>editFfmpegPath</cstring>
            </property>
           </widget>
          </item>
-         <item row="5" column="1">
-          <widget class="QLineEdit" name="editFfmpegPath">
-           <property name="minimumSize">
-            <size>
-             <width>120</width>
-             <height>0</height>
-            </size>
-           </property>
+         <item row="9" column="0">
+          <widget class="QLabel" name="labelExportTo">
            <property name="text">
-            <string>ffmpeg</string>
+            <string>Video location:</string>
            </property>
-           <property name="readOnly">
-            <bool>true</bool>
+           <property name="alignment">
+            <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+           </property>
+           <property name="buddy">
+            <cstring>editVideoFilePath</cstring>
            </property>
           </widget>
          </item>
@@ -172,7 +154,7 @@
            </item>
           </layout>
          </item>
-         <item row="3" column="1">
+         <item row="5" column="1">
           <widget class="QWidget" name="widgetResolution" native="true">
            <property name="enabled">
             <bool>false</bool>
@@ -278,33 +260,83 @@
            </layout>
           </widget>
          </item>
-         <item row="6" column="0">
-          <widget class="QLabel" name="labelResolution">
-           <property name="text">
-            <string>Render as:</string>
+         <item row="2" column="0">
+          <widget class="QLabel" name="labelHoldLastFrameSec">
+           <property name="toolTip">
+            <string>The added duration for showing the last frame.</string>
            </property>
-           <property name="alignment">
-            <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+           <property name="text">
+            <string>Hold Last Frame for:</string>
            </property>
-           <property name="buddy">
-            <cstring>comboProfile</cstring>
+          </widget>
+         </item>
+         <item row="0" column="1">
+          <layout class="QHBoxLayout" name="layoutFps_2" stretch="0,1">
+           <item>
+            <widget class="QSpinBox" name="spinInputFps">
+             <property name="minimumSize">
+              <size>
+               <width>90</width>
+               <height>0</height>
+              </size>
+             </property>
+             <property name="keyboardTracking">
+              <bool>false</bool>
+             </property>
+             <property name="minimum">
+              <number>1</number>
+             </property>
+             <property name="maximum">
+              <number>10000</number>
+             </property>
+             <property name="value">
+              <number>30</number>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <spacer name="horizontalSpacer_14">
+             <property name="orientation">
+              <enum>Qt::Horizontal</enum>
+             </property>
+             <property name="sizeType">
+              <enum>QSizePolicy::Expanding</enum>
+             </property>
+             <property name="sizeHint" stdset="0">
+              <size>
+               <width>6</width>
+               <height>6</height>
+              </size>
+             </property>
+            </spacer>
+           </item>
+          </layout>
+         </item>
+         <item row="6" column="0" colspan="3">
+          <widget class="Line" name="line">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
            </property>
           </widget>
          </item>
-         <item row="5" column="0">
-          <widget class="QLabel" name="labelFfmpegLocation">
+         <item row="0" column="0">
+          <widget class="QLabel" name="labelFpsInput">
+           <property name="toolTip">
+            <string>The speed of reading the input stream.
+For example, to make your timelapse twice faster, the Input FPS should be twice larger of the Video FPS.</string>
+           </property>
            <property name="text">
-            <string>FFMpeg:</string>
+            <string comment="Input FPS of recorded timelapses.">Input FPS:</string>
            </property>
            <property name="alignment">
             <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
            </property>
            <property name="buddy">
-            <cstring>editFfmpegPath</cstring>
+            <cstring>spinInputFps</cstring>
            </property>
           </widget>
          </item>
-         <item row="7" column="1">
+         <item row="9" column="1">
           <widget class="QLineEdit" name="editVideoFilePath">
            <property name="minimumSize">
             <size>
@@ -317,45 +349,33 @@
            </property>
           </widget>
          </item>
-         <item row="6" column="2">
-          <widget class="QPushButton" name="buttonEditProfile">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
+         <item row="7" column="1">
+          <widget class="QLineEdit" name="editFfmpegPath">
            <property name="minimumSize">
             <size>
-             <width>28</width>
-             <height>24</height>
+             <width>120</width>
+             <height>0</height>
             </size>
            </property>
-           <property name="maximumSize">
-            <size>
-             <width>28</width>
-             <height>24</height>
-            </size>
+           <property name="text">
+            <string>ffmpeg</string>
            </property>
-           <property name="toolTip">
-            <string>Edit video profile</string>
+           <property name="readOnly">
+            <bool>true</bool>
            </property>
           </widget>
          </item>
-         <item row="1" column="0">
-          <widget class="QLabel" name="labelFps">
-           <property name="text">
-            <string>Video FPS:</string>
-           </property>
-           <property name="alignment">
-            <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-           </property>
-           <property name="buddy">
-            <cstring>spinFps</cstring>
+         <item row="8" column="1">
+          <widget class="QComboBox" name="comboProfile">
+           <property name="minimumSize">
+            <size>
+             <width>120</width>
+             <height>0</height>
+            </size>
            </property>
           </widget>
          </item>
-         <item row="3" column="0">
+         <item row="5" column="0">
           <layout class="QHBoxLayout" name="horizontalLayout_8" stretch="1,0">
            <item>
             <spacer name="horizontalSpacer_12">
@@ -388,58 +408,131 @@
            </item>
           </layout>
          </item>
-         <item row="7" column="0">
-          <widget class="QLabel" name="labelExportTo">
+         <item row="5" column="2">
+          <widget class="QPushButton" name="buttonLockRatio">
+           <property name="enabled">
+            <bool>false</bool>
+           </property>
+           <property name="toolTip">
+            <string>Constrain proportions</string>
+           </property>
            <property name="text">
-            <string>Video location:</string>
+            <string/>
+           </property>
+           <property name="icon">
+            <iconset theme="lock">
+             <normaloff>.</normaloff>.</iconset>
+           </property>
+           <property name="checkable">
+            <bool>true</bool>
+           </property>
+          </widget>
+         </item>
+         <item row="8" column="0">
+          <widget class="QLabel" name="labelResolution">
+           <property name="text">
+            <string>Render as:</string>
            </property>
            <property name="alignment">
             <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
            </property>
            <property name="buddy">
-            <cstring>editVideoFilePath</cstring>
+            <cstring>comboProfile</cstring>
            </property>
           </widget>
          </item>
-         <item row="4" column="0" colspan="3">
-          <widget class="Line" name="line">
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
+         <item row="9" column="2">
+          <widget class="QPushButton" name="buttonBrowseExport">
+           <property name="toolTip">
+            <string>Select a file location for the exported timelapse video</string>
+           </property>
+           <property name="text">
+            <string/>
+           </property>
+           <property name="icon">
+            <iconset theme="folder">
+             <normaloff>.</normaloff>.</iconset>
            </property>
           </widget>
          </item>
-         <item row="0" column="1">
-          <layout class="QHBoxLayout" name="layoutFps_2" stretch="0,1">
+         <item row="1" column="0">
+          <widget class="QLabel" name="labelFps">
+           <property name="text">
+            <string>Video FPS:</string>
+           </property>
+           <property name="alignment">
+            <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+           </property>
+           <property name="buddy">
+            <cstring>spinFps</cstring>
+           </property>
+          </widget>
+         </item>
+         <item row="8" column="2">
+          <widget class="QPushButton" name="buttonEditProfile">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>28</width>
+             <height>24</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>28</width>
+             <height>24</height>
+            </size>
+           </property>
+           <property name="toolTip">
+            <string>Edit video profile</string>
+           </property>
+          </widget>
+         </item>
+         <item row="7" column="2">
+          <widget class="QPushButton" name="buttonBrowseFfmpeg">
+           <property name="toolTip">
+            <string>Setup ffmpeg executable location</string>
+           </property>
+           <property name="text">
+            <string/>
+           </property>
+           <property name="icon">
+            <iconset theme="folder">
+             <normaloff>.</normaloff>.</iconset>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="1">
+          <layout class="QHBoxLayout" name="horizontalLayout_6">
            <item>
-            <widget class="QSpinBox" name="spinInputFps">
+            <widget class="QSpinBox" name="spinLastFrameSec">
              <property name="minimumSize">
               <size>
                <width>90</width>
                <height>0</height>
               </size>
              </property>
-             <property name="keyboardTracking">
-              <bool>false</bool>
-             </property>
-             <property name="minimum">
-              <number>1</number>
+             <property name="suffix">
+              <string comment="Contraction of "second" for interval"> sec.</string>
              </property>
              <property name="maximum">
-              <number>10000</number>
+              <number>120</number>
              </property>
              <property name="value">
-              <number>30</number>
+              <number>5</number>
              </property>
             </widget>
            </item>
            <item>
-            <spacer name="horizontalSpacer_14">
+            <spacer name="horizontalSpacer_15">
              <property name="orientation">
               <enum>Qt::Horizontal</enum>
              </property>
-             <property name="sizeType">
-              <enum>QSizePolicy::Expanding</enum>
-             </property>
              <property name="sizeHint" stdset="0">
               <size>
                <width>6</width>
@@ -450,53 +543,6 @@
            </item>
           </layout>
          </item>
-         <item row="3" column="2">
-          <widget class="QPushButton" name="buttonLockRatio">
-           <property name="enabled">
-            <bool>false</bool>
-           </property>
-           <property name="toolTip">
-            <string>Constrain proportions</string>
-           </property>
-           <property name="text">
-            <string/>
-           </property>
-           <property name="icon">
-            <iconset theme="lock">
-             <normaloff>.</normaloff>.</iconset>
-           </property>
-           <property name="checkable">
-            <bool>true</bool>
-           </property>
-          </widget>
-         </item>
-         <item row="6" column="1">
-          <widget class="QComboBox" name="comboProfile">
-           <property name="minimumSize">
-            <size>
-             <width>120</width>
-             <height>0</height>
-            </size>
-           </property>
-          </widget>
-         </item>
-         <item row="0" column="0">
-          <widget class="QLabel" name="labelFpsInput">
-           <property name="toolTip">
-            <string>The speed of reading the input stream.
-For example to make your speedpaint twice faster it should be twice larger of the Video FPS.</string>
-           </property>
-           <property name="text">
-            <string comment="Input FPS of recorded timelapses.">Input FPS:</string>
-           </property>
-           <property name="alignment">
-            <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-           </property>
-           <property name="buddy">
-            <cstring>spinInputFps</cstring>
-           </property>
-          </widget>
-         </item>
         </layout>
        </item>
        <item row="3" column="0">
diff --git a/plugins/dockers/recorder/recorder_export_config.cpp b/plugins/dockers/recorder/recorder_export_config.cpp
index a6d40d851d..d7d782f12a 100644
--- a/plugins/dockers/recorder/recorder_export_config.cpp
+++ b/plugins/dockers/recorder/recorder_export_config.cpp
@@ -18,6 +18,7 @@ const QString keyFfmpegPath = "ffmpeg_path";
 const QString keyVideoDirectory = "recorder_export/videodirectory";
 const QString keyInputFps = "recorder_export/inputfps";
 const QString keyFps = "recorder_export/fps";
+const QString keyLastFrameSec = "recorder_export/lastframesec";
 const QString keyResize = "recorder_export/resize";
 const QString keySize = "recorder_export/size";
 const QString keyLockRatio = "recorder_export/lockratio";
@@ -28,11 +29,11 @@ const QString keyEditedProfiles = "recorder_export/editedprofiles";
 const QString profilePrefix = "-framerate $IN_FPS\n-i \"$INPUT_DIR%07d.$EXT\"\n";
 
 const QList<RecorderProfile> defaultProfiles = {
-    { "MP4 x264",   "mp4",  profilePrefix % "-vf \"scale=$WIDTH:$HEIGHT\"\n-c:v libx264\n-r $OUT_FPS\n-pix_fmt yuv420p" },
-    { "GIF",        "gif",  profilePrefix % "-vf \"fps=$OUT_FPS,scale=$WIDTH:$HEIGHT:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse\"\n-loop -1" },
-    { "Matroska",   "mkv",  profilePrefix % "-vf \"scale=$WIDTH:$HEIGHT\"\n-r $OUT_FPS" },
-    { "WebM",       "webm", profilePrefix % "-vf \"scale=$WIDTH:$HEIGHT\"\n-r $OUT_FPS" },
-    { "MP4 x264 (+5s Flash Effect)",  "mp4", profilePrefix % "-filter_complex \"\n"
+    { "MP4 x264",   "mp4",  profilePrefix % "-filter_complex \"loop=$LAST_FRAME_SEC*$OUT_FPS:size=1:start=$FRAMES,scale=$WIDTH:$HEIGHT\"\n-c:v libx264\n-r $OUT_FPS\n-pix_fmt yuv420p" },
+    { "GIF",        "gif",  profilePrefix % "-filter_complex \"fps=$OUT_FPS,loop=$LAST_FRAME_SEC*$OUT_FPS:size=1:start=$FRAMES,scale=$WIDTH:$HEIGHT:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse\"\n-loop -1" },
+    { "Matroska",   "mkv",  profilePrefix % "-filter_complex \"loop=$LAST_FRAME_SEC*$OUT_FPS:size=1:start=$FRAMES,scale=$WIDTH:$HEIGHT\"\n-r $OUT_FPS" },
+    { "WebM",       "webm", profilePrefix % "-filter_complex \"loop=$LAST_FRAME_SEC*$OUT_FPS:size=1:start=$FRAMES,scale=$WIDTH:$HEIGHT\"\n-r $OUT_FPS" },
+    { "MP4 x264 (Flash Effect)",  "mp4", profilePrefix % "-filter_complex \"\n"
                                             " [0]scale=$WIDTH:$HEIGHT[q1];\n"
                                             " [q1]tpad=stop_mode=clone:stop_duration=1[v1];\n"
                                             " [0]trim=start_frame=$FRAMES-1[p1];\n"
@@ -40,14 +41,14 @@ const QList<RecorderProfile> defaultProfiles = {
                                             " [p2]fps=$OUT_FPS[p3];\n"
                                             " [p3]trim=start_frame=0:end_frame=1[p4];\n"
                                             " [p4]scale=$WIDTH:$HEIGHT[p5];\n"
-                                            " [p5]tpad=stop_mode=clone:stop_duration=4[p6];\n"
+                                            " [p5]tpad=stop_mode=clone:stop_duration=$LAST_FRAME_SEC[p6];\n"
                                             " [p6]fade=type=in:color=white:start_time=0.7:duration=0.7[v2];\n"
                                             " [v1][v2]concat=n=2:v=1\n"
                                             "\"\n-c:v libx264\n-r $OUT_FPS\n-pix_fmt yuv420p" },
-    { "Custom1",  "editme", profilePrefix % "-vf \"scale=$WIDTH:$HEIGHT\"\n-r $OUT_FPS" },
-    { "Custom2",  "editme", profilePrefix % "-vf \"scale=$WIDTH:$HEIGHT\"\n-r $OUT_FPS" },
-    { "Custom3",  "editme", profilePrefix % "-vf \"scale=$WIDTH:$HEIGHT\"\n-r $OUT_FPS" },
-    { "Custom4",  "editme", profilePrefix % "-vf \"scale=$WIDTH:$HEIGHT\"\n-r $OUT_FPS" }
+    { "Custom1",  "editme", profilePrefix % "-filter_complex \"loop=$LAST_FRAME_SEC:size=1:start=$FRAMES,scale=$WIDTH:$HEIGHT\"\n-r $OUT_FPS" },
+    { "Custom2",  "editme", profilePrefix % "-filter_complex \"loop=$LAST_FRAME_SEC:size=1:start=$FRAMES,scale=$WIDTH:$HEIGHT\"\n-r $OUT_FPS" },
+    { "Custom3",  "editme", profilePrefix % "-filter_complex \"loop=$LAST_FRAME_SEC:size=1:start=$FRAMES,scale=$WIDTH:$HEIGHT\"\n-r $OUT_FPS" },
+    { "Custom4",  "editme", profilePrefix % "-filter_complex \"loop=$LAST_FRAME_SEC:size=1:start=$FRAMES,scale=$WIDTH:$HEIGHT\"\n-r $OUT_FPS" }
 };
 }
 
@@ -83,6 +84,15 @@ void RecorderExportConfig::setFps(int value)
     config->writeEntry(keyFps, value);
 }
 
+int RecorderExportConfig::lastFrameSec() const
+{
+    return config->readEntry(keyLastFrameSec, 5);
+}
+
+void RecorderExportConfig::setLastFrameSec(int value)
+{
+    config->writeEntry(keyLastFrameSec, value);
+}
 
 bool RecorderExportConfig::resize() const
 {
diff --git a/plugins/dockers/recorder/recorder_export_config.h b/plugins/dockers/recorder/recorder_export_config.h
index 921284ad7b..b3b0f70ebe 100644
--- a/plugins/dockers/recorder/recorder_export_config.h
+++ b/plugins/dockers/recorder/recorder_export_config.h
@@ -32,6 +32,9 @@ public:
     int fps() const;
     void setFps(int value);
 
+    void setLastFrameSec(int value);
+    int lastFrameSec() const;
+
     bool resize() const;
     void setResize(bool value);
 
diff --git a/plugins/dockers/recorder/recorder_profile_settings.ui b/plugins/dockers/recorder/recorder_profile_settings.ui
index 06f4336be8..1065d5e5f1 100644
--- a/plugins/dockers/recorder/recorder_profile_settings.ui
+++ b/plugins/dockers/recorder/recorder_profile_settings.ui
@@ -10,7 +10,7 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>617</width>
+    <width>638</width>
     <height>454</height>
    </rect>
   </property>
@@ -69,16 +69,6 @@
        <property name="bottomMargin">
         <number>0</number>
        </property>
-       <item row="0" column="0">
-        <widget class="QPlainTextEdit" name="editFfmpegArguments">
-         <property name="documentTitle">
-          <string notr="true"/>
-         </property>
-         <property name="plainText">
-          <string notr="true"/>
-         </property>
-        </widget>
-       </item>
        <item row="1" column="0">
         <layout class="QHBoxLayout" name="horizontalLayout_3" stretch="0,1">
          <item>
@@ -99,6 +89,7 @@
 <a href="$WIDTH">$WIDTH</a>
 <a href="$HEIGHT">$HEIGHT</a>
 <a href="$FRAMES">$FRAMES</a>
+<a href="$LAST_FRAME_SEC">$LAST_FRAME_SEC</a>
 <a href="$INPUT_DIR">$INPUT_DIR</a>
 <a href="$EXT">$EXT</a>
 </string>
@@ -113,6 +104,16 @@
          </item>
         </layout>
        </item>
+       <item row="0" column="0">
+        <widget class="QPlainTextEdit" name="editFfmpegArguments">
+         <property name="documentTitle">
+          <string notr="true"/>
+         </property>
+         <property name="plainText">
+          <string notr="true"/>
+         </property>
+        </widget>
+       </item>
       </layout>
      </widget>
      <widget class="QWidget" name="pagePreview">
diff --git a/plugins/dockers/recorder/recorderdocker.ui b/plugins/dockers/recorder/recorderdocker.ui
index 707558e054..d53273ae30 100644
--- a/plugins/dockers/recorder/recorderdocker.ui
+++ b/plugins/dockers/recorder/recorderdocker.ui
@@ -296,7 +296,7 @@
            <widget class="QCheckBox" name="checkBoxRecordIsolateMode">
             <property name="toolTip">
              <string>Record frames when Isolate Layer or Isolate Group mode is active.
-Depending on timelapse speed this may cause flickering in resulting video.</string>
+Depending on timelapse speed, this may cause flickering in the resulting video.</string>
             </property>
             <property name="text">
              <string comment="Record when Isolate Layer mode is active">Record in isolate mode</string>
@@ -361,7 +361,7 @@ Depending on timelapse speed this may cause flickering in resulting video.</stri
         <widget class="QLabel" name="labelUnsupportedColorSpace">
          <property name="text">
           <string>⚠ Unsupported color space.
-"RGB/Alpha 8-bit" is only supported.</string>
+Only "RGB/Alpha 8-bit" is supported.</string>
          </property>
          <property name="wordWrap">
           <bool>true</bool>
diff --git a/plugins/dockers/recorder/recorderdocker_dock.cpp b/plugins/dockers/recorder/recorderdocker_dock.cpp
index b47e6abf52..3005c9c907 100644
--- a/plugins/dockers/recorder/recorderdocker_dock.cpp
+++ b/plugins/dockers/recorder/recorderdocker_dock.cpp
@@ -100,7 +100,7 @@ public:
             case RecorderFormat::JPEG:
                 index = 0;
                 title = i18nc("Title for label. JPEG Quality level", "Quality:");
-                hint = i18nc("@tooltip", "Greater value will produce a larger file and a better quality. Doesn't affect CPU consumption.\nValues lower than 50 are not recommended due to high artifacts");
+                hint = i18nc("@tooltip", "Greater value will produce a larger file and a better quality. Doesn't affect CPU consumption.\nValues lower than 50 are not recommended due to high artifacts.");
                 minValue = 1;
                 maxValue = 100;
                 suffix = "%";
@@ -461,7 +461,7 @@ void RecorderDockerDock::onWriterPausedChanged(bool paused)
 void RecorderDockerDock::onWriterFrameWriteFailed()
 {
     QMessageBox::warning(this, i18nc("@title:window", "Recorder"),
-        i18n("The recorder have been stopped due to failure while writing a frame. Please check free disk space and start recorder again."));
+        i18n("The recorder has been stopped due to failure while writing a frame. Please check free disk space and start the recorder again."));
 }
 
 void RecorderDockerDock::slotScrollerStateChanged(QScroller::State state)


More information about the kimageshop mailing list