Modifier la fonction createVideoWithList pour utiliser spawn au lieu de execSync pour l'exécution de ffmpeg en arrière-plan

This commit is contained in:
2025-03-10 17:31:11 +01:00
parent 848c50bf33
commit 7baac5dcb7

View File

@@ -1,6 +1,6 @@
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const { spawn } = require('child_process');
const serverError = require('../../utils/serverError');
const db = require('../../db');
@@ -28,13 +28,9 @@ async function deleteVideoProject(videoId) {
}
async function createVideoWithList(projectId, pathList, duration) {
//pathList étant la liste des chemins déjà triés
const tempFile = path.join('temp.txt');
try {
// Trouver tous les fichiers image pour le projet donné
const workdir = path.join(PROJECTS_DIR, 'storage', `${projectId}`);
const dir = path.join(PROJECTS_DIR, 'storage', `${projectId}`, 'images');
console.log('dir:', dir);
const images = pathList;
console.log('images:', images);
@@ -45,38 +41,50 @@ async function createVideoWithList(projectId, pathList, duration) {
return numA - numB;
});
// En déduire l'id de la première et dernière image utilisée
// Déterminer l'id de la première et la dernière image utilisée
const firstImageId = parseInt(path.basename(sortedImages[0]).match(/\d+/)[0], 10);
const lastImageId = parseInt(path.basename(sortedImages[sortedImages.length - 1]).match(/\d+/)[0], 10);
console.log('firstImageId:', firstImageId);
console.log('lastImageId:', lastImageId);
// Créer un fichier temporaire pour la liste des images
// Créer le fichier temporaire pour la liste des images
fs.writeFileSync(tempFile, sortedImages.map(image => `file '${image}'`).join('\n'));
const frameRate = Math.ceil(sortedImages.length / parseInt(duration));
// le fichier final prend cette forme : {projectId}_{firstImageId}_{lastImageId}-{timestamp}.mp4
const timestamp = new Date().getTime();
const outputVideo = path.join(workdir, `${projectId}_${firstImageId}_${lastImageId}-${timestamp}.mp4`);
// Commande ffmpeg pour créer la vidéo
const ffmpegCommand = `ffmpeg -r ${frameRate} -f concat -safe 0 -i ${tempFile} -vsync vfr -pix_fmt yuv420p ${outputVideo}`;
console.log('Running ffmpeg command:', ffmpegCommand);
try {
execSync(ffmpegCommand, { stdio: 'ignore', detached: true });
console.log('Video creation started in background:', outputVideo);
} catch (error) {
console.error('ffmpeg command failed:', error);
serverError.sendError(error);
}
// Préparer les arguments pour ffmpeg
const ffmpegArgs = [
'-r', frameRate.toString(),
'-f', 'concat',
'-safe', '0',
'-i', tempFile,
'-vsync', 'vfr',
'-pix_fmt', 'yuv420p',
outputVideo
];
console.log('Lancement de ffmpeg en arrière-plan avec les arguments:', ffmpegArgs);
// Lancer ffmpeg en mode détaché
const child = spawn('ffmpeg', ffmpegArgs, {
detached: true,
stdio: 'ignore'
});
// Permettre au processus ffmpeg de continuer même si le parent se termine
child.unref();
console.log('Video creation started in background:', outputVideo);
return outputVideo;
} catch (error) {
console.error('Error creating video:', error);
serverError.sendError(error);
} finally {
// Supprimer le fichier temporaire
// Attention : supprimer le fichier temporaire immédiatement pourrait poser problème
// si ffmpeg n'a pas encore fini de le lire. Envisagez un délai ou un mécanisme de nettoyage
if (fs.existsSync(tempFile)) {
fs.unlinkSync(tempFile);
console.log('Temporary file deleted:', tempFile);
@@ -117,7 +125,7 @@ async function createVideo(projectId) {
// Commande ffmpeg pour créer la vidéo
const ffmpegCommand = `ffmpeg -r ${frameRate} -f concat -safe 0 -i ${tempFile} -vsync vfr -pix_fmt yuv420p ${outputVideo}`;
console.log('Running ffmpeg command:', ffmpegCommand);
execSync(ffmpegCommand);
spawn(ffmpegCommand);
console.log('Video created successfully:', outputVideo);
} catch (error) {
console.error('Error creating video:', error);