video generation working

This commit is contained in:
Quentin Roussel
2024-08-18 14:26:06 +08:00
parent 074bcf20d7
commit abaf134c28
6 changed files with 66 additions and 9 deletions

2
.dockerignore Normal file
View File

@@ -0,0 +1,2 @@
node_modules/
node_modules/*

3
.gitignore vendored
View File

@@ -1 +1,2 @@
images/*.png
images/**/*.png
**/*.mp4

View File

@@ -30,7 +30,7 @@ function downloadImage(time_string, filepath) {
"Sec-Fetch-Dest": "image",
"Sec-Fetch-Mode": "no-cors",
"Sec-Fetch-Site": "same-origin",
"Priority": "u=5, i",
"Priority": "i",
"Pragma": "no-cache",
"Cache-Control": "no-cache",
"TE": "trailers",
@@ -61,12 +61,12 @@ function downloadImage(time_string, filepath) {
}
export async function initImages(count) {
let files = fs.readdirSync('images/');
let files = fs.readdirSync('images/raw');
let downloaded = 0;
let i = 0;
while(downloaded < count) {
let time_string = getTimeString(i);
let filename = `images/${time_string}.png`;
let filename = `images/raw/${time_string}.png`;
if (files.includes(`${time_string}.png`)) {
downloaded++;
i++;
@@ -90,7 +90,7 @@ export async function updateImages(count) {
for (let i = count; i >= 0; i--) {
time_strings.push(getTimeString(i));
}
let files = fs.readdirSync('images/');
let files = fs.readdirSync('images/raw');
let image_count = files.length;
let updated = false;
@@ -99,12 +99,11 @@ export async function updateImages(count) {
for (let time_string of time_strings) {
if (!files.includes(`${time_string}.png`)) {
try {
await downloadImage(time_string, `images/${time_string}.png`);
await downloadImage(time_string, `images/raw/${time_string}.png`);
updated = true;
image_count++;
} catch (error) {
console.log("No more images available");
break;
console.log("Skipped image " + time_string);
}
}
}
@@ -112,7 +111,7 @@ export async function updateImages(count) {
//Remove old files
for (let file of files.sort().slice(0, image_count - count)) {
console.log(`Deleting ${file}`);
fs.unlinkSync(`images/${file}`);
fs.unlinkSync(`images/raw/${file}`);
}
return updated;

View File

@@ -1,9 +1,14 @@
import { initImages, updateImages } from './downloader.mjs';
import { createVideo } from './video.mjs';
const IMAGE_COUNT = 5;
initImages(IMAGE_COUNT).then(() => {
console.log('Downloaded initial images successfully');
createVideo().then(() => {
console.log('Generated final images successfully');
});
});
setInterval(() => {

View File

50
video.mjs Normal file
View File

@@ -0,0 +1,50 @@
import { createCanvas, loadImage } from 'canvas';
import fs from 'fs';
import { exec } from 'child_process';
async function overlayImage(time_string) {
let ctx = createCanvas(853, 479).getContext('2d');
let bg = await loadImage('bg.png')
ctx.drawImage(bg, 0, 0, 853, 479)
let overlay = await loadImage('images/raw/' + time_string + '.png')
ctx.drawImage(overlay, 0, 0, 853, 479)
let text = time_string.substring(8, 10) + ':' + time_string.substring(10, 12);
ctx.font = 'bold 70px sans-serif';
ctx.fillStyle = 'rgba(0,0,0,0.7)';
ctx.fillText(text, 853 - 250, 479 - 40);
return ctx.canvas.toBuffer("image/png");
}
async function generateFinalImages() {
//Clear out the final images directory
let final_files = fs.readdirSync('images/final');
for (let file of final_files) {
fs.unlinkSync(`images/final/${file}`);
}
let files = fs.readdirSync('images/raw');
let i = 0;
for (let file of files) {
let time_string = file.split('.')[0];
let final_image = await overlayImage(time_string);
fs.writeFileSync(`images/final/${i}.png`, final_image);
i++;
}
}
export async function createVideo() {
await generateFinalImages();
//run the command ffmpeg -framerate 5 -i %d.png -c:v libx264 -r 30 output.mp4
return new Promise((resolve, reject) => {
exec('ffmpeg -framerate 5 -i images/final/%d.png -c:v libx264 -r 30 images/output.mp4', (err, stdout, stderr) => {
if (err) {
reject(err);
return;
}
resolve(stdout);
});
});
}