rohring-video-generator v0.0.62
Rohring Video Generator
Rohring Video Generator is a React-based package that converts uploaded images into an MP4 video using FFmpeg. The processed video can be downloaded as an MP4 file.
Features
- Upload multiple images to generate a slideshow video.
- Automatic resizing of images to fit within a 1920x1080 resolution.
- Adds custom text descriptions to each image.
- Uses FFmpeg for video processing in the browser.
- Generates a downloadable MP4 video.
Getting Started
Prerequisites
Ensure you have Node.js installed on your system. The following dependencies are required:
@ffmpeg/ffmpeg
for handling video generation.file-saver
for downloading the generated video.framer-motion
for animations (if used in the UI).
Installation
Clone the repository and install dependencies:
git clone https://github.com/webteamrohring/rohr-video-generator
cd rohr-video-generator
npm install
Usage
Download and Use the Package in Any Application
To install the package, run:
npm install rohring-video-generator
Available Scripts
npm start
Runs the package in development mode.
npm test
Launches the test runner.
npm run build
Builds the package for production.
How It Works
- The user uploads images along with optional text descriptions.
- Images are resized to a maximum resolution of 1920x1080.
- Each image is placed on a black background with the text description below.
- Images are processed using FFmpeg and stored in its virtual filesystem.
- FFmpeg executes commands to generate a video slideshow.
- The generated video is available for download as an MP4 file.
Video Generation Process
- Load FFmpeg and initialize the virtual filesystem.
- Resize images while maintaining their aspect ratio.
- Overlay text descriptions at the bottom of each image.
- Store images as PNG files in FFmpeg's memory.
- Generate a video using the following FFmpeg command:
ffmpeg -framerate 0.5 -start_number 0 -i img%d.png -vf "scale='min(1080,iw)':'min(1024,ih)',pad=1080:1024:(1080-iw)/2:(1024-ih)/2:black" -c:v libx264 -pix_fmt yuv420p -r 30 output.mp4
- Read and download the generated MP4 file.
Example Code
import { FFmpeg } from "@ffmpeg/ffmpeg";
import { saveAs } from "file-saver";
export async function generateVideoFromImages(images, descriptions, setLoading) {
if (images.length === 0) {
alert("Please upload images first.");
return;
}
setLoading(true);
const ffmpeg = new FFmpeg();
await ffmpeg.load();
for (let i = 0; i < images.length; i++) {
const img = await createImageBitmap(images[i]);
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const maxWidth = 1920;
const maxHeight = 1080;
const textHeight = 200;
let width = img.width;
let height = img.height;
if (width > maxWidth || height > maxHeight) {
const scaleFactor = Math.min(maxWidth / width, maxHeight / height);
width = Math.floor(width * scaleFactor);
height = Math.floor(height * scaleFactor);
}
canvas.width = width;
canvas.height = height + textHeight;
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0, width, height);
ctx.font = "30px Arial";
ctx.fillStyle = "white";
ctx.textAlign = "center";
const textWidth = Math.min(800, canvas.width - 40);
const words = (descriptions[i] || "").split(" ");
let line = "";
const lines = [];
const lineHeight = 24;
for (let word of words) {
let testLine = line + word + " ";
let metrics = ctx.measureText(testLine);
if (metrics.width > textWidth) {
lines.push(line);
line = word + " ";
} else {
line = testLine;
}
}
lines.push(line);
const textYStart = height + (textHeight - lines.length * lineHeight) / 2;
lines.forEach((line, index) => {
ctx.fillText(line, canvas.width / 2, textYStart + index * lineHeight);
});
const resizedBlob = await new Promise((resolve) =>
canvas.toBlob(resolve, "image/png")
);
const fileData = await resizedBlob.arrayBuffer();
ffmpeg.writeFile(`img${i}.png`, new Uint8Array(fileData));
}
await ffmpeg.exec([
"-framerate", "0.5",
"-start_number", "0",
"-i", "img%d.png",
"-vf", "scale='min(1080,iw)':'min(1024,ih)',pad=1080:1024:(1080-iw)/2:(1024-ih)/2:black",
"-c:v", "libx264",
"-pix_fmt", "yuv420p",
"-r", "30",
"output.mp4",
]);
const data = await ffmpeg.readFile("output.mp4");
const fileName = new Date().toISOString().replace(/[:.]/g, "-") + ".mp4";
const videoBlob = new Blob([data.buffer], { type: "video/mp4" });
saveAs(videoBlob, fileName);
setLoading(false);
}
License
This project is licensed under the MIT License.
Author
Eric Ramos
Repository
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago