Commit f56b21ab by ramdayalmunda

video generation code completed

parent 2a90ab81
module.exports.CONFIG = {
module.exports = {
PORT: process.env.PORT || 5000,
S3_ACCESS_KEY: process.env.S3_ACCESS_KEY,
S3_SECRET_KEY: process.env.S3_SECRET_KEY,
......
const { STATUS_CODE } = require("../helper/constants")
const { STATUS_CODE, TEMP_IMAGE_DIR, TEMP_VIDEO_DIR } = require("../helper/constants")
const { generateCanvas, mergeImages } = require("../helper/tutor-shot")
const path = require('path')
const sharp = require('sharp')
const fs = require('fs')
const { createVideoFromImages } = require("../helper/ffmpeg-helper")
const { deleteFile } = require("../helper/utilities")
const { generatePreSignedGetUrl } = require("../helper/upload")
module.exports.generateVideo = async function (req, res) {
console.log('generate Video', req.body)
console.log('generate Video')
try {
let tutorShotData = req.body.tutorShotData;
let videoPath = req.body.videoPath
let thumbnailPath = req.body.thumbnailPath
let fileName = req.body.fileName
let thumbnailName = req.body.thumbnailName
let videoPath; // local path of the video file
let thumbnailPath // local path of the thumbnail file
let fileName; // remote name of the final video file
let thumbnailName; // remote name of the final thumbnail
if (tutorShotData) {
console.log('got tutor-shot Data')
let imageDir = path.join(__dirname, '..', 'temporary', 'images')
let imageDir = TEMP_IMAGE_DIR
let imagePathString = path.join(imageDir, `${tutorShotData._id}_%d.png`)
videoPath = path.join(TEMP_VIDEO_DIR, `${tutorShotData._id}.mp4`)
console.log('videoPath', videoPath)
thumbnailPath = path.join(TEMP_IMAGE_DIR, `${tutorShotData._id}_thumbnail`)
fileName = tutorShotData._id
thumbnailName = `${tutorShotData._id}_thumbnail`
// // this is to generate each individual images and get their buffers
let frameNumber = 1;
let imageArr = []
for (let i = 0; i < tutorShotData.segments.length; i++) {
console.log(i, 'tutor-shot', tutorShotData.segments[i])
if (tutorShotData.segments[i].imageUrl) tutorShotData.segments[i].signedImageUrl = await generatePreSignedGetUrl(tutorShotData.segments[i].imageUrl)
// if (tutorShotData.segments[i].thumbnailUrl) tutorShotData.segments[i].signedThumbnailUrl = await generatePreSignedGetUrl(tutorShotData.segments[i].thumbnailUrl)
let CE = generateCanvas(tutorShotData.segments[i], { dimension: tutorShotData.segments[i].dimension })
......@@ -34,27 +43,36 @@ module.exports.generateVideo = async function (req, res) {
{ buffer: await CE.getBuffer() }
],
{
// outputType: "buffer",
return: "Buffer",
outputType: "buffer",
}
)
console.log('mergin image completed')
let limit = 24 * ((tutorShotData.segments[i]?.duration) ? (tutorShotData.segments[i].duration) : 2);
let frameNum = 0
let firstImage = path.join(imageDir, `${tutorShotData._id}_${frameNumber++}.png`)
await sharp(mergedImage).toFile(firstImage)
imageArr.push(firstImage)
do {
let fileName = path.join(imageDir, `${tutorShotData._id}_${frameNumber++}.png`)
imageArr.push(fileName)
await sharp(mergedImage).toFile(fileName)
fs.copyFileSync(firstImage, fileName)
console.log('image generated', fileName)
} while (++frameNum < limit)
if (i == 0 && thumbnailPath) {
const imageBase64 = Buffer.from(mergedImage, 'base64'); // Replace 'your_image_buffer_data_here' with your actual image buffer data
// Write the buffer data to the file
await fs.writeFile(thumbnailPath, imageBase64);
fs.copyFileSync(firstImage, thumbnailPath)
console.log('thumbnail generated')
}
}
console.log('---ALL images generated', videoPath)
console.log('___BEFORE__')
console.log('outputFilePath', path.parse(videoPath))
console.log('outputFileName', path.dirname(videoPath).name)
console.log('__CONFIGURED___')
let options = {
outputFilePath: path.dirname(videoPath),
outputFileName: path.parse(videoPath).name,
......@@ -63,23 +81,26 @@ module.exports.generateVideo = async function (req, res) {
imagePathString: imagePathString,
deleteImages: true,// default is true
}
console.log('to create Video from image')
await createVideoFromImages([], options)
console.log('Video from images Created')
// to delete the individual frames that were generated and the thumbnail
!(async function () {
deleteFile(imageArr)
})()
return videoPath
// !(async function () {
// deleteFile(imageArr)
// })()
// return videoPath
}
let remotePath = path.join(CONFIG.S3_PATH.TUTOR_SHOT, fileName)
let remoteThumbnailPath = path.join(CONFIG.S3_PATH.TUTOR_SHOT, thumbnailName)
await uploadToAwsS3(videoPath, remotePath)
await uploadToAwsS3(thumbnailPath, remoteThumbnailPath)
// let remotePath = path.join(CONFIG.S3_PATH.TUTOR_SHOT, fileName)
// let remoteThumbnailPath = path.join(CONFIG.S3_PATH.TUTOR_SHOT, thumbnailName)
// await uploadToAwsS3(videoPath, remotePath)
// await uploadToAwsS3(thumbnailPath, remoteThumbnailPath)
res.status(STATUS_CODE.OK).json()
} catch (err) {
console.log(err)
console.log('------ERROR:GENERATING VIDEO',err)
res.status(STATUS_CODE.ERROR).json()
}
}
\ No newline at end of file
const path = require('path')
module.exports.STATUS_CODE = {
OK: 200,
NOT_FOUND: 400,
ERROR: 500
}
module.exports.TEMP_IMAGE_DIR = path.join(__dirname, '..', 'temporary', 'image');
module.exports.TEMP_VIDEO_DIR = path.join(__dirname, '..', 'temporary', 'video');
module.exports.TEMP_AUDIO_DIR = path.join(__dirname, '..', 'temporary', 'audio');
\ No newline at end of file
......@@ -27,6 +27,10 @@ const path = require('path')
module.exports.createVideoFromImages = async function (imageArr, options) {
return new Promise(async (res, rej) => {
console.log('createVideoFromImages')
console.log('imageArr', imageArr)
console.log('options', options)
let frameRate = options?.frameRate ? options.frameRate : 24
let tempImageDir = path.join(__dirname, '..', 'temporary', 'images')
let outputFilePath = path.join(options.outputFilePath, `${options.outputFileName}.${options.outputFormat}`)
......@@ -40,6 +44,7 @@ module.exports.createVideoFromImages = async function (imageArr, options) {
imagePathString = path.join(tempImageDir, `${options.outputFileName}_%d.png`)
////// to create temporary image files //////
for (let i = 0; i < imageArr.length; i++) {
console.log('looping image arr')
if (imageArr[i].filePath) {
let limit = imageArr[i]?.duration ? imageArr[i].duration : 1
limit = limit * frameRate
......@@ -55,8 +60,13 @@ module.exports.createVideoFromImages = async function (imageArr, options) {
}
////// using ffmpeg creating video //////
console.log('ffmpeg config')
console.log('imagePathString', imagePathString)
console.log('outputFilePath', outputFilePath)
console.log('frameRate', frameRate)
ffmpeg()
.on('end', () => {
console.log('VIDEO END')
res(path.join(options.outputFilePath, `${options.outputFileName}.${options.outputFormat}`))
////// to delete the frames that are created //////
......
......@@ -31,6 +31,7 @@ module.exports.mergeImages = async function (imageArr, options) {
compositeArr.push({ input: await nextSharp.toBuffer() })
}
imageSharp.composite(compositeArr)
await imageSharp.toFile('/var/www/BeGenieUs/begenieus-jobs/temporary/image/temp-1.png')
if (options.outputType == 'buffer') return imageSharp.toBuffer()
if (options.outputType == 'file' && options.outputFile) {
await imageSharp.toFile(options.outputFile)
......
const Fs = require('fs');
const AWS = require('aws-sdk');
const CONFIG = require('../config');
AWS.config.update({
accessKeyId: CONFIG.S3_ACCESS_KEY,
......@@ -41,3 +42,13 @@ module.exports.uploadToAwsS3 = async function (localPath, remotePath, options) {
return { status: httpStatus.NETWORK_ERROR, path: remotePath }
}
}
module.exports.generatePreSignedGetUrl = async function (fileName) {
return await new Promise((resolve, reject) => {
s3.getSignedUrl('getObject', {
Key: fileName,
}, (err, url) => {
resolve(url); // successful response
});
})
}
\ No newline at end of file
const express = require('express')
const CONFIG = require('./config.js')
console.log('CONFIG', CONFIG)
const PORT = CONFIG.PORT;
const app = express()
app.use( express.json() )
app.use( require("./routes/tutor-shot") )
app.use( '/tutor-shot',require("./routes/tutor-shot") )
app.listen( PORT, ()=>{
console.log(`BeGenieUs jobs running on http://localhost:${PORT}`)
......
......@@ -4,17 +4,19 @@
"description": "",
"main": "index.js",
"scripts": {
"start": "node index.js"
"start": "node index.js",
"dev": "pm2 restart ../jobs.config.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"aws-sdk": "^2.1570.0",
"axios": "^1.6.7",
"canvas": "^2.11.2",
"express": "^4.18.3",
"fluent-ffmpeg": "^2.1.2",
"mongoose": "^8.2.0",
"sharp": "^0.33.2"
"mongoose": "^8.2.1",
"sharp": "^0.32.1"
}
}
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