Commit 5e21b37a by Pragati Upadhyay

profile model change

parent 453e5c9a
...@@ -42,7 +42,7 @@ module.exports.generateVideo = async function (req, res) { ...@@ -42,7 +42,7 @@ module.exports.generateVideo = async function (req, res) {
let imageDir = TEMP_IMAGE_DIR let imageDir = TEMP_IMAGE_DIR
let imagePathString = path.join(imageDir, `${tutorShotData._id}_%d.png`) let imagePathString = path.join(imageDir, `${tutorShotData._id}_%d.png`)
videoPath = path.join(TEMP_VIDEO_DIR, `${tutorShotData._id}.mp4`) videoPath = path.join(TEMP_VIDEO_DIR, `${tutorShotData._id}.webm`)
thumbnailPath = path.join(TEMP_IMAGE_DIR, `${tutorShotData._id}_thumbnail`) thumbnailPath = path.join(TEMP_IMAGE_DIR, `${tutorShotData._id}_thumbnail`)
fileName = `${tutorShotData._id}.webm` fileName = `${tutorShotData._id}.webm`
thumbnailName = `${tutorShotData._id}_thumbnail.png` thumbnailName = `${tutorShotData._id}_thumbnail.png`
...@@ -146,7 +146,6 @@ module.exports.generateVideo = async function (req, res) { ...@@ -146,7 +146,6 @@ module.exports.generateVideo = async function (req, res) {
socketPayload.percent = 100 socketPayload.percent = 100
socketPayload.complete = true socketPayload.complete = true
socket.emit("videoGenerationProgress", socketPayload) socket.emit("videoGenerationProgress", socketPayload)
console.log("socketon")
console.log('---Tutor-shot-generated----', tutorShotData?._id) console.log('---Tutor-shot-generated----', tutorShotData?._id)
} }
......
const sharp = require('sharp') const ffmpeg = require('fluent-ffmpeg');
const ffmpeg = require('fluent-ffmpeg') const fs = require('fs');
const fs = require('fs') const path = require('path');
const path = require('path') const sharp = require('sharp');
/** /**
* *
* @param {[ * @param {string} imagePath - Path to the image file
* { * @param {number} duration - Duration in seconds to display the image
* filePath: 'String: path of the file you want', * @param {string} outputClipPath - Path to the output clip file
* buffer: 'Buffer: buffer of the file you want', * @param {function} callback - Callback function
* duration: 'Number: duration in seconds, how long you want the image to be displayed',
* }
* ]} imageArr
* @param {
* {
* outputFileName: "String: name of the video file, without extension; (required)",
* outputFormat: "String: mp4 (required)",
* frameRate: "Number: frames per second; (required, default: 1)",
* imagePathString: "String: path to the individual frames: ex:'/path/test-video_%d.png'",
* deleteImages: "Boolean: to delete the individual frames from the disk; (default: true)",
* outputFilePath: "String: path to the directory where the video would be generated",
* }
* } options
* @returns
*/ */
function createClipFromImage(imagePath, duration, outputClipPath, callback) { function createClipFromImage(imagePath, duration, outputClipPath, callback) {
ffmpeg(imagePath) ffmpeg(imagePath)
...@@ -30,10 +16,11 @@ function createClipFromImage(imagePath, duration, outputClipPath, callback) { ...@@ -30,10 +16,11 @@ function createClipFromImage(imagePath, duration, outputClipPath, callback) {
.inputOptions(`-t ${duration}`) .inputOptions(`-t ${duration}`)
.inputOptions('-framerate 1') .inputOptions('-framerate 1')
.outputOptions([ .outputOptions([
'-c:v libx264', // Use H.264 codec '-c:v libvpx', // Use VP8 codec for video
// '-pix_fmt yuv420p', // Pixel format compatible with most devices '-b:v 1M', // Bitrate for video
'-crf 23', // Constant Rate Factor that balances quality and file size '-crf 10', // Constant Rate Factor for quality
'-preset veryfast' // Faster encoding with reasonable file size '-auto-alt-ref 0', // VP8 option to disable alternate reference frames
'-c:a libvorbis' // Use Vorbis codec for audio
]) ])
.output(outputClipPath) .output(outputClipPath)
.on('end', () => { .on('end', () => {
...@@ -50,10 +37,10 @@ function concatenateClips(clips, outputPath, callback) { ...@@ -50,10 +37,10 @@ function concatenateClips(clips, outputPath, callback) {
const fileList = 'filelist.txt'; const fileList = 'filelist.txt';
const fileContent = clips.map(clip => `file '${clip}'`).join('\n'); const fileContent = clips.map(clip => `file '${clip}'`).join('\n');
fs.writeFileSync(fileList, fileContent); fs.writeFileSync(fileList, fileContent);
console.log("created", outputPath, 'x' ) console.log("created", outputPath, 'x' );
ffmpeg() ffmpeg()
.input(fileList) .input(fileList)
.inputOptions(['-f concat','-safe 0']) // Corrected input options .inputOptions(['-f concat', '-safe 0']) // Corrected input options
.outputOptions('-c copy') .outputOptions('-c copy')
.output(outputPath) .output(outputPath)
.on('end', () => { .on('end', () => {
...@@ -69,7 +56,6 @@ function concatenateClips(clips, outputPath, callback) { ...@@ -69,7 +56,6 @@ function concatenateClips(clips, outputPath, callback) {
.run(); .run();
} }
module.exports.createVideo = async function (screenshots, outputPath) { module.exports.createVideo = async function (screenshots, outputPath) {
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
const clips = []; const clips = [];
...@@ -78,7 +64,7 @@ module.exports.createVideo = async function (screenshots, outputPath) { ...@@ -78,7 +64,7 @@ module.exports.createVideo = async function (screenshots, outputPath) {
for (let index = 0; index < screenshots.length; index++) { for (let index = 0; index < screenshots.length; index++) {
const screenshot = screenshots[index]; const screenshot = screenshots[index];
const duration = screenshot.duration || 3; const duration = screenshot.duration || 3;
const clipPath = `clip${index}.mp4`; // Temporary clip path const clipPath = `clip${index}.webm`; // Temporary clip path
const clip = await createClipFromImageAsync(screenshot, duration, clipPath); const clip = await createClipFromImageAsync(screenshot, duration, clipPath);
clips.push(clip); clips.push(clip);
...@@ -119,42 +105,36 @@ function concatenateClipsAsync(clips, outputPath) { ...@@ -119,42 +105,36 @@ function concatenateClipsAsync(clips, outputPath) {
}); });
} }
module.exports.createVideoFromImages = async function (imageArr, options) {
module.exports.createVideoFromImages = async function (imageArr,options) {
return new Promise(async (res, rej) => { return new Promise(async (res, rej) => {
let frameRate = options?.frameRate ? options.frameRate : 24;
let frameRate = options?.frameRate ? options.frameRate : 24 let tempImageDir = path.join(__dirname, '..', 'temporary', 'images');
let tempImageDir = path.join(__dirname, '..', 'temporary', 'images') let outputFilePath = path.join(options.outputFilePath, `${options.outputFileName}.${options.outputFormat}`);
let outputFilePath = path.join(options.outputFilePath, `${options.outputFileName}.${options.outputFormat}`) let imagePathString = options?.imagePathString;
let imagePathString = options?.imagePathString let deleteImages = (options && options?.hasOwnProperty('deleteImages')) ? (!!options.deleteImages) : true;
let deleteImages = (options && options?.hasOwnProperty('deleteImages')) ? (!!options.deleteImages) : true
let frameNumber = 1;
let frames = [];
let frameNumber = 1
let frames = []
if (!imagePathString) { // if the path is not generated then generate the path if (!imagePathString) { // if the path is not generated then generate the path
imagePathString = path.join(tempImageDir, `${options.outputFileName}_%d.png`) imagePathString = path.join(tempImageDir, `${options.outputFileName}_%d.png`);
////// to create temporary image files ////// ////// to create temporary image files //////
for (let i = 0; i < imageArr.length; i++) { for (let i = 0; i < imageArr.length; i++) {
if (imageArr[i].filePath) { if (imageArr[i].filePath) {
let limit = imageArr[i]?.duration ? imageArr[i].duration : 1 let limit = imageArr[i]?.duration ? imageArr[i].duration : 1;
limit = limit * frameRate limit = limit * frameRate;
let frameNum = 0 let frameNum = 0;
do { do {
let newFilePath = path.join(tempImageDir, `${options.outputFileName}_${frameNumber++}.png`) let newFilePath = path.join(tempImageDir, `${options.outputFileName}_${frameNumber++}.png`);
await sharp(imageArr[i].filePath).toFile(newFilePath) await sharp(imageArr[i].filePath).toFile(newFilePath);
frames.push(newFilePath) frames.push(newFilePath);
} while (++frameNum < limit);
} while (++frameNum < limit)
} }
} }
} }
////// using ffmpeg creating video ////// ////// using ffmpeg creating video //////
ffmpeg() ffmpeg()
.on('end', () => { .on('end', () => {
res(path.join(options.outputFilePath, `${options.outputFileName}.${options.outputFormat}`)) res(path.join(options.outputFilePath, `${options.outputFileName}.${options.outputFormat}`));
////// to delete the frames that are created ////// ////// to delete the frames that are created //////
if (deleteImages) if (deleteImages)
...@@ -168,20 +148,17 @@ module.exports.createVideoFromImages = async function (imageArr,options) { ...@@ -168,20 +148,17 @@ module.exports.createVideoFromImages = async function (imageArr,options) {
}; };
}); });
}); });
}) })
.on('error', (err) => { .on('error', (err) => {
console.error('Error creating video:', err); console.error('Error creating video:', err);
rej(undefined, err) rej(undefined, err);
}) })
// .videoFilters('format=yuv420p')
.input(imagePathString) .input(imagePathString)
.outputOptions('-c:v libvpx', '-b:v 1M', '-crf 10', '-auto-alt-ref 0', '-c:a libvorbis') // Added correct codecs
.output(outputFilePath) .output(outputFilePath)
.outputFPS(frameRate) // Set frames per second as needed .outputFPS(frameRate) // Set frames per second as needed
.run(); .run();
});
})
} }
module.exports.joinAudioVideo = async function (videoPath, audioPath, output) { module.exports.joinAudioVideo = async function (videoPath, audioPath, output) {
...@@ -191,11 +168,11 @@ module.exports.joinAudioVideo = async function (videoPath, audioPath, output) { ...@@ -191,11 +168,11 @@ module.exports.joinAudioVideo = async function (videoPath, audioPath, output) {
.input(audioPath) .input(audioPath)
.output(output) .output(output)
.on('end', () => { .on('end', () => {
res(output) res(output);
}) })
.on('error', (err) => { .on('error', (err) => {
rej(err) rej(err);
})
.run()
}) })
.run();
});
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment