From ef90f77a1174c7283e89dfa374bf8b57949fb84c Mon Sep 17 00:00:00 2001 From: dakerboul Date: Mon, 10 Mar 2025 18:00:30 +0100 Subject: [PATCH] =?UTF-8?q?Refactor=20la=20fonction=20createVideoWithList?= =?UTF-8?q?=20pour=20simplifier=20la=20cr=C3=A9ation=20de=20vid=C3=A9os=20?= =?UTF-8?q?et=20mettre=20=C3=A0=20jour=20le=20statut=20de=20la=20vid=C3=A9?= =?UTF-8?q?o=20=C3=A0=20"completed"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/video/videoManager.js | 76 ++++++++++++++------------------------- 1 file changed, 26 insertions(+), 50 deletions(-) diff --git a/src/video/videoManager.js b/src/video/videoManager.js index 2336369..3ae042c 100644 --- a/src/video/videoManager.js +++ b/src/video/videoManager.js @@ -28,9 +28,13 @@ async function deleteVideoProject(videoId) { } async function createVideoWithList(projectId, pathList, duration, videoId) { - const workdir = path.join(PROJECTS_DIR, 'storage', `${projectId}`); - const tempFile = path.join(workdir, 'temp.txt'); + //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); @@ -41,72 +45,44 @@ async function createVideoWithList(projectId, pathList, duration, videoId) { 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 lastImageId = parseInt(path.basename(sortedImages[sortedImages.length - 1]).match(/\d+/)[0], 10); console.log('firstImageId:', firstImageId); 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')); 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`); - // Préparer les arguments pour ffmpeg - const ffmpegArgs = [ - '-r', frameRate.toString(), - '-f', 'concat', - '-safe', '0', - '-i', tempFile, - '-vsync', 'vfr', - '-pix_fmt', 'yuv420p', - outputVideo - ]; + // 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); + console.log('Video created successfully:', outputVideo); - console.log('Lancement de ffmpeg avec les arguments:', ffmpegArgs); - - // Lancer ffmpeg sans détachement - const child = spawn('ffmpeg', ffmpegArgs, { - cwd: workdir, - 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'); - }); + // Mettre à jour le statut de la vidéo à "completed" + const updateStatusQuery = 'UPDATE public.videos SET status = $2 WHERE id = $1 RETURNING *'; + const updateStatusValues = [videoId, 1]; // 1 pour le statut "completed" + const updateStatusRes = await db.query(updateStatusQuery, updateStatusValues); + console.log('Video status updated to completed:', updateStatusRes.rows[0]); return outputVideo; } catch (error) { console.error('Error creating video:', error); serverError.sendError(error); + } finally { + // Supprimer le fichier temporaire + if (fs.existsSync(tempFile)) { + fs.unlinkSync(tempFile); + console.log('Temporary file deleted:', tempFile); + } } }