Create video_processing.yaml
Browse files- video_processing.yaml +81 -0
video_processing.yaml
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
_id: video_processing
|
| 2 |
+
title: en=Video processing;ru=Работа с видео
|
| 3 |
+
description: Using FFmpeg process videos
|
| 4 |
+
version: 1
|
| 5 |
+
url: https://huggingface.co/PiperMy/Node-Packages/resolve/main/video_processing.yaml
|
| 6 |
+
readme: ""
|
| 7 |
+
nodes:
|
| 8 |
+
split_video_by_frames:
|
| 9 |
+
_id: split_video_by_frames
|
| 10 |
+
arrange:
|
| 11 |
+
x: 280
|
| 12 |
+
y: 110
|
| 13 |
+
category:
|
| 14 |
+
id: split_video_by_frames
|
| 15 |
+
title: en=Video processing;ru=Обработка видео
|
| 16 |
+
costs: ""
|
| 17 |
+
environment: {}
|
| 18 |
+
inputs:
|
| 19 |
+
video:
|
| 20 |
+
order: 1
|
| 21 |
+
title: Source video
|
| 22 |
+
type: video
|
| 23 |
+
required: true
|
| 24 |
+
fps:
|
| 25 |
+
order: 2
|
| 26 |
+
title: Frame rate
|
| 27 |
+
type: integer
|
| 28 |
+
min: 1
|
| 29 |
+
max: 60
|
| 30 |
+
step: 1
|
| 31 |
+
default: 12
|
| 32 |
+
outputs:
|
| 33 |
+
frames:
|
| 34 |
+
title: Frames
|
| 35 |
+
type: image[]
|
| 36 |
+
package: video_processing
|
| 37 |
+
script: |-
|
| 38 |
+
const ffmpeg = require('fluent-ffmpeg');
|
| 39 |
+
const path = require('path');
|
| 40 |
+
const fs = require('fs/promises');
|
| 41 |
+
const { fileTypeFromBuffer } = require('file-type');
|
| 42 |
+
|
| 43 |
+
(async () => {
|
| 44 |
+
const { video, fps } = inputs;
|
| 45 |
+
|
| 46 |
+
const frames = [];
|
| 47 |
+
|
| 48 |
+
await useTempFolder(async (tmpFolder) => {
|
| 49 |
+
|
| 50 |
+
const { data } = await download(video);
|
| 51 |
+
const { ext } = await fileTypeFromBuffer(data);
|
| 52 |
+
const videoPath = path.join(tmpFolder, `source.${ext}`);
|
| 53 |
+
await fs.writeFile(videoPath, data);
|
| 54 |
+
|
| 55 |
+
await new Promise((resolve, reject) => {
|
| 56 |
+
ffmpeg(videoPath)
|
| 57 |
+
.outputOptions([
|
| 58 |
+
`-r ${fps || 12}`,
|
| 59 |
+
'-q:v 1'
|
| 60 |
+
])
|
| 61 |
+
.output(`${tmpFolder}/%05d.jpg`)
|
| 62 |
+
.on('start', (cmd) => log(cmd))
|
| 63 |
+
.on('end', () => resolve())
|
| 64 |
+
.on('error', (err) => reject(err))
|
| 65 |
+
.run();
|
| 66 |
+
});
|
| 67 |
+
|
| 68 |
+
const files = await fs.readdir(tmpFolder);
|
| 69 |
+
for (const file of files) {
|
| 70 |
+
if (file.endsWith('jpg')) {
|
| 71 |
+
frames.push(await fs.readFile(path.join(tmpFolder, file)));
|
| 72 |
+
}
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
});
|
| 76 |
+
|
| 77 |
+
return next({outputs: { frames }});
|
| 78 |
+
})();
|
| 79 |
+
source: catalog
|
| 80 |
+
title: en=Split video by frames;ru=Разбить видео по кадрам
|
| 81 |
+
version: 6
|