Reputation: 456
I'm trying to split a number of .mp4
videos into .jpg
images.
The set up is using electron-react-app
. I have used a preload
script to enable access to limited functions with the React components.
Problem: Unable to serially execute the call to execFile()
on an array of video file names. The first video file is being successfully converted but can't get the remaining videos to convert despite using promises
.
Function in pre-load script (accessed in React component):
const ffmpeg = require("ffmpeg-static-electron")
const { execFile } = require("child_process");
...
{split: (tempReviewFolderPath, filename) => {
execFile(`${ffmpeg.path}`, [
"-i",
`${path.join(tempReviewFolderPath, filename)}`,
"-vf",
"fps=3",
`${path.join(tempReviewFolderPath, "image-%d.jpg")}`,
]),
(error, stdout, stderr) => {
if (error) {
console.log(error);
} else {
console.log(stdout, stderr);
}
};
}
}
React
component:
tempReviewFolderPath
is the filepath
to the folder contaning the videos.
filenamesArray
is an array containing video filename strings.
"main_process:video_to_split"
is the channel used in electron ipc
which takes (channel, callback) as args.
useEffect(() => {
("main_process:video_to_split",
({ tempReviewFolderPath, filenamesArray }) => {
try {
Promise.all(
filenamesArray.map((filename) => {
return new Promise((resolve) => {
preLoad.split(tempReviewFolderPath, filename);
resolve(filename);
});
})
).catch(console.error);
} catch (error) {
console.log(error);
}
})
}, []}
This only splits the first video.
I've also tried:-
pre-load script
const execFile = require("util").promisify(require("child_process").execFile);
{split: async (tempReviewFolderPath, filename) => {
await execFile(`${ffmpeg.path}`, [
"-i",
`${path.join(tempReviewFolderPath, filename)}`,
"-vf",
"fps=3",
`${path.join(tempReviewFolderPath, "image-%d.jpg")}`,
]),
(error, stdout, stderr) => {
if (error) {
console.log(error);
} else {
console.log(stdout, stderr);
}
};
}
}
React
component:
useEffect(() => {
("main_process:video_to_split",
( tempReviewFolderPath, filenamesArray }) => {
try {
preLoad.split(tempReviewFolderPath, filename);
} catch (error) {
console.log(error);
}
})
}, []}
Lastly (out of desperation) :
useEffect(() => {
("main_process:video_to_split",
({ tempReviewFolderPath, filenamesArray }) => {
let filename1 = filenamesArray[0];
let filename2 = filenamesArray[1];
try {
preLoad.split(tempReviewFolderPath, filename1);
preLoad.split(tempReviewFolderPath, filename2);
} catch (error) {
console.log(error);
}
}
)
Again, same problem - only the first video is split.
What am I doing wrong ?
Many thanks.
Upvotes: 0
Views: 225
Reputation: 456
Found solution:
Problem related to "image-%d.jpg" which was simply being overwritten on each iteration by map.
Solution: just added index and changed function.
filenamesArray.map((filename, index) => {
return new Promise((res, rej) => {
api_link.split(tempReviewFolderPath, filename, index);
res(filename);
});
});
Upvotes: 1