Node-Packages / video_processing.yaml
mypiper's picture
Update video_processing.yaml
54f838a verified
_id: video_processing
author: Anton Breslavskii | https://github.com/breslavsky
description: Using FFmpeg process videos
readme: Fix ffmpeg fluent
title: en=Video processing;ru=Работа с видео
url: https://huggingface.co/PiperMy/Node-Packages/resolve/main/video_processing.yaml
version: 3
nodes:
split_video_by_frames:
_id: split_video_by_frames
arrange:
x: 120
y: 120
category:
_id: video_processing
title: "title: en=Video processing;ru=Обработка видео"
environment: {}
inputs:
video:
order: 1
title: en=Video;ru=Видео
type: video
required: true
fps:
order: 2
title: en=Frame rate;ru=Частота кадров
type: integer
min: 1
max: 60
step: 1
default: 12
outputs:
frames:
title: en=Frames;ru=Кадры
type: image[]
package: video_processing
script: |-
export async function run({ inputs }) {
const { video, fps } = inputs;
const { FatalError, NextNode } = DEFINITIONS;
const ffmpeg = require('fluent-ffmpeg');
const path = require('path');
const fs = require('fs/promises');
const { fileTypeFromBuffer } = require('file-type');
const frames = [];
await useTempFolder(async (tmpFolder) => {
const { data } = await download(video);
const { ext } = await fileTypeFromBuffer(data);
const videoPath = path.join(tmpFolder, `source.${ext}`);
await fs.writeFile(videoPath, data);
await new Promise((resolve, reject) => {
ffmpeg(videoPath)
.outputOptions([
`-r ${fps || 12}`,
'-q:v 1'
])
.output(`${tmpFolder}/%05d.jpg`)
.on('start', (cmd) => console.log(cmd))
.on('end', () => resolve())
.on('error', (err) => reject(new FatalError(err)))
.run();
});
const files = await fs.readdir(tmpFolder);
for (const file of files) {
if (file.endsWith('jpg')) {
frames.push(await fs.readFile(path.join(tmpFolder, file)));
}
}
});
return NextNode.from({ outputs: { frames } });
}
source: catalog
title: en=Split video by frames;ru=Разбить видео по кадрам
version: 1
join_frames_to_video:
_id: join_frames_to_video
arrange:
x: 480
y: 120
category:
_id: video_processing
title: "title: en=Video processing;ru=Обработка видео"
execution: deferred
inputs:
frames:
order: 1
title: en=Frames;ru=Кадры
type: image[]
required: true
fps:
order: 2
title: en=Frame rate;ru=Частота кадров
type: integer
min: 1
max: 60
step: 1
default: 12
outputs:
video:
title: en=Video;ru=Видео
type: video
package: video_processing
script: |-
export async function run({ inputs }) {
const { frames, fps = 12 } = inputs;
const { FatalError, NextNode } = DEFINITIONS;
const ffmpeg = require('fluent-ffmpeg');
const path = require('path');
const fs = require('fs/promises');
let output;
await useTempFolder(async (tmpFolder) => {
const buffers = (await Promise.all(frames.map(frame => download(frame)))).map(({ data }) => data);
for (let i = 0; i < buffers.length; i++) {
const fileName = path.join(tmpFolder, `${String(i).padStart(5, '0')}.jpg`);
await fs.writeFile(fileName, buffers[i]);
}
const outputPath = path.join(tmpFolder, 'output.mp4');
await new Promise((resolve, reject) => {
ffmpeg()
.input(path.join(tmpFolder, '%05d.jpg'))
.inputFPS(fps)
.outputFPS(fps)
.outputOptions([
'-c:v libx264',
'-pix_fmt yuv420p',
'-crf 23'
])
.output(outputPath)
.on('start', cmd => console.log(cmd))
.on('end', resolve)
.on('error', err => reject(new FatalError(err)))
.run();
});
output = await fs.readFile(outputPath);
});
return NextNode.from({ outputs: { video: output } });
}
source: catalog
title: en=Join frames to video;ru=Собрать кадры в видео
version: 1