Skip to content

Commit

Permalink
feat : add function to download and add image in video
Browse files Browse the repository at this point in the history
  • Loading branch information
ChetanXpro committed Aug 15, 2023
1 parent a98c3b2 commit 2b3473c
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 78 deletions.
17 changes: 17 additions & 0 deletions src/images/downloadImages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import axios from 'axios'
import fs from 'fs'
export const downloadImages = async (queries: any) => {
for (const query of queries) {
const name = query.timestamp.split('->')[0].trim()
const { data } = await axios.get(`https://api.unsplash.com/search/photos?query=${query.Query}&page=1`, {
headers: {
Authorization: `Client-ID ${process.env.UNSPLASH_ACCESS_KEY}`,
},
})
const url = data.results[0].urls.thumb
const response = await axios.get(url, {
responseType: 'stream',
})
await response.data.pipe(fs.createWriteStream(`${name}.jpg`))
}
}
81 changes: 18 additions & 63 deletions src/images/imagesProccessing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,40 @@ const configuration = new Configuration({
})
const openai = new OpenAIApi(configuration)

export const imageProccessing = async ({ language, topic }: { language?: string; topic?: string }) => {
export const imageProccessing = async ({
language,
topic,
queries,
}: {
language?: string
topic?: string
queries: any
}) => {
const inputVideoPath = '/home/chetan/code/ts-content-gpt/tryyyyyyyyy.mp4'
const inputImagePath = '/home/chetan/code/ts-content-gpt/oo.jpg'
const outputVideoPath = '/home/chetan/code/ts-content-gpt/yyooooooo.mp4'
const targetTimestamp = '00:00:10.000'

const queries = [
{ Query: 'Great Wall of China', timestamp: '1 -> 3' },
{ Query: 'longest wall in the world', timestamp: '5 -> 8' },
// { Query: 'Ming Dynasty', timestamp: '7 -> 8' },
// { Query: 'Chinese Empire', timestamp: '11 -> 12' },
// { Query: 'brick, tamperth, and stone', timestamp: '17 -> 18' },
]

interface IQuery {
Query: string
timestamp: string
}
let filter = ''
queries.forEach((query: IQuery, index) => {
queries.forEach((query: IQuery, index: any) => {
const currIndex = index + 1
const prevIndex = index
const totalQuery = queries.length
const lastIndex = index === totalQuery - 1

const [startingTime, endTime] = query.timestamp.split('->')
if (index === 0) {
filter += ` -filter_complex "[${prevIndex}:v][${currIndex}:v]overlay=25:25:enable='between(t,${startingTime.trim()},${endTime.trim()})'[v${currIndex}];[v${currIndex}]`
let imgPath = ''

queries.forEach((query: IQuery, index: any) => {
imgPath += ' -i ' + `/home/chetan/code/ts-content-gpt/${query.timestamp.split('->')[0].trim()}.jpg`
})

filter += `${imgPath} -filter_complex "[${prevIndex}:v][${currIndex}:v]overlay=25:25:enable='between(t,${startingTime.trim()},${endTime.trim()})'[v${currIndex}];[v${currIndex}]`
return
}

Expand All @@ -58,66 +64,15 @@ export const imageProccessing = async ({ language, topic }: { language?: string;

// console.log('filter: ', filter)

const mainFilter = `${path} -i ${inputVideoPath} -i ${inputImagePath} -i ${inputImagePath} ${filter} -map "[v]" -map 0:a -c:v libx264 -c:a copy ${outputVideoPath} `
const mainFilter = `${path} -i ${inputVideoPath} ${filter} -map "[v]" -map 0:a -c:v libx264 -c:a copy ${outputVideoPath} `

console.log('mainFilter: ', mainFilter)

const ll = `${path} -i ${inputVideoPath} -i ${inputVideoPath} -i ${inputImagePath} -filter_complex "[0:v][1:v]overlay=25:25:enable='between(t,1 , 2)'[v1];[v1][2:v]overlay=25:25:enable='between(t,3 , 4)'[v2];[v2]format=yuv420p[v]" -map "[v]" -map 0:a -c:v libx264 -c:a copy /home/chetan/code/ts-content-gpt/yyooooooo.mp4`

// const command = `${path} -i ${inputVideoPath} -i ${inputImagePath} -filter_complex "[0:v][1:v] overlay=25:25:enable='between(t,0,10)'" -pix_fmt yuv420p -c:a copy ${outputVideoPath}`
// const command = `${path} -i ${inputVideoPath} -i ${inputImagePath} -filter_complex "[1:v]scale=-1:100[ovrl];[0:v][ovrl]overlay=x=W-w-10:y=10:enable='between(t,${targetTimestamp},T)'[out]" -map "[out]" -map 0:a -c:v libx264 -c:a copy ${outputVideoPath}`
// const i = `[0:v][1:v]overlay=25:25:enable='between(t,1 , 2)'[v1]; [v1][2:v]overlay=25:25:enable='between(t,3 , 4)'[v2]; [v2]format=yuv420p[v]" -map "[v]" -map 0:a -c:v libx264 -c:a copy /home/chetan/code/ts-content-gpt/yyooooooo.mp4`
// const command = `${path} -i ${inputVideoPath} -i ${inputImagePath} -i ${inputImagePath} -filter_complex "[0:v][1:v]overlay=25:25:enable='between(t,0,10)'[v1]; [v1][2:v]overlay=50:50:enable='between(t,15,20)'[v2]; [v2]format=yuv420p[v]" -map "[v]" -map 0:a -c:v libx264 -c:a copy ${outputVideoPath}`
// const command = `${path} -i ${inputVideoPath} -i ${inputImagePath} -i ${inputImagePath} -i ${inputImagePath} -filter_complex " [0:v][1:v]overlay=25:25:enable='between(t,0,10)'[v1];[v1] [2:v]overlay=50:50:enable='between(t,13,20)'[v2]; [v2][3:v]overlay=75:75:enable='between(t,23,30)'[v3]; [v3]format=yuv420p[v]" -map "[v]" -map 0:a -c:v libx264 -c:a copy ${outputVideoPath}`

// const command = `${path} -i ${inputVideoPath} -i ${inputImagePath} -i ${inputImagePath} -i ${inputImagePath} -i ${inputImagePath} -i ${inputImagePath} -filter_complex "[0:v][1:v]overlay=25:25:enable='between(t,0,5)'[v1];[v1][2:v]overlay=50:50:enable='between(t,7,13)'[v2];[v2][3:v]overlay=75:75:enable='between(t,12,16)'[v3];[v3][4:v]overlay=100:100:enable='between(t,18,22)'[v4];[v4][5:v]overlay=125:125:enable='between(t,24,26)'[v5];[v5]format=yuv420p[v]" -map "[v]" -map 0:a -c:v libx264 -c:a copy ${outputVideoPath}`

exec(mainFilter, (err, stdout, stderr) => {
if (err) {
console.error(err)
// console.log('stderr: ', stderr)
}
// console.log(stdout)
})

return
ffmpeg()
.input(inputVideoPath)
.input(inputImagePath)
.complexFilter([
{
filter: 'setpts',
options: `PTS-STARTPTS+(gte(T,${targetTimestamp})*(${targetTimestamp}-PTS/TB))`,
outputs: 'timestamped',
},
{
filter: 'overlay',
options: {
x: 'W-w-10',
y: '10',
},
inputs: ['timestamped', '1'], // Use the 'timestamped' output from the previous filter and the image input
outputs: 'out',
},
])
.outputOptions('-map', '[out]')
.outputOptions('-c:v', 'libx264')
.output(outputVideoPath)
.on('end', () => {
console.log('Image overlay complete!')
})
.on('error', err => {
console.error(err)
})
.run()

return
fs.readFile('/home/chetan/code/ts-content-gpt/basicaudio.wav.srt', 'utf8', async function (err, data) {
if (err) throw err
const chatCompletion = await openai.createChatCompletion({
model: 'gpt-3.5-turbo',
messages: [{ role: 'system', content: tryy(data) }],
})
console.log('chatCompletion: ', chatCompletion.data.choices[0].message)
})
}
58 changes: 44 additions & 14 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { mergeAudio } from './video/video'
import { uploadVideos } from './upoad/upload'
import uploadFile from './upoad/azureUpload'
import { imageProccessing } from './images/imagesProccessing'
import { downloadImages } from './images/downloadImages'
import { getImageQuerys } from './Editing/getImageQuerys'
const inputFilePath = path.join(__dirname, '..', 'basicaudio.mp3')

const outputFilePath = path.join(__dirname, '..', 'basicaudio.wav')
Expand All @@ -23,27 +25,36 @@ const outputVideoFilePath = path.join(__dirname, '..', 'shorts', 'ytshort.mp4')

const generateYoutubeShort = async (language: string, topic: string) => {
try {
const script = await createShortScript({ language: language, topic: topic })
// const script = await createShortScript({ language: language, topic: topic })

console.log('SCRIPT GENERATED: ', script)
// console.log('SCRIPT GENERATED: ', script)

if (!script) throw new Error('Script not generated')
// if (!script) throw new Error('Script not generated')

await createAudio({ script, language, outputFilePath: inputFilePath })
// await createAudio({ script, language, outputFilePath: inputFilePath })

console.log('AUDIO GENERATED SUCCESSFULLY', 'basicaudio.mp3')
// console.log('AUDIO GENERATED SUCCESSFULLY', 'basicaudio.mp3')

await convertToWav(inputFilePath, outputFilePath)
// await convertToWav(inputFilePath, outputFilePath)

await whisper(outputFilePath)
// await whisper(outputFilePath)

console.log('MERGING AUDIO AND VIDEO')
// console.log('MERGING AUDIO AND VIDEO')

// await mergeAudio({
// videoFilePath,
// audioFilePath: outputFilePath,
// outputVideoPath: outputVideoFilePath,
// })

const queries = await getImageQuerys()

console.log('QUERIES: ', queries)

await downloadImages(queries)

await imageProccessing({ language: '', queries })

await mergeAudio({
videoFilePath,
audioFilePath: outputFilePath,
outputVideoPath: outputVideoFilePath,
})
return
// uploadVideos('facts', 'facts', ['#facts', '#trending', '#shorts'], outputVideoFilePath)
uploadFile('videos', Math.random() + 'new.mp4', outputVideoFilePath).catch(console.error)
Expand All @@ -60,7 +71,26 @@ const generateYoutubeShort = async (language: string, topic: string) => {

// app.use(express.json())

imageProccessing({ language: '' })
generateYoutubeShort('english', 'indian fact')

const queries = [
{ Query: 'Great Wall of China', timestamp: '1 -> 3' },
{ Query: 'Chinese Empire', timestamp: '11 -> 12' },
// { Query: 'Ming Dynasty', timestamp: '7 -> 8' },
// { Query: 'Chinese Empire', timestamp: '11 -> 12' },
// { Query: 'brick, tamperth, and stone', timestamp: '17 -> 18' },
]

// mergeAudio({
// videoFilePath,
// audioFilePath: outputFilePath,
// outputVideoPath: outputVideoFilePath,
// })

// imageProccessing({ language: '', queries })

// downloadImages(queries)

// app.post('/generate', async (req, res) => {
// try {
// const { language, topic } = req.body
Expand Down
4 changes: 3 additions & 1 deletion src/promptTemplates/image.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@ export const tryy = (
timestamp: string
) => `this is a timestamp for my video , i am using a api to fetch images , so based on this given timetamp you have to give me 5 best query by which i can fetch images also you have to send on what time i have to show that image ,
Time is in formet of hh:mm:ss,ms --> hh:mm:ss,ms , so you only have to return seconds part of timestamp , for example if timestamp is 00:00:10,000 --> 00:00:15,000 , you only have to return 10 -> 15 , so i can show image between 10 to 15 seconds of video
Make sure that you only return good querys , so that it will be easy to find image for that
specifications delimited by angle brackets .
TIMESTAMP: <${timestamp}>
### OUTPUT
You will output in parsable JSON object , all these json will be in a array.
make sure to return only seconds in timestamp like 5 -> 10 ,24 -> 30 etc
[{"Query":"...","timestamp":".. -> .."}]`

0 comments on commit 2b3473c

Please sign in to comment.