58 const QString &savedFilesMask,
63 Q_UNUSED(savedFilesMask);
68 QVariantMap formatPreferences;
69 if (!options.videoFormatPreferencesJson.isEmpty()) {
70 formatPreferences = QJsonDocument::fromJson(options.videoFormatPreferencesJson.toUtf8()).toVariant().toMap();
88 QString inputDir = framesDirectory;
89 if (!inputDir.endsWith(QStringLiteral(
"/"))) {
90 inputDir.append(QStringLiteral(
"/"));
93 settings.
inputFiles.reserve(savedFiles.size());
94 for (
const QString &savedFile : savedFiles) {
95 settings.
inputFiles.append(inputDir + savedFile);
100 QTemporaryFile audioFile;
103 if (!audioFiles.isEmpty()) {
104 QString audioPath = audioFiles.first().filePath();
105 QString errorMessage;
107 settings.
audioFile = audioFile.fileName();
124 bool batchMode =
false;
127 Q_UNUSED(framesDirectory);
128 Q_UNUSED(savedFiles);
130 if (!QFileInfo(options.
ffmpegPath).exists()) {
144 const QString exportDimensions =
146 .append(QString::number(options.
width))
148 .append(QString::number(options.
height))
154 const QFileInfo resultFileInfo(resultFile);
155 const QDir videoDir(resultFileInfo.absolutePath());
157 const QString suffix = resultFileInfo.suffix().toLower();
158 const QString palettePath = videoDir.filePath(
"KritaTempPalettegen_\%06d.png");
171 <<
"-r" << QString::number(options.
frameRate)
172 <<
"-start_number" << QString::number(sequenceStart) <<
"-start_number_range" <<
"1"
173 <<
"-i" << savedFilesMask;
175 const int lavfiOptionsIndex = additionalOptionsList.indexOf(
"-lavfi");
177 if ( lavfiOptionsIndex != -1 ) {
178 complexFilterArgs << additionalOptionsList.takeAt(lavfiOptionsIndex + 1);
180 additionalOptionsList.removeAt( lavfiOptionsIndex );
184 paletteArgs <<
"-r" << QString::number(options.
frameRate)
185 <<
"-start_number" << QString::number(sequenceStart) <<
"-start_number_range" <<
"1"
186 <<
"-i" << savedFilesMask;
188 const int paletteOptionsIndex = additionalOptionsList.indexOf(
"-palettegen");
189 QString palettegenString =
"palettegen";
191 if ( paletteOptionsIndex != -1 ) {
192 palettegenString = additionalOptionsList.takeAt(paletteOptionsIndex + 1);
194 additionalOptionsList.removeAt( paletteOptionsIndex );
198 paletteArgs <<
"-vf" << (exportDimensions +
"," + palettegenString );
200 paletteArgs <<
"-vf" << palettegenString;
203 paletteArgs <<
"-y" << palettePath;
206 ffmpegArgs <<
"-v" <<
"debug"
210 ffmpegSettings.
args = ffmpegArgs;
214 ffmpegSettings.
progressMessage = i18nc(
"Animation export dialog for palette exporting. arg1: file-suffix",
215 "Creating palette for %1 file format.",
"[suffix]");
216 ffmpegSettings.
logPath = QDir::tempPath() + QDir::separator() +
"krita" + QDir::separator() +
"ffmpeg.log";
220 if (!result.
isOk()) {
224 if (lavfiOptionsIndex == -1) {
225 complexFilterArgs <<
"[0:v][1:v] paletteuse";
228 args <<
"-i" << palettePath;
231 ffmpegWrapper->reset();
235 if (options.
includeAudio && audioFiles.count() > 0 && audioFiles.first().exists()) {
236 QFileInfo audioFileInfo = audioFiles.first();
237 const int msecPerFrame = (1000 / animation->
framerate());
238 const int msecStart = msecPerFrame * clipRange.
start();
239 const int msecDuration = msecPerFrame * clipRange.
duration();
241 const QTime startTime = QTime::fromMSecsSinceStartOfDay(msecStart);
242 const QTime durationTime = QTime::fromMSecsSinceStartOfDay(msecDuration);
243 const QString ffmpegTimeFormat = QStringLiteral(
"H:m:s.zzz");
245 args <<
"-ss" << QLocale::c().toString(startTime, ffmpegTimeFormat);
246 args <<
"-t" << QLocale::c().toString(durationTime, ffmpegTimeFormat);
247 args <<
"-i" << audioFileInfo.absoluteFilePath();
253 simpleFilterArgs << exportDimensions;
256 if ( !complexFilterArgs.isEmpty() ) {
257 args <<
"-lavfi" << (!simpleFilterArgs.isEmpty() ? simpleFilterArgs.join(
",").append(
"[0:v];"):
"") + complexFilterArgs.join(
";");
258 }
else if ( !simpleFilterArgs.isEmpty() ) {
259 args <<
"-vf" << simpleFilterArgs.join(
",");
262 args << additionalOptionsList;
264 dbgFile <<
"savedFilesMask" << savedFilesMask
265 <<
"save files offset" << sequenceStart
266 <<
"start" << QString::number(clipRange.
start())
267 <<
"duration" << clipRange.
duration();
272 ffmpegSettings.
args = args;
275 ffmpegSettings.
logPath = QDir::tempPath() + QDir::separator() +
"krita" + QDir::separator() +
"ffmpeg.log";
276 ffmpegSettings.
progressMessage = i18nc(
"Animation export dialog for tracking ffmpeg progress. arg1: file-suffix, arg2: progress frame number, arg3: totalFrameCount.",
277 "Creating desired %1 file: %2/%3 frames.",
"[suffix]",
"[progress]",
"[framecount]");
279 resultOuter = ffmpegWrapper->start(ffmpegSettings);