File size: 4,993 Bytes
3890c2b
8b74733
c58c466
 
 
8b74733
54f838a
3890c2b
 
 
 
c58c466
 
3890c2b
c58c466
 
3890c2b
 
 
 
c58c466
3890c2b
 
 
 
c58c466
3890c2b
 
 
 
 
 
 
c58c466
3890c2b
 
 
8b74733
 
3890c2b
8b74733
 
 
 
 
3890c2b
8b74733
3890c2b
8b74733
 
 
 
 
 
3890c2b
8b74733
 
 
 
 
 
 
 
 
 
 
 
3890c2b
8b74733
 
 
 
 
 
 
 
3890c2b
8b74733
 
3890c2b
 
c58c466
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
_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