
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
Convert your videos into an animated Scratch project!
Instead of the naiive method of assigning each frame of a video to a costume, each costume contains many frames, arranged in a grid (default of 30x30). This allows the PNG or JPEG compression to work between more frames (partially interframe compression) rather than per frame (intraframe compression).
Frames are instead displayed as a spritesheet.
To be able to cram more photos per spritesheet and improve overall compression, as well as reduce the number of bitmaps Scratch needs to load, frames that look similar to the immediate previous frame will be discarded, and will be repeated in the video player.
npm i -g svideo
svideo -i input.mp4 -o output.sb3
Options:
--help Show help [boolean]
--version Show version number [boolean]
--rows, --row The number of rows to place in the grid [number] [default: 10]
--columns, --col The number of columns to place in the grid [number] [default: 10]
-i, --input Input file to convert [string] [required]
-o, --output Destination file for the Scratch `.sb3` archive [string] [required]
-w, --width The width of each frame [number] [default: 480]
-t, --temporaryFolder Path to a temporary folder for use while building the project [string] [default: "temp/"]
-f, --imageFileFormat The file format of frames in the output [choices: "jpg", "png"] [default: "jpg"]
-r, --frameRate The framerate of the output [number]
-q, --compressionLevel The compression level of the image. 1-100 for PNG and 1-32 for JPEG [number]
-a, --audioInterval The number of seconds between cuts in the audio [number] [default: No cuts]
-s, --subtitles Hardcode (burn) subtitles onto the video [string]
--videoFilters, --vf Additional video filters to pass to FFMPEG, such as crop [string]
--backgroundColour, --colour Set the colour of the padded region around the video [string] [default: "black"]
--startPosition, --ss Seek to a start position [string]
--endPosition, --to Stop at an end position [string]
You can interface with svideo with the application programming interface instead if you wish. Comments for each method will be included at a later date. (or if someone does it before I do)
yarn add svideonpm i --save svideo// ES6 Import Statements
import svideo from "svideo";
// Not ES6 Require Statement
// const svideo = require("svideo");
// Create a new SVideo Application
const app = new svideo.App();
(async () => {
// Set the input file
await app.setFile("wooper.mp4");
// Set the subtitles file
app.setSubtitlesFile("wooper.en.vtt");
// Set the output file
app.setOutputFile("wooper.sb3");
// Print information
console.log(app.toString());
// Convert and commit changes
await app.convert();
})();
import { existsSync, readdirSync, renameSync } from "fs";
import { resolve, parse } from "path";
import SVideo from "../dist/index.js";
const videos = readdirSync("tv")
.map((file) => parse(file))
.filter((video) => [".mp4", ".webm", ".mkv"].includes(video.ext))
.sort((a, b) => parseInt(a.name, 10) - parseInt(b.name, 10))
.map((video) => {
const videoPath = resolve("tv", video.base);
const subtitlePath = resolve("tv", video.name + ".vtt");
let subtitle;
if (!existsSync(videoPath)) throw new Error("Cannot find " + videoPath);
if (!existsSync(subtitlePath)) {
console.log("Cannot find " + subtitlePath);
} else {
subtitle = "tv/" + video.name + ".vtt";
}
return {
name: video.name,
folder: resolve("tv"),
video: videoPath,
subtitle,
};
});
console.log(videos);
for (const video of videos) {
const converter = new SVideo.App();
console.log(video);
converter.setTempFolder();
await converter.setFile(video.video);
if (video.subtitle) converter.setSubtitlesFile(video.subtitle);
converter.setWidth(480);
converter.setColumns(20);
converter.setRows(10);
converter.setOutputFile(
resolve(
video.folder,
`이달의소녀탐구 #${video.name} (LOONA TV #${video.name}).sb3`
)
);
console.log(converter.toString());
await converter.convert();
}
This project is licenced under the MIT licence. Because it's MIT Scratch. Haha.
FAQs
Convert your videos into an animated Scratch project!
We found that svideo demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.