Last active
July 19, 2023 11:53
-
-
Save makinori/93e5ebcd04d9226f63113630c83eebdf to your computer and use it in GitHub Desktop.
Upscale anime videos with Real CUGAN
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// download https://github.com/nihui/realcugan-ncnn-vulkan | |
// place this script in the same directory | |
// run `zx upscale-video.js` | |
const inputVideo = "palutenas-revolting-dinner-1.mp4"; | |
const outputVideo = "palutenas-revolting-dinner-1-x4.mp4"; | |
const scale = 4; // upscale ratio (1/2/3/4, default=2) | |
const noiseLevel = -1; // denoise level (-1/0/1/2/3, default=-1) | |
// note: upscaling palutena's revolting dinner 240p x4 with denoising will | |
// somewhat ruin the output. its probably not noisy, just really low res | |
async function cleanup(makeFolders) { | |
await fs.remove("tmp-input"); | |
await fs.remove("tmp-output"); | |
await fs.remove("tmp-in.txt"); | |
if (makeFolders) { | |
await fs.mkdirp("tmp-input"); | |
await fs.mkdirp("tmp-output"); | |
} | |
} | |
(async () => { | |
await cleanup(true); | |
// get fps | |
const fps = Number( | |
(await $`ffprobe.exe ${inputVideo}`).stderr.match( | |
/ ([0-9]+(?:\.[0-9]+)?) fps,/, | |
)[1], | |
); | |
const frameTime = fps / 1000; | |
if (Number.isNaN(fps)) throw new Error("Failed to get fps"); | |
// convert video to frames | |
await $`ffmpeg.exe -i ${inputVideo} tmp-input/%d.png`; | |
// upscale frames | |
await $`./realcugan-ncnn-vulkan.exe -i tmp-input -o tmp-output -s ${scale} -n ${noiseLevel}`; | |
// convert frames into video | |
const ffmpegInput = (await fs.readdir("tmp-output")) | |
.map(n => Number(n.replace(/[^0-9]/g, ""))) | |
.sort((a, b) => a - b) | |
.map(n => "file 'tmp-output/" + n + ".png'\nduration " + frameTime) | |
.join("\n"); | |
await fs.writeFile("tmp-in.txt", ffmpegInput); | |
// re-encode web compatible | |
await $`ffmpeg.exe -y -f concat -safe 0 -i tmp-in.txt -vf "settb=AVTB,setpts=N/${fps}/TB,fps=${fps}" -c:v libx264 -pix_fmt yuv420p -profile:v baseline -level 3 -preset medium -crf 21 tmp-${outputVideo}`; | |
// concat audio | |
// await $`ffmpeg.exe -y -i ${inputVideo} -i tmp-${outputVideo} -c copy -map 1:v:0 -map 0:a:0 ${outputVideo}`; | |
await $`ffmpeg.exe -y -i ${inputVideo} -i tmp-${outputVideo} -c:v copy -map 1:v:0 -map 0:a:0 -c:a aac ${outputVideo}`; | |
// cleanup | |
await fs.remove(`tmp-${outputVideo}`); | |
await cleanup(false); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment