Krita Source Code Documentation
Loading...
Searching...
No Matches
RecorderExport::Private Class Reference

Public Member Functions

QString applyVariables (const QString &templateArguments)
 
void checkFfmpeg ()
 
void cleanupFFMpeg ()
 
void fillComboProfiles ()
 
QString formatDuration (long durationMs)
 
 Private (RecorderExport *q_ptr)
 
QStringList splitCommand (const QString &command)
 
void startExport ()
 
bool tryAbortExport ()
 
void updateFps (RecorderExportConfig &config, bool takeFromInputFps=false)
 
void updateFrameInfo ()
 
void updateRatio (bool widthToHeight)
 
void updateVideoDuration ()
 
void updateVideoFilePath ()
 

Public Attributes

RecorderDirectoryCleanercleaner = nullptr
 
QElapsedTimer elapsedTimer
 
QScopedPointer< KisFFMpegWrapperffmpeg
 
RecorderExportq
 
RecorderExportSettingssettings
 
int spinInputFPSMaxValue = 0
 
int spinInputFPSMinValue = 0
 
QScopedPointer< Ui::RecorderExport > ui
 

Detailed Description

Definition at line 48 of file recorder_export.cpp.

Constructor & Destructor Documentation

◆ Private()

RecorderExport::Private::Private ( RecorderExport * q_ptr)
inline

Definition at line 63 of file recorder_export.cpp.

64 : q(q_ptr)
65 , ui(new Ui::RecorderExport)
66 , settings(q_ptr->settings)
67 {
68 }
QScopedPointer< Ui::RecorderExport > ui
RecorderExportSettings * settings
RecorderExportSettings * settings

Member Function Documentation

◆ applyVariables()

QString RecorderExport::Private::applyVariables ( const QString & templateArguments)
inline

Definition at line 262 of file recorder_export.cpp.

263 {
264 const QSize &outSize = settings->resize ? settings->size : settings->imageSize;
265 const int previewLength = settings->resultPreview ? settings->firstFrameSec : 0;
266 const int resultLength = settings->extendResult ? settings->lastFrameSec : 0;
267 const float transitionLength = settings->resultPreview ? 0.7 : 0;
268 return QString(templateArguments)
269 .replace("$IN_FPS", QString::number(settings->inputFps))
270 .replace("$OUT_FPS", QString::number(settings->fps))
271 .replace("$WIDTH", QString::number(outSize.width()))
272 .replace("$HEIGHT", QString::number(outSize.height()))
273 .replace("$FRAMES", QString::number(settings->framesCount))
274 .replace("$INPUT_DIR", settings->inputDirectory)
275 .replace("$FIRST_FRAME_SEC", QString::number(previewLength))
276 .replace("$TRANSITION_LENGTH", QString::number(transitionLength))
277 .replace("$H264_ENCODER", settings->h264Encoder)
278 .replace("$LAST_FRAME_SEC", QString::number(resultLength))
280 }
QLatin1String fileExtension(RecorderFormat format)

References RecorderExportSettings::extendResult, RecorderFormatInfo::fileExtension(), RecorderExportSettings::firstFrameSec, RecorderExportSettings::format, RecorderExportSettings::fps, RecorderExportSettings::framesCount, RecorderExportSettings::h264Encoder, RecorderExportSettings::imageSize, RecorderExportSettings::inputDirectory, RecorderExportSettings::inputFps, RecorderExportSettings::lastFrameSec, RecorderExportSettings::resize, RecorderExportSettings::resultPreview, settings, and RecorderExportSettings::size.

◆ checkFfmpeg()

void RecorderExport::Private::checkFfmpeg ( )
inline

Definition at line 70 of file recorder_export.cpp.

71 {
72 const QJsonObject ffmpegJson = KisFFMpegWrapper::findFFMpeg(settings->ffmpegPath);
73 const bool success = ffmpegJson["enabled"].toBool();
74 const QIcon &icon = KisIconUtils::loadIcon(success ? "dialog-ok" : "window-close");
75 const QList<QAction *> &actions = ui->editFfmpegPath->actions();
76 QAction *action;
77
78 if (!actions.isEmpty()) {
79 action = actions.first();
80 action->setIcon(icon);
81 } else {
82 action = ui->editFfmpegPath->addAction(icon, QLineEdit::TrailingPosition);
83 }
84 if (success) {
85 const QJsonArray h264Encoders = ffmpegJson["codecs"].toObject()["h264"].toObject()["encoders"].toArray();
86 settings->ffmpegPath = ffmpegJson["path"].toString();
87 settings->h264Encoder = h264Encoders.contains("libopenh264") ? "libopenh264" : "libx264";
88 ui->editFfmpegPath->setText(settings->ffmpegPath);
89 action->setToolTip("Version: "+ffmpegJson["version"].toString()
90 +(ffmpegJson["codecs"].toObject()["h264"].toObject()["encoding"].toBool() ? "":" (MP4/MKV UNSUPPORTED)")
91 );
92 } else {
93 ui->editFfmpegPath->setText(i18nc("This text is displayed instead of path to external tool in case of external tool is not found", "[NOT FOUND]"));
94 action->setToolTip(i18n("FFmpeg executable location couldn't be detected, please install it or select its location manually"));
95 }
96 ui->buttonBox->button(QDialogButtonBox::Save)->setEnabled(success);
97 }
static QJsonObject findFFMpeg(const QString &customLocation)
QString toString(const QString &value)
QIcon loadIcon(const QString &name)

References RecorderExportSettings::ffmpegPath, KisFFMpegWrapper::findFFMpeg(), RecorderExportSettings::h264Encoder, KisIconUtils::loadIcon(), settings, and ui.

◆ cleanupFFMpeg()

void RecorderExport::Private::cleanupFFMpeg ( )
inline

Definition at line 254 of file recorder_export.cpp.

255 {
256 if (ffmpeg) {
257 ffmpeg->reset();
258 ffmpeg.reset();
259 }
260 }
QScopedPointer< KisFFMpegWrapper > ffmpeg

References ffmpeg.

◆ fillComboProfiles()

void RecorderExport::Private::fillComboProfiles ( )
inline

Definition at line 99 of file recorder_export.cpp.

100 {
101 QSignalBlocker blocker(ui->comboProfile);
102 ui->comboProfile->clear();
103 for (const RecorderProfile &profile : settings->profiles) {
104 ui->comboProfile->addItem(profile.name);
105 }
106 blocker.unblock();
107 ui->comboProfile->setCurrentIndex(settings->profileIndex);
108 }

References RecorderExportSettings::profileIndex, RecorderExportSettings::profiles, settings, and ui.

◆ formatDuration()

QString RecorderExport::Private::formatDuration ( long durationMs)
inline

Definition at line 297 of file recorder_export.cpp.

298 {
299 QString result;
300 const long ms = (durationMs % 1000) / 10;
301
302 result += QString(".%1").arg(ms, 2, 10, QLatin1Char('0'));
303
304 long duration = durationMs / 1000;
305 const long seconds = duration % 60;
306 result = QString("%1%2").arg(seconds, 2, 10, QLatin1Char('0')).arg(result);
307
308 duration = duration / 60;
309 const long minutes = duration % 60;
310 if (minutes != 0) {
311 result = QString("%1:%2").arg(minutes, 2, 10, QLatin1Char('0')).arg(result);
312
313 duration = duration / 60;
314 if (duration != 0)
315 result = QString("%1:%2").arg(duration, 2, 10, QLatin1Char('0')).arg(result);
316 }
317
318 return result;
319 }

◆ splitCommand()

QStringList RecorderExport::Private::splitCommand ( const QString & command)
inline

Definition at line 186 of file recorder_export.cpp.

