Commit 2a90ab81 by ramdayalmunda

transfered and adjucted code from server to jobs

parent e2e52f84
node_modules/ node_modules/
\ No newline at end of file temporary/
logs/
\ No newline at end of file
module.exports.CONFIG = {
PORT: process.env.PORT || 5000,
S3_ACCESS_KEY: process.env.S3_ACCESS_KEY,
S3_SECRET_KEY: process.env.S3_SECRET_KEY,
S3_BUCKET_NAME: process.env.S3_BUCKET_NAME,
S3_REGION: process.env.S3_REGION,
}
\ No newline at end of file
const { STATUS_CODE } = require("../helper/constants") const { STATUS_CODE } = 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")
module.exports.generateVideo = async function(req, res){ module.exports.generateVideo = async function (req, res) {
console.log('generate Video', req.body) console.log('generate Video', req.body)
try{
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
if (tutorShotData) {
let imageDir = path.join(__dirname, '..', 'temporary', 'images')
let imagePathString = path.join(imageDir, `${tutorShotData._id}_%d.png`)
// // 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++) {
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 })
let mergedImage = await mergeImages(
[
{ url: tutorShotData.segments[i].signedImageUrl },
{ buffer: await CE.getBuffer() }
],
{
// outputType: "buffer",
return: "Buffer",
}
)
let limit = 24 * ((tutorShotData.segments[i]?.duration) ? (tutorShotData.segments[i].duration) : 2);
let frameNum = 0
do {
let fileName = path.join(imageDir, `${tutorShotData._id}_${frameNumber++}.png`)
imageArr.push(fileName)
await sharp(mergedImage).toFile(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);
}
}
let options = {
outputFilePath: path.dirname(videoPath),
outputFileName: path.parse(videoPath).name,
outputFormat: path.extname(videoPath).slice(1),
frameRate: 24,
imagePathString: imagePathString,
deleteImages: true,// default is true
}
await createVideoFromImages([], options)
// to delete the individual frames that were generated and the thumbnail
!(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)
res.status(STATUS_CODE.OK).json() res.status(STATUS_CODE.OK).json()
}catch(err){ } catch (err) {
console.log(err) console.log(err)
res.status(STATUS_CODE.ERROR).json() res.status(STATUS_CODE.ERROR).json()
} }
......
const sharp = require('sharp')
const ffmpeg = require('fluent-ffmpeg')
const fs = require('fs')
const path = require('path')
/**
*
* @param {[
* {
* filePath: 'String: path of the file you want',
* buffer: 'Buffer: buffer of the file you want',
* 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
*/
module.exports.createVideoFromImages = async function (imageArr, options) {
return new Promise(async (res, rej) => {
let frameRate = options?.frameRate ? options.frameRate : 24
let tempImageDir = path.join(__dirname, '..', 'temporary', 'images')
let outputFilePath = path.join(options.outputFilePath, `${options.outputFileName}.${options.outputFormat}`)
let imagePathString = options?.imagePathString
let deleteImages = (options && options?.hasOwnProperty('deleteImages')) ? (!!options.deleteImages) : true
let frameNumber = 1
let frames = []
if (!imagePathString) { // if the path is not generated then generate the path
imagePathString = path.join(tempImageDir, `${options.outputFileName}_%d.png`)
////// to create temporary image files //////
for (let i = 0; i < imageArr.length; i++) {
if (imageArr[i].filePath) {
let limit = imageArr[i]?.duration ? imageArr[i].duration : 1
limit = limit * frameRate
let frameNum = 0
do {
let newFilePath = path.join(tempImageDir, `${options.outputFileName}_${frameNumber++}.png`)
await sharp(imageArr[i].filePath).toFile(newFilePath)
frames.push(newFilePath)
} while (++frameNum < limit)
}
}
}
////// using ffmpeg creating video //////
ffmpeg()
.on('end', () => {
res(path.join(options.outputFilePath, `${options.outputFileName}.${options.outputFormat}`))
////// to delete the frames that are created //////
if (deleteImages)
frames.forEach((filePath) => {
fs.access(filePath, fs.constants.F_OK, (err) => {
if (!err) {
// File exists, proceed with deletion
fs.unlink(filePath, (err) => {
if (err) { console.error(`Error deleting ${filePath}:`, err); }
});
};
});
});
})
.on('error', (err) => {
console.error('Error creating video:', err);
rej(undefined, err)
})
.input(imagePathString)
.output(outputFilePath)
.outputFPS(frameRate) // Set frames per second as needed
.run();
})
}
module.exports.joinAudioVideo = async function (videoPath, audioPath, output) {
return new Promise((res, rej) => {
console.log('videoPath', videoPath)
console.log('audioPath', audioPath)
console.log('output', output)
ffmpeg()
.on('end', () => {
res(output)
})
.on('error', (err) => {
rej(err)
})
.input(videoPath)
.input(audioPath)
.output(output)
.run()
})
}
\ No newline at end of file
const CanvasEditor = require("./canvas-editor.js");
const sharp = require('sharp')
const axios = require('axios')
module.exports.generateCanvas = function (segmentData, options) {
let CE = new CanvasEditor()
CE.mount(options)
for (let i = 0; i < segmentData.object.length; i++) {
CE.addElement(segmentData.object[i])
}
return CE
}
module.exports.mergeImages = async function (imageArr, options) {
let imageSharp;
if (imageArr[0].url) {
let { data } = await axios.get(imageArr[0].url, { responseType: 'arraybuffer' });
imageSharp = sharp(Buffer.from(data))
delete data
}
let compositeArr = []
for (let i = 1; i < imageArr.length; i++) {
let nextSharp;
if (imageArr[i].url) {
let { data } = await axios.get(imageArr[i].url, { responseType: 'arraybuffer' });
nextSharp = sharp(Buffer.from(data))
delete data
} else if (imageArr[i].buffer) {
nextSharp = sharp(imageArr[i].buffer)
}
compositeArr.push({ input: await nextSharp.toBuffer() })
}
imageSharp.composite(compositeArr)
if (options.outputType == 'buffer') return imageSharp.toBuffer()
if (options.outputType == 'file' && options.outputFile) {
await imageSharp.toFile(options.outputFile)
return options.outputFile
}
return imageSharp
}
\ No newline at end of file
const Fs = require('fs');
const AWS = require('aws-sdk');
AWS.config.update({
accessKeyId: CONFIG.S3_ACCESS_KEY,
secretAccessKey: CONFIG.S3_SECRET_KEY,
});
const s3 = new AWS.S3({
params: { Bucket: CONFIG.S3_BUCKET_NAME, },
region: CONFIG.S3_REGION,
})
module.exports.uploadToAwsS3 = async function (localPath, remotePath, options) {
const buffer = Fs.readFileSync(localPath);
try {
var params = {
Body: buffer,
Bucket: CONFIG.S3_BUCKET_NAME,
Key: remotePath
};
s3.putObject(params, function (err, data) {
if (err) {
errorLog.error(err, `Exception handling error on uploadToAwsS3`);
}
// successful response
});
if (options && !options.preventUnlink) {
try { Fs.unlinkSync(localPath) }
catch (err) { console.log(err) }
}
return
} catch (error) {
errorLog.error(error, `error occur while uploading data to s3`);
return { status: httpStatus.NETWORK_ERROR, path: remotePath }
}
}
\ No newline at end of file
const fs = require('fs')
module.exports.createDirectory = function (directory) {
fs.mkdir(directory, { recursive: true }, (err) => {
if (err) {
console.error(`Error creating directory: ${err}`);
} else {
console.log(`Directory created successfully at: ${directory}`);
}
});
}
module.exports.deleteFile = function (item) {
function deleteFileByPath(path) {
fs.unlink(path, (err) => { if (err) console.log(err) })
}
if (typeof item == 'string') {
deleteFileByPath(item)
} else if (Array.isArray(item)) {
for (let i = 0; i < item.length; i++) {
if (typeof item[i] == 'string') deleteFileByPath(item[i])
}
}
return
}
const express = require('express') const express = require('express')
const PORT = process.env.PORT || 5000; const CONFIG = require('./config.js')
console.log('CONFIG', CONFIG)
const PORT = CONFIG.PORT;
const app = express()
const app = express()
app.use( require("./routes/tutor-shot") ) app.use( require("./routes/tutor-shot") )
......
...@@ -10,7 +10,11 @@ ...@@ -10,7 +10,11 @@
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"axios": "^1.6.7",
"canvas": "^2.11.2",
"express": "^4.18.3", "express": "^4.18.3",
"mongoose": "^8.2.0" "fluent-ffmpeg": "^2.1.2",
"mongoose": "^8.2.0",
"sharp": "^0.33.2"
} }
} }
const path = require('path');
const tutorShotController = require("../controller/tutor-shot") const tutorShotController = require("../controller/tutor-shot")
const { createDirectory } = require("../helper/utilities")
const router = new require('express').Router() const router = new require('express').Router()
router.post("/generate", tutorShotController.generateVideo) router.post("/generate", tutorShotController.generateVideo)
createDirectory( path.join(__dirname, '..', 'temporary', 'image') )
createDirectory( path.join(__dirname, '..', 'temporary', 'video') )
createDirectory( path.join(__dirname, '..', 'temporary', 'audio') )
module.exports = router module.exports = router
\ No newline at end of file
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