polotno-node 2.9.37 → 2.9.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/video-parallel.js +32 -15
package/package.json
CHANGED
package/video-parallel.js
CHANGED
|
@@ -278,6 +278,8 @@ module.exports.jsonToVideo = async function jsonToVideo(
|
|
|
278
278
|
.outputOptions('-pix_fmt yuv420p')
|
|
279
279
|
.videoFilters('scale=trunc(iw/2)*2:trunc(ih/2)*2'); // Ensure dimensions are divisible by 2
|
|
280
280
|
|
|
281
|
+
const audioInputs = [];
|
|
282
|
+
|
|
281
283
|
// Add each audio segment as a separate input
|
|
282
284
|
inputs.forEach((input, index) => {
|
|
283
285
|
const inputStartSec = (input.inputStartTime / 1000).toFixed(3);
|
|
@@ -285,35 +287,50 @@ module.exports.jsonToVideo = async function jsonToVideo(
|
|
|
285
287
|
(input.inputEndTime - input.inputStartTime) /
|
|
286
288
|
1000
|
|
287
289
|
).toFixed(3);
|
|
288
|
-
const
|
|
290
|
+
const outputOffsetMs = Math.round(input.outputStartTime);
|
|
291
|
+
console.log({ outputOffsetMs });
|
|
289
292
|
const volume = input.volume !== undefined ? input.volume : 1;
|
|
290
293
|
|
|
291
|
-
// Apply `-itsoffset` before each input file to shift its audio stream
|
|
292
294
|
ffmpegCmd
|
|
293
|
-
.
|
|
294
|
-
.
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
295
|
+
.input(input.mp4File)
|
|
296
|
+
.inputOptions([`-ss ${inputStartSec}`, `-t ${inputDurationSec}`]);
|
|
297
|
+
|
|
298
|
+
audioInputs.push({
|
|
299
|
+
index: index + 1, // +1 because the first input is the image sequence
|
|
300
|
+
delay: outputOffsetMs,
|
|
301
|
+
volume: volume,
|
|
302
|
+
});
|
|
299
303
|
});
|
|
300
304
|
|
|
301
305
|
// Map the video stream from the image sequence
|
|
302
306
|
ffmpegCmd.outputOptions(['-map 0:v']);
|
|
303
307
|
|
|
304
|
-
//
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
+
// Prepare audio filter complex
|
|
309
|
+
if (audioInputs.length > 0) {
|
|
310
|
+
const audioFilters = audioInputs.map(
|
|
311
|
+
(input, i) =>
|
|
312
|
+
`[${input.index}:a]adelay=${input.delay}|${input.delay},volume=${input.volume}[a${i}]`
|
|
313
|
+
);
|
|
314
|
+
const audioMerge = audioInputs.map((_, i) => `[a${i}]`).join('');
|
|
315
|
+
const filterComplex = `${audioFilters.join(
|
|
316
|
+
';'
|
|
317
|
+
)};${audioMerge}amix=inputs=${
|
|
318
|
+
audioInputs.length
|
|
319
|
+
}:duration=longest[aout]`;
|
|
320
|
+
|
|
321
|
+
ffmpegCmd.complexFilter(filterComplex);
|
|
322
|
+
ffmpegCmd.outputOptions(['-map [aout]']);
|
|
323
|
+
}
|
|
308
324
|
|
|
309
325
|
ffmpegCmd
|
|
310
326
|
.format(format)
|
|
311
327
|
.audioCodec('aac')
|
|
328
|
+
.on('start', (command) => console.log('FFmpeg command:', command))
|
|
312
329
|
.on('end', () => resolve())
|
|
313
330
|
.on('error', (err, stdout, stderr) => {
|
|
314
|
-
console.
|
|
315
|
-
console.
|
|
316
|
-
console.
|
|
331
|
+
console.error('Error:', err.message);
|
|
332
|
+
console.error('stdout:', stdout);
|
|
333
|
+
console.error('stderr:', stderr);
|
|
317
334
|
reject(err);
|
|
318
335
|
})
|
|
319
336
|
.save(attrs.out);
|