187 {
188 QStringList args;
189 QString tmp;
190 int quoteCount = 0;
191 bool inQuote = false;
192
193 // handle quoting. tokens can be surrounded by double quotes
194 // "hello world". three consecutive double quotes represent
195 // the quote character itself.
196 for (int i = 0; i < command.size(); ++i) {
197 if (command.at(i) == QLatin1Char('"')) {
198 ++quoteCount;
199 if (quoteCount == 3) {
200 // third consecutive quote
201 quoteCount = 0;
202 tmp += command.at(i);
203 }
204 continue;
205 }
206 if (quoteCount) {
207 if (quoteCount == 1)
208 inQuote = !inQuote;
209 quoteCount = 0;
210 }
211 if (!inQuote && command.at(i).isSpace()) {
212 if (!tmp.isEmpty()) {
213 args += tmp;
214 tmp.clear();
215 }
216 } else {
217 tmp += command.at(i);
218 }
219 }
220 if (!tmp.isEmpty())
221 args += tmp;
222
223 return args;
224 }

◆ startExport()

void RecorderExport::Private::startExport ( )
inline

Definition at line 226 of file recorder_export.cpp.

227 {
228 Q_ASSERT(ffmpeg == nullptr);
229
231
232 const QString &arguments = applyVariables(settings->profiles[settings->profileIndex].arguments);
233
234 ffmpeg.reset(new KisFFMpegWrapper(q));
235 QObject::connect(ffmpeg.data(), SIGNAL(sigStarted()), q, SLOT(onFFMpegStarted()));
236 QObject::connect(ffmpeg.data(), SIGNAL(sigFinished()), q, SLOT(onFFMpegFinished()));
237 QObject::connect(ffmpeg.data(), SIGNAL(sigFinishedWithError(QString)), q, SLOT(onFFMpegFinishedWithError(QString)));
238 QObject::connect(ffmpeg.data(), SIGNAL(sigProgressUpdated(int)), q, SLOT(onFFMpegProgressUpdated(int)));
239
240 KisFFMpegWrapperSettings FFmpegSettings;
241 KisConfig cfg(true);
242 FFmpegSettings.processPath = settings->ffmpegPath;
243 FFmpegSettings.args = splitCommand(arguments);
244 FFmpegSettings.outputFile = settings->videoFilePath;
245 FFmpegSettings.batchMode = true; //TODO: Consider renaming to 'silent' mode, meaning no window for extra window handling...
246
247 ffmpeg->startNonBlocking(FFmpegSettings);
248 ui->labelStatus->setText(i18nc("Status for the export of the video record", "Starting FFmpeg..."));
249 ui->buttonCancelExport->setEnabled(false);
250 ui->progressExport->setValue(0);
251 elapsedTimer.start();
252 }
QString applyVariables(const QString &templateArguments)
QStringList splitCommand(const QString &command)
void onFFMpegFinishedWithError(QString error)
void onFFMpegProgressUpdated(int frameNo)
QList< RecorderProfile > profiles

References applyVariables(), KisFFMpegWrapperSettings::args, KisFFMpegWrapperSettings::batchMode, elapsedTimer, ffmpeg, RecorderExportSettings::ffmpegPath, RecorderExport::onFFMpegFinished(), RecorderExport::onFFMpegFinishedWithError(), RecorderExport::onFFMpegProgressUpdated(), RecorderExport::onFFMpegStarted(), KisFFMpegWrapperSettings::outputFile, KisFFMpegWrapperSettings::processPath, RecorderExportSettings::profileIndex, RecorderExportSettings::profiles, q, settings, splitCommand(), ui, updateFrameInfo(), and RecorderExportSettings::videoFilePath.

◆ tryAbortExport()

bool RecorderExport::Private::tryAbortExport ( )
inline

Definition at line 172 of file recorder_export.cpp.

173 {
174 if (!ffmpeg)
175 return true;
176
177 if (QMessageBox::question(q, q->windowTitle(), i18n("Abort encoding the timelapse video?"))
178 == QMessageBox::Yes) {
180 return true;
181 }
182
183 return false;
184 }

References cleanupFFMpeg(), ffmpeg, and q.

◆ updateFps()

