Refactor la fonction createVideoWithList pour simplifier la création de vidéos et mettre à jour le statut de la vidéo à "completed"

This commit is contained in:
2025-03-10 18:00:30 +01:00
parent e38718b1fa
commit ef90f77a11

View File

@@ -28,9 +28,13 @@ async function deleteVideoProject(videoId) {
} }
async function createVideoWithList(projectId, pathList, duration, videoId) { async function createVideoWithList(projectId, pathList, duration, videoId) {
const workdir = path.join(PROJECTS_DIR, 'storage', `${projectId}`); //pathList étant la liste des chemins déjà triés
const tempFile = path.join(workdir, 'temp.txt'); const tempFile = path.join('temp.txt');
try { 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; const images = pathList;
console.log('images:', images); console.log('images:', images);
@@ -41,72 +45,44 @@ async function createVideoWithList(projectId, pathList, duration, videoId) {
return numA - numB; return numA - numB;
}); });
// Déterminer l'id de la première et de la dernière image utilisée // En déduire l'id de la première et dernière image utilisée
const firstImageId = parseInt(path.basename(sortedImages[0]).match(/\d+/)[0], 10); const firstImageId = parseInt(path.basename(sortedImages[0]).match(/\d+/)[0], 10);
const lastImageId = parseInt(path.basename(sortedImages[sortedImages.length - 1]).match(/\d+/)[0], 10); const lastImageId = parseInt(path.basename(sortedImages[sortedImages.length - 1]).match(/\d+/)[0], 10);
console.log('firstImageId:', firstImageId); console.log('firstImageId:', firstImageId);
console.log('lastImageId:', lastImageId); console.log('lastImageId:', lastImageId);
// Créer le fichier temporaire pour la liste des images // Créer un fichier temporaire pour la liste des images
fs.writeFileSync(tempFile, sortedImages.map(image => `file '${image}'`).join('\n')); fs.writeFileSync(tempFile, sortedImages.map(image => `file '${image}'`).join('\n'));
const frameRate = Math.ceil(sortedImages.length / parseInt(duration)); 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 timestamp = new Date().getTime();
const outputVideo = path.join(workdir, `${projectId}_${firstImageId}_${lastImageId}-${timestamp}.mp4`); const outputVideo = path.join(workdir, `${projectId}_${firstImageId}_${lastImageId}-${timestamp}.mp4`);
// Préparer les arguments pour ffmpeg // Commande ffmpeg pour créer la vidéo
const ffmpegArgs = [ const ffmpegCommand = `ffmpeg -r ${frameRate} -f concat -safe 0 -i ${tempFile} -vsync vfr -pix_fmt yuv420p ${outputVideo}`;
'-r', frameRate.toString(), console.log('Running ffmpeg command:', ffmpegCommand);
'-f', 'concat', execSync(ffmpegCommand);
'-safe', '0', console.log('Video created successfully:', outputVideo);
'-i', tempFile,
'-vsync', 'vfr',
'-pix_fmt', 'yuv420p',
outputVideo
];
console.log('Lancement de ffmpeg avec les arguments:', ffmpegArgs); // Mettre à jour le statut de la vidéo à "completed"
const updateStatusQuery = 'UPDATE public.videos SET status = $2 WHERE id = $1 RETURNING *';
// Lancer ffmpeg sans détachement const updateStatusValues = [videoId, 1]; // 1 pour le statut "completed"
const child = spawn('ffmpeg', ffmpegArgs, { const updateStatusRes = await db.query(updateStatusQuery, updateStatusValues);
cwd: workdir, console.log('Video status updated to completed:', updateStatusRes.rows[0]);
detached: false,
stdio: 'pipe'
});
// Afficher les logs de ffmpeg
child.stdout.on('data', (data) => {
console.log(`ffmpeg stdout: ${data}`);
});
child.stderr.on('data', (data) => {
console.error(`ffmpeg stderr: ${data}`);
});
child.on('close', (code) => {
console.log(`ffmpeg process exited with code ${code}`);
// Vous pouvez ici gérer la suppression du fichier temporaire
if (fs.existsSync(tempFile)) {
fs.unlinkSync(tempFile);
console.log('Temporary file deleted:', tempFile);
}
});
console.log('Video creation started:', outputVideo);
// Mettre à jour le statut de la vidéo dans la base de données
const query = 'UPDATE public.videos SET status = 1 WHERE id = $1';
db.query(query, [videoId], (err, results) => {
if (err) {
return serverError.sendError('Error updating video status:', res, err);
}
console.log('Video status updated:', results.rows ? results.rows[0] : 'Aucune ligne retournée');
});
return outputVideo; return outputVideo;
} catch (error) { } catch (error) {
console.error('Error creating video:', error); console.error('Error creating video:', error);
serverError.sendError(error); serverError.sendError(error);
} finally {
// Supprimer le fichier temporaire
if (fs.existsSync(tempFile)) {
fs.unlinkSync(tempFile);
console.log('Temporary file deleted:', tempFile);
}
} }
} }