void RecorderExport::Private::updateFps ( RecorderExportConfig & config,
bool takeFromInputFps = false )
inline

Definition at line 155 of file recorder_export.cpp.

156 {
157 if (!settings->lockFps)
158 return;
159
160 if (takeFromInputFps) {
162 config.setFps(settings->fps);
163 ui->spinFps->setValue(settings->fps);
164 } else {
167 ui->spinInputFps->setValue(settings->inputFps);
168 }
170 }

References RecorderExportSettings::fps, RecorderExportSettings::inputFps, RecorderExportSettings::lockFps, RecorderExportConfig::setFps(), RecorderExportConfig::setInputFps(), settings, ui, and updateVideoDuration().

◆ updateFrameInfo()

void RecorderExport::Private::updateFrameInfo ( )
inline

Definition at line 110 of file recorder_export.cpp.

111 {
113 QDir::Name, QDir::Files | QDir::NoDotAndDotDot);
114 const QStringList &frames = dir.entryList(); // dir.count() calls entryList().count() internally
115 settings->framesCount = frames.count();
116 if (settings->framesCount != 0) {
117 const QString &fileName = settings->inputDirectory % QDir::separator() % frames.last();
118 settings->imageSize = QImageReader(fileName).size();
119 settings->imageSize.rwidth() &= ~1;
120 settings->imageSize.rheight() &= ~1;
121 }
122 }

References RecorderFormatInfo::fileExtension(), RecorderExportSettings::format, RecorderExportSettings::framesCount, RecorderExportSettings::imageSize, RecorderExportSettings::inputDirectory, and settings.

◆ updateRatio()

void RecorderExport::Private::updateRatio ( bool widthToHeight)
inline

Definition at line 138 of file recorder_export.cpp.

139 {
140 const float ratio = static_cast<float>(settings->imageSize.width()) / static_cast<float>(settings->imageSize.height());
141 if (widthToHeight) {
142 settings->size.setHeight(static_cast<int>(settings->size.width() / ratio));
143 } else {
144 settings->size.setWidth(static_cast<int>(settings->size.height() * ratio));
145 }
146 // make width and height even
147 settings->size.rwidth() &= ~1;
148 settings->size.rheight() &= ~1;
149 QSignalBlocker blockerWidth(ui->spinScaleHeight);
150 QSignalBlocker blockerHeight(ui->spinScaleWidth);
151 ui->spinScaleHeight->setValue(settings->size.height());
152 ui->spinScaleWidth->setValue(settings->size.width());
153 }

References RecorderExportSettings::imageSize, settings, RecorderExportSettings::size, and ui.

◆ updateVideoDuration()

void RecorderExport::Private::updateVideoDuration ( )
inline

◆ updateVideoFilePath()

Member Data Documentation

◆ cleaner

RecorderDirectoryCleaner* RecorderExport::Private::cleaner = nullptr

Definition at line 56 of file recorder_export.cpp.

◆ elapsedTimer

QElapsedTimer RecorderExport::Private::elapsedTimer

Definition at line 58 of file recorder_export.cpp.

◆ ffmpeg

QScopedPointer<KisFFMpegWrapper> RecorderExport::Private::ffmpeg

Definition at line 55 of file recorder_export.cpp.

◆ q

RecorderExport* RecorderExport::Private::q

Definition at line 51 of file recorder_export.cpp.

◆ settings

RecorderExportSettings* RecorderExport::Private::settings

Definition at line 53 of file recorder_export.cpp.

◆ spinInputFPSMaxValue

int RecorderExport::Private::spinInputFPSMaxValue = 0

Definition at line 61 of file recorder_export.cpp.

◆ spinInputFPSMinValue

int RecorderExport::Private::spinInputFPSMinValue = 0

Definition at line 60 of file recorder_export.cpp.

◆ ui

QScopedPointer<Ui::RecorderExport> RecorderExport::Private::ui

Definition at line 52 of file recorder_export.cpp.


The documentation for this class was generated from the following file: