├── .gitattributes
├── .gitignore
├── AnimationBulletin.js
├── AnimationRun.js
├── DemoOutputVideos
├── Type-Photo!AlignH-Center!AlignV-Center!Crop-Full
│ └── 1080p.mp4
├── Type-Photo!AlignH-Left!AlignV-Top!Crop-Full
│ └── 1080p.mp4
├── Type-Photo!AlignH-Right!AlignV-Bottom!Crop-Full
│ └── 1080p.mp4
├── Type-Video!AlignH-Center!AlignV-Center!Crop-Full
│ └── 1080p.mp4
├── Type-Video!AlignH-Left!AlignV-Top!Crop-FitToFrame
│ └── 1080p.mp4
├── Type-Video!AlignH-Left!AlignV-Top!Crop-Full
│ └── 1080p.mp4
├── Type-Video!AlignH-Left!AlignV-Top!Crop-Left
│ └── 1080p.mp4
├── Type-Video!AlignH-Left!AlignV-Top!Crop-Right
│ └── 1080p.mp4
└── Type-Video!AlignH-Right!AlignV-Bottom!Crop-Full
│ └── 1080p.mp4
├── LICENSE
├── README.md
├── app.js
├── assets
├── Audio
│ └── audio.mpeg
├── Font
│ ├── Roboto-Bold.ttf
│ └── Roboto-Light.ttf
├── Footage
│ └── id
│ │ └── 720p-sample1.mp4
├── Image
│ └── id
│ │ ├── block_1.jpg
│ │ ├── block_3.jpg
│ │ └── o.jpg
├── index.html
└── template_index
├── classes
└── Text.js
├── config.js
├── download
└── id
├── ffmpeg_wrapper.js
├── fontcode
├── generate.js
├── metric.json
├── robotobold.json
└── robotolight.json
├── multi_worker.js
├── package-lock.json
├── package.json
├── utils.js
├── worker.js
└── workerChild.js
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (https://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # TypeScript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 | # parcel-bundler cache (https://parceljs.org/)
61 | .cache
62 |
63 | # next.js build output
64 | .next
65 |
66 | # nuxt.js build output
67 | .nuxt
68 |
69 | # vuepress build output
70 | .vuepress/dist
71 |
72 | # Serverless directories
73 | .serverless
74 |
75 | # FuseBox cache
76 | .fusebox/
77 |
78 | backup
79 | metrics
80 | fontcode/text.js
81 | fontcode/test.js
--------------------------------------------------------------------------------
/AnimationBulletin.js:
--------------------------------------------------------------------------------
1 | const path = require("path");
2 | const fs = require('fs');
3 | const Utils = require('./utils');
4 | const Config = require('./config');
5 | const AnimationRun = require('./AnimationRun');
6 | class AnimBulletin extends AnimationRun {
7 | reset = function (user, blockId) {
8 | user["blockList"][blockId].lineslistheightMax = 0;
9 | user["blockList"][blockId].increment = 0;
10 | user["blockList"][blockId].maxFirst = 0;
11 | user["blockList"][blockId].currentInY = 0;
12 | user["blockList"][blockId].wordsListMain = [];
13 | user["blockList"][blockId].wordsListSub = [];
14 | user["blockList"][blockId].linesListMain = [];
15 | user["blockList"][blockId].linesListSub = [];
16 | }
17 | run = async function (id, isPreview) {
18 | await this.runAnimation(id, isPreview);
19 | let user = Config.users[id];
20 | try {
21 | this.font = this.global_data.font
22 | let offsetY = 0;
23 | for (let blockId = 0; blockId < user["blockList"].length; blockId++) {
24 | this.reset(user, blockId);
25 | await this.doProcessText(id, blockId, user.animation_style);
26 | await this.processDimensions(user, blockId, user.animation_style);
27 | let maxWidthBound = user.maxWidthBound;
28 | let maxFirstCrop = user.maxFirstCrop;
29 | let destY = 0;
30 | let y = 0;
31 | let timing = 0;
32 | let cmdText = "";
33 | let frameIncrement = 0;
34 | if (user["blockList"][blockId].type == "photo" || user["blockList"][blockId].type == "quoteImage") {
35 | cmdText = "";
36 | let percentTotal = 100
37 | if (user["blockList"][blockId].background_settings.crop != "Fittoframe") {
38 | let yHeight = 1080
39 | percentTotal = this.processResolution(id, Config.hdWidth, yHeight, user["blockList"][blockId].width, user["blockList"][blockId].height)
40 | }
41 |
42 | let startY = 0;
43 | y = startY;
44 | let duration = 0
45 | destY = 5;
46 | if (blockId > 0) {
47 | startY = 0;
48 | y = startY;
49 | destY = 5; duration = 300;
50 | }
51 | else {
52 | startY = 0;
53 | destY = 134;
54 | }
55 | let start = Date.now();
56 | let stop = false
57 | let end = start + duration;
58 | startY = -(user.iHeight);
59 | y = startY;
60 | destY = 0;
61 | duration = 0;
62 | if (blockId > 0) duration = 300;
63 | start = Date.now();
64 | stop = false;
65 | end = start + duration;
66 | frameIncrement = 0;
67 | startY = user.iHeight == 1080 ? 125 : 125;
68 | y = startY;
69 | destY = user.iHeight == 1080 ? 200 : 200
70 | duration = 0
71 | if (blockId > 0) duration = user["blockList"][blockId].timing * 1000 - 300
72 | else {
73 | duration = user["blockList"][blockId].timing * 1000;
74 | y = startY;
75 | destY = user.iHeight == 1080 ? 200 : 200;
76 | }
77 | start = Date.now();
78 | timing = (user["blockList"][blockId].timing) * 30
79 | end = start + duration;
80 | let currentIncrement = 1;
81 | let resize_command = [];
82 | if (isPreview) {
83 | resize_command.push("-resize")
84 | if (user["blockList"][blockId].background_settings.crop == "left" || user["blockList"][blockId].background_settings.crop == "right") {
85 | resize_command.push(213 + "x" + Config.previewHeight)
86 | } else {
87 | resize_command.push(Config.previewWidth + "x" + Config.previewHeight)
88 | }
89 | }
90 | for (let iFrame = 0; iFrame < timing; iFrame += currentIncrement) {
91 | frameIncrement++
92 | if (stop) {
93 | break;
94 | }
95 |
96 | let val = iFrame / timing;
97 | let heightAfter = user["blockList"][blockId].height * percentTotal;
98 | offsetY = heightAfter - user["blockList"][blockId].height
99 | cmdText = ["convert", "-depth", "8", "-define", "PNG:compression-level=9",
100 | "-define", "PNG:compression-strategy=2", "-size",
101 | user["blockList"][blockId].hHeight + "x1080", "xc:white",
102 | "(", user["blockList"][blockId].url, "-quality", "40", "-gravity",
103 | "center", "-resize", (percentTotal) + "%", "-extent",
104 | +user["blockList"][blockId].hHeight + "x1080+0+" + 0,
105 | "-define",
106 | "distort:viewport=" + user["blockList"][blockId].hHeight + "x1080+0+0",
107 | "-gravity", "center", "-distort", "SRT", (1 + (val * 0.05)) + " 0", ")",
108 | "-composite", "-gravity", "center", ...resize_command, "-define",
109 | "PNG:compression-level=9", "-define", "PNG:compression-strategy=2",
110 | Config.output_directory + id + path.sep + "data" + path.sep + "frames" + (blockId + 1) + path.sep + "fie-" + frameIncrement.toLocaleString('en-US', { minimumIntegerDigits: 4, useGrouping: false }) + "." + "jpg"];
111 | if (this.isDebug) {
112 | if (this.which == -1)
113 | this.add_command(id, 'convert', cmdText);
114 | else if (this.which == blockId) { this.add_command(id, 'convert', cmdText); }
115 | } else {
116 | this.add_command(id, 'convert', cmdText);
117 | }
118 | }
119 |
120 |
121 | } else if (user["blockList"][blockId].type == "logoVideo") {
122 | await this.generateLogo(user, id, blockId);
123 | } else if (user["blockList"][blockId].type == "logoText") {
124 | let size = Config.previewWidth + "x" + Config.previewHeight;
125 | if (!isPreview) {
126 | size = (Config.hdWidth + "x" + Config.hdHeight);
127 | }
128 | cmdText = ["-size", size, "xc:" + user["blockList"][blockId].accent, "-quality", "50",
129 | Config.output_directory + id + path.sep + "data" + path.sep + "frames" + (blockId + 1) + path.sep + "fiebg.jpg"];
130 | this.add_command(id, 'convert', cmdText);
131 | await this.generateLogo(user, id, blockId);
132 | } else if (user["blockList"][blockId].type == "logoImage") {
133 | await this.generateLogo(user, id, blockId);
134 | await this.generateCommands(user, id, blockId);
135 | }
136 | offsetY = 90;
137 | if (user["blockList"][blockId].type == "text" || user["blockList"][blockId].background_settings.crop == "right" || user["blockList"][blockId].background_settings.crop == "left" || user["blockList"][blockId].type == "quoteImage" || user["blockList"][blockId].type == "quoteVideo") {
138 | if (user["blockList"][blockId].type == "text" || user["blockList"][blockId].background_settings.crop == "right" || user["blockList"][blockId].background_settings.crop == "left") {
139 | offsetY = user["blockList"][blockId].linesListYAxis[0] + 90;
140 | } else {
141 | offsetY = user["blockList"][blockId].linesListYAxis[0];
142 | }
143 | }
144 |
145 | if (user["blockList"][blockId].type == "logoImage" || user["blockList"][blockId].type == "logoVideo" || user["blockList"][blockId].type == "logoText") {
146 | await generateTextBulletin(id, blockId)
147 | } else {
148 | /*TEXT AND SUBTITLE*/
149 | let startY = user.iHeight == 1080 ? 200 : 200;
150 | destY = user.iHeight == 1080 ? 125 : 125;
151 | timing = (user["blockList"][blockId].timing) * 30;
152 | if (blockId <= 0) {
153 | startY = user.iHeight == 1080 ? 200 : 200;
154 | timing = ((user["blockList"][blockId].timing) * 30);
155 | y = startY;
156 | }
157 |
158 | if (user["blockList"][blockId].type == "text") {
159 | timing = (user["blockList"][blockId].timing - 1) * 30;
160 | }
161 |
162 | let secondAnimStart = 16;
163 | let thirdAnimStart = 24;
164 | let forthAnimStart = (user["blockList"][blockId].timing == 3) ? 49 :
165 | (user["blockList"][blockId].timing == 4) ? 54 : 59;
166 | let textYAxis = 0;
167 | let yAxis = 0;
168 | let vopacity = 0;
169 | let totalY = 0;
170 | let valX = 0;
171 | let xAxis = 0;
172 | let curIndex = 0;
173 | let valueOpacity = 0;
174 | let currentTIndex = 0;
175 | let halfTiming = timing < 30 ? 20 : 30;
176 | let currentLine = user["blockList"][blockId].linesListMain.length
177 | let xStart = forthAnimStart
178 | for (let i = 0; i < user["blockList"][blockId].linesListSub.length; i++) {
179 | user["blockList"][blockId].linesListSub[i]["preStartRectangle"] = xStart + 1
180 | user["blockList"][blockId].linesListSub[i]["start"] = xStart
181 | user["blockList"][blockId].linesListSub[i]["end"] = (
182 | (user["blockList"][blockId].timing == 3) ? 9 :
183 | (user["blockList"][blockId].timing == 4) ? 15 : 20);
184 |
185 | user["blockList"][blockId].linesListSub[i]["iAfter"] = 0;
186 | user["blockList"][blockId].linesListSub[i]["t"] = 0;
187 | user["blockList"][blockId].linesListSub[i]["preEndRectangle"] = xStart + 1 + (
188 | (user["blockList"][blockId].timing == 3) ? 12 :
189 | (user["blockList"][blockId].timing == 4) ? 17 : 22)
190 | xStart += 1 + (
191 | (user["blockList"][blockId].timing == 3) ? 5 :
192 | (user["blockList"][blockId].timing == 4) ? 6 : 7)
193 | user["blockList"][blockId].linesListSub[i]["nextStartRectangle"] = xStart + 1
194 |
195 | }
196 | let totalSubLines = 1;
197 | let resize_command = []
198 | if (isPreview) {
199 | resize_command.push("-resize")
200 | if (user["blockList"][blockId].background_settings.crop == "left" || user["blockList"][blockId].background_settings.crop == "right") {
201 |
202 | resize_command.push(213 + "x" + Config.previewHeight)
203 |
204 | } else {
205 | resize_command.push(Config.previewWidth + "x" + (user["blockList"][blockId].lineslistheightMax / 1080) * Config.previewHeight)
206 |
207 | }
208 |
209 | }
210 | for (let d = 0; d < timing; d++) {
211 | if (d > 15) {
212 | vopacity = curIndex / halfTiming > 1.0 ? 1.0 : (curIndex / halfTiming);
213 | curIndex++;
214 | }
215 | valueOpacity = (currentTIndex / timing) >= 1.0 ? 1.0 : (currentTIndex / timing);
216 | currentTIndex++;
217 | frameIncrement++;
218 | let cmdText = []
219 | if (user["blockList"][blockId].type == "text") {
220 | cmdText = ["convert", "-quality", "40", "-size"];
221 | if (valueOpacity > 0) {
222 | cmdText.push(this.mainWidth + "x" + this.mainHeight)
223 | } else {
224 | if (isPreview) {
225 | cmdText.push(Config.previewWidth + "x" + Config.previewHeight)
226 | } else {
227 | cmdText.push(Config.hdWidth + "x" + 1080)
228 | }
229 | }
230 | cmdText.push("xc:" + user["blockList"][blockId].background_settings["color"])
231 | } else if (user["blockList"][blockId].background_settings.crop == "left" || user["blockList"][blockId].background_settings.crop == "right") {
232 | cmdText = ["convert", "-define", "png:color-type=6", "-quality", "40", "-size"];
233 | if (valueOpacity > 0) {
234 | cmdText.push(this.mainWidth + "x" + 1080)
235 | } else {
236 | if (isPreview) {
237 | cmdText.push(Config.previewWidth + "x" + Config.previewHeight)
238 | } else {
239 | cmdText.push(Config.hdWidth + "x" + user["blockList"][blockId].lineslistheightMax)
240 | }
241 | }
242 | cmdText.push("xc:none")
243 | }
244 | else {
245 | cmdText = ["convert", "-define", "png:color-type=6", "-quality", "40", "-size"];
246 | if (valueOpacity > 0) {
247 | cmdText.push(this.mainWidth + "x" + user["blockList"][blockId].lineslistheightMax)
248 | } else {
249 | if (isPreview) {
250 |
251 | cmdText.push(Config.previewWidth + "x" + user["blockList"][blockId].lineslistheightMax)
252 | } else {
253 |
254 |
255 | cmdText.push(Config.hdWidth + "x" + user["blockList"][blockId].lineslistheightMax)
256 | }
257 | }
258 | cmdText.push("xc:none")
259 | }
260 | cmdText.push("-fill")
261 | cmdText.push(user["blockList"][blockId].text[0]["color"])
262 | cmdText.push("-font")
263 | cmdText.push(this.fontBold)
264 | cmdText.push("-pointsize")
265 | cmdText.push(user["blockList"][blockId].text[0]["fontSize"])
266 |
267 | if (valueOpacity > 0) {
268 | let finalX = user["blockList"][blockId].linesListXAxis[0]
269 | if (user["blockList"][blockId].increment >= 0) {
270 | cmdText.push("(")
271 | cmdText.push("xc:transparent")
272 | let n = (user["blockList"][blockId].increment / 15)
273 | let valYVerticalLine = user["blockList"][blockId].increment >= 15 ? 1 : n * (2 - n);
274 |
275 | textYAxis = user["blockList"][blockId].type == "text" || user["blockList"][blockId].background_settings.crop == "left" || user["blockList"][blockId].background_settings.crop == "right" ? user["blockList"][blockId].linesListYAxis[0] : 0
276 | cmdText.push("-fill")
277 | cmdText.push(user["blockList"][blockId].accent)
278 | cmdText.push("-draw")
279 | totalY = textYAxis + this.getHeightCharacter(user.animation_style, currentLine, user["blockList"][blockId].linesListMain, "Main")
280 | let vY = user["blockList"][blockId].type == "text" || user["blockList"][blockId].background_settings.crop == "left" || user["blockList"][blockId].background_settings.crop == "right" ? user["blockList"][blockId].linesListYAxis[0] : 0
281 | let tY = vY + ((totalY - vY) * valYVerticalLine)
282 | yAxis = user["blockList"][blockId].type == "text" || user["blockList"][blockId].background_settings.crop == "left" || user["blockList"][blockId].background_settings.crop == "right" ? user["blockList"][blockId].linesListYAxis[0] : 0
283 |
284 |
285 | let startX = finalX;
286 | let incValueFinalX = finalX + 18;
287 | let endRect = parseInt(Math.max(...user["blockList"][blockId].linesWidthMain) + incValueFinalX + 30)
288 | if (user["blockList"][blockId].alignH == "right") {
289 | finalX = maxWidthBound;
290 | incValueFinalX = finalX + 18;
291 | endRect = incValueFinalX - parseInt(Math.max(...user["blockList"][blockId].linesWidthMain)) - 30
292 | } else {
293 | startX += 18;
294 | }
295 |
296 | cmdText.push("rectangle " + finalX + "," + tY + " " + incValueFinalX + "," + parseInt(vY))
297 | if (user["blockList"][blockId].increment >= secondAnimStart && user["blockList"][blockId].legibility) {
298 | cmdText.push("-fill");
299 | let clr = Utils.hexToRgb(user["blockList"][blockId].legibilityColor);
300 | cmdText.push("rgba(" + clr.r + "," + clr.g + "," + clr.b + "," + ((valueOpacity * 0.50) + 0.1) + ")");
301 | cmdText.push("-draw");
302 | cmdText.push("rectangle " + startX + "," + (vY) + " " + endRect + "," + (totalY + 1));
303 | }
304 | cmdText.push(")");
305 | cmdText.push("-composite");
306 | }
307 | if (user["blockList"][blockId].increment >= secondAnimStart) {
308 | cmdText.push("(")
309 | cmdText.push("xc:transparent")
310 | let ne = (user["blockList"][blockId].increment - secondAnimStart) / (thirdAnimStart - secondAnimStart)
311 | valX = user["blockList"][blockId].increment > thirdAnimStart >= 1 ? 1 : ne * (2 - ne)
312 |
313 | //textYAxis = 90 + (Math.abs(user["blockList"][blockId].linesListMain[0]["nDescentLine"]) + 5)
314 | textYAxis = 40 + (Math.abs(user["blockList"][blockId].linesListMain[0]["nDescentLine"]) + 5);
315 | for (let ieg = 0; ieg < currentLine; ieg++) {
316 | let gf = ieg + 1;
317 | if (user["blockList"][blockId].alignH == "right") {
318 | finalX = (maxWidthBound)
319 | } else {
320 | finalX = user["blockList"][blockId].linesListXAxis[ieg] + 30
321 | }
322 | let text = user["blockList"][blockId].linesListMain[ieg]["textLine"]
323 | if (valueOpacity > 0) {
324 | cmdText.push("-fill")
325 | let clr = Utils.hexToRgb(user["blockList"][blockId].text[0]["color"])
326 | cmdText.push("rgba(" + clr.r + "," + clr.g + "," + clr.b + "," + 1 + ")");
327 | cmdText.push("-annotate")
328 | if (user["blockList"][blockId].alignH == "right") {
329 | let width_line = Math.max(...user["blockList"][blockId].linesWidthMain)
330 | let current_width_line = user["blockList"][blockId].linesWidthMain[ieg]
331 | cmdText.push("+" + ((width_line - current_width_line)) + "+" + textYAxis)
332 | } else if (user["blockList"][blockId].alignH == "center") {
333 | cmdText.push("+" + (maxFirstCrop + 10) + "+" + textYAxis);
334 | } else {
335 | if (ieg > 0) {
336 | cmdText.push("+" + (finalX + 10) + "+" + textYAxis);
337 | } else {
338 | cmdText.push("+" + (finalX + 10) + "+" + textYAxis);
339 | }
340 | }
341 |
342 | cmdText.push(text);
343 | }
344 | if (ieg < currentLine - 1) {
345 | textYAxis += 20+(+(user["blockList"][blockId].linesListMain[ieg + 1]["nDescentLine"]))
346 | }
347 | }
348 |
349 | if (user["blockList"][blockId].alignH == "right") {
350 | let width_line = Math.max(...user["blockList"][blockId].linesWidthMain)
351 | let xMovement = (1 + ((width_line - 1) * valX))
352 | xAxis = xMovement
353 | let xFinal = (finalX - Math.abs(xAxis)) - 18
354 | cmdText.push("-crop")
355 | cmdText.push(xAxis + "x" + user["blockList"][blockId].lineslistheightMax + "+" + 0 + "-" + 0)
356 | cmdText.push("-geometry")
357 | cmdText.push("+" + xFinal + "+" + (yAxis))
358 |
359 | } else
360 | if (user["blockList"][blockId].alignH == "center") {
361 | let width_line = Math.max(...user["blockList"][blockId].linesWidthMain)
362 | let xMovement = (width_line
363 | + (((maxFirstCrop + 10) - width_line) * valX))
364 | let xAxis = xMovement;
365 | cmdText.push("-crop")
366 | cmdText.push((width_line + 30) + "x" + user["blockList"][blockId].lineslistheightMax + "+" + xAxis + "+" + 0)
367 | cmdText.push("-geometry")
368 | cmdText.push("+" + finalX + "+" + (yAxis))
369 | } else {
370 | let width_line = Math.max(...user["blockList"][blockId].linesWidthMain);
371 | let xMovement = ((width_line)
372 | + ((finalX - width_line) * valX))
373 | let xAxis = xMovement
374 | cmdText.push("-crop")
375 | cmdText.push((width_line + 30) + "x" + user["blockList"][blockId].lineslistheightMax + "+" + xAxis + "+" + 0)
376 | cmdText.push("-geometry")
377 | cmdText.push("+" + finalX + "+" + (yAxis))
378 | }
379 |
380 | cmdText.push(")")
381 | cmdText.push("-composite")
382 | }
383 | totalY += (30 / Config.hdHeight) * user.iHeight
384 | let totalYY = totalY
385 |
386 | if (user["blockList"][blockId].increment >= forthAnimStart) {
387 | for (let i = 0; i < totalSubLines; i++) {
388 | let text = user["blockList"][blockId].linesListSub[i]["textLine"]
389 |
390 | cmdText.push("(")
391 | cmdText.push("xc:transparent")
392 |
393 |
394 | textYAxis = offsetY
395 |
396 | let clr = Utils.hexToRgb(user["blockList"][blockId].text[0]["color"])
397 |
398 | cmdText.push("-fill")
399 | cmdText.push("rgba(" + clr.r + "," + clr.g + "," + clr.b + "," + valueOpacity + ")");
400 |
401 |
402 | textYAxis += (60 / Config.hdHeight) * user.iHeight
403 | if (user["blockList"][blockId].alignH == "right") {
404 | finalX = (maxWidthBound) + 30
405 | } else {
406 | finalX = user["blockList"][blockId].linesListXAxis[0] + 30
407 | }
408 | cmdText.push("-fill")
409 | cmdText.push(user["blockList"][blockId].accent)
410 | let cX = (finalX) - 30
411 | let endX = cX + user["blockList"][blockId].linesWidthSub[i] + 30
412 | let ne = (user["blockList"][blockId].increment - user["blockList"][blockId].linesListSub[i]["preStartRectangle"]) / (user["blockList"][blockId].linesListSub[i]["preEndRectangle"] - user["blockList"][blockId].linesListSub[i]["preStartRectangle"])
413 | valX = ne >= 1 ? 1 : ne <= 0 ? 0 : Math.sin(ne * Math.PI / 2)
414 | valX = valX < 0 ? 0 : valX
415 | if (user["blockList"][blockId].alignH == "right") {
416 | cX = maxWidthBound - 30 - 18
417 | let cxS = (cX - user["blockList"][blockId].linesWidthSub[i])
418 | endX = cX + 30 + 18 + 18
419 | let xMovement = cX
420 | + (cxS - cX) * valX
421 | cX = xMovement + 4
422 | } else {
423 | cX = (finalX)
424 | let cxS = cX + user["blockList"][blockId].linesWidthSub[i] + 30
425 | endX = cX - 30
426 | let xMovement = cX
427 | + (cxS - cX) * valX
428 | cX = xMovement
429 | }
430 | if (valX != 0) {
431 | cmdText.push("-draw")
432 | cmdText.push("rectangle " + ((cX)) + "," + (totalYY - 4) + " " + endX + "," + (totalYY + user["blockList"][blockId].linesListSub[i]["ascentLine"] + user["blockList"][blockId].linesListSub[i]["descentLine"] + 4))
433 | }
434 | cmdText.push(")");
435 | cmdText.push("-composite")
436 | if (user["blockList"][blockId].increment >= user["blockList"][blockId].linesListSub[i]["start"]) {
437 | cmdText.push("(")
438 |
439 | cmdText.push("xc:transparent")
440 | cmdText.push("-fill")
441 | clr = Utils.hexToRgb(user["blockList"][blockId].text[1]["color"])
442 | cmdText.push("rgba(" + clr.r + "," + clr.r + "," + clr.r + "," + (vopacity) + ")")
443 |
444 |
445 | if (user["blockList"][blockId].linesListSub[i]["iAfter"] > user["blockList"][blockId].linesListSub[i]["end"]) {
446 |
447 | user["blockList"][blockId].linesListSub[i]["t"] = 1
448 | } else {
449 |
450 | user["blockList"][blockId].linesListSub[i]["t"] = parseFloat(user["blockList"][blockId].linesListSub[i]["iAfter"] / user["blockList"][blockId].linesListSub[i]["end"])
451 | user["blockList"][blockId].linesListSub[i]["iAfter"] += 1
452 |
453 | }
454 | let valX = Math.sin(user["blockList"][blockId].linesListSub[i]["t"] * Math.PI / 2);
455 | cmdText.push("-font")
456 | cmdText.push(this.subFont)
457 | cmdText.push("-pointsize")
458 | cmdText.push(user["blockList"][blockId].text[1]["fontSize"])
459 | if (user["blockList"][blockId].alignH == "right") {
460 | let current_width_line = user["blockList"][blockId].linesWidthSub[i]
461 |
462 | let xMovement = (1 + ((current_width_line - 1) * valX))
463 | let xAxis = xMovement
464 |
465 | let xFinal = finalX - Math.abs(xAxis) - 18
466 |
467 | if (valueOpacity > 0) {
468 | cmdText.push("-annotate")
469 | cmdText.push("+" + (0) + "+" + (totalYY + user["blockList"][blockId].linesListSub[i]["ascentLine"]))
470 | cmdText.push(text)
471 | cmdText.push("-crop")
472 | cmdText.push(xAxis + "x" + (user["blockList"][blockId].linesListSub[i]["descentLine"] + user["blockList"][blockId].linesListSub[i]["ascentLine"] + totalYY) + "+" + 0 + "+" + 0)
473 | cmdText.push("-geometry")
474 | cmdText.push("+" + (xFinal - 30) + "+" + 0)
475 | }
476 | } else {
477 | let width_line = user["blockList"][blockId].linesWidthSub[i] + 18
478 |
479 | let xMovement = (1 + (width_line - 1) * valX)
480 | xAxis = xMovement
481 |
482 |
483 |
484 | if (valueOpacity > 0) {
485 | cmdText.push("-annotate")
486 |
487 | cmdText.push("+" + 18 + "+" + (totalYY + user["blockList"][blockId].linesListSub[i]["ascentLine"]))
488 | cmdText.push(text)
489 | cmdText.push("-crop")
490 | cmdText.push(xAxis + "x" + (user["blockList"][blockId].linesListSub[i]["heightLine"] + totalYY) + "+" + (width_line - xAxis) + "+" + 0)
491 | cmdText.push("-geometry")
492 | cmdText.push("+" + (finalX) + "+" + 0)
493 | }
494 |
495 | }
496 | cmdText.push(")")
497 | cmdText.push("-composite")
498 |
499 | }
500 |
501 | totalYY += user["blockList"][blockId].linesListSub[i]["ascentLine"] + user["blockList"][blockId].linesListSub[i]["descentLine"]
502 | totalYY += (40 / Config.hdHeight) * user.iHeight
503 | }
504 |
505 | if (user["blockList"][blockId].increment > (user["blockList"][blockId].linesListSub.length >= totalSubLines) ? user["blockList"][blockId].linesListSub[totalSubLines - 1]["nextStartRectangle"] : user["blockList"][blockId].linesListSub[totalSubLines]["nextStartRectangle"]) {
506 | if (totalSubLines >= user["blockList"][blockId].linesListSub.length) {
507 | totalSubLines = user["blockList"][blockId].linesListSub.length
508 | } else {
509 | totalSubLines++;
510 | }
511 | }
512 | }
513 | }
514 |
515 | if (user["blockList"][blockId].background_settings.crop != "left" && user["blockList"][blockId].background_settings.crop != "right") {
516 | cmdText.push("-background")
517 | cmdText.push("transparent")
518 | } else {
519 | cmdText.push("-background")
520 | cmdText.push(user["blockList"][blockId].background_settings.color)
521 |
522 | }
523 |
524 | if (user["blockList"][blockId].type == "quoteImage" || user["blockList"][blockId].type == "quoteVideo") {
525 | cmdText.push("-resize")
526 | cmdText.push((100) + "%")
527 |
528 | }
529 | if (valueOpacity >= 0) {
530 | cmdText.push("-extent")
531 | }
532 | if (user["blockList"][blockId].background_settings.crop != "left" && user["blockList"][blockId].background_settings.crop != "right") {
533 |
534 |
535 | if (user["blockList"][blockId].type == "text" || user.isPreview) {
536 | if (valueOpacity > 0) {
537 | cmdText.push(user.iWidth + "x" + user.iHeight)
538 | cmdText.push("-resize")
539 | if (user["blockList"][blockId].type == "text" && !user.isPreview) {
540 | cmdText.push(user.iWidth + "x" + user.iHeight)
541 | } else {
542 | cmdText.push(Config.previewWidth + "x" + (user["blockList"][blockId].lineslistheightMax / Config.hdHeight) * Config.previewHeight)
543 | }
544 | }
545 | } else {
546 | cmdText.push(user.iWidth + "x" + user["blockList"][blockId].lineslistheightMax)
547 | }
548 | } else {
549 | if (user.isPreview) {
550 | cmdText.push(user.iWidth / 2 + "x" + user.iHeight)
551 | if (valueOpacity > 0) {
552 | cmdText.push("-resize")
553 | cmdText.push((Config.previewWidth / 2) + "x" + Config.previewHeight)
554 |
555 | }
556 | } else { cmdText.push(user.iWidth / 2 + "x" + user.iHeight) }
557 |
558 | }
559 | let format = "png"
560 | let appendFormat = "PNG32:"
561 | if (user["blockList"][blockId].type == "text") {
562 | format = "jpg"
563 | appendFormat = ""
564 | }
565 |
566 | if (valueOpacity >= 0) {
567 | user["blockList"][blockId].increment++
568 | cmdText.push(...resize_command, appendFormat + Config.output_directory + id + path.sep + "data" + path.sep + "frames" + (blockId + 1) + path.sep + "fim-" + user["blockList"][blockId].increment.toLocaleString('en-US', { minimumIntegerDigits: 4, useGrouping: false }) + "." + format);
569 |
570 |
571 | }
572 |
573 | if (this.isDebug) {
574 | if (this.which == -1)
575 | this.add_command(id, 'convert', cmdText);
576 | else if (this.which == blockId) {
577 | this.add_command(id, 'convert', cmdText);
578 | }
579 | } else {
580 |
581 | this.add_command(id, 'convert', cmdText);
582 |
583 | }
584 | }
585 | }
586 | }
587 | let queue_reply = '';
588 | let queueName = this.queue;
589 | let tLimit = this.totalLimit;
590 | const onMessage = function (msg) {
591 | try {
592 | let data = JSON.parse(msg.content.toString())
593 | if (data.status == "error") {
594 | let obj = new Object()
595 | obj.socket = Config.users[data.id].socket;
596 | if (!isPreview)
597 | obj.data = {
598 | 'status': 'error', videos_progress: { '360p': Config.users[data.id].p_360, '480p': Config.users[data.id].p_480, '720p': Config.users[data.id].p_720, '1080p': Config.users[data.id].p_1080 }
599 | , videos_url: { '360p': 'none', '480p': 'none', '720p': 'none', '1080p': 'none' }
600 | }
601 | else
602 | obj.data = {
603 | 'status': 'error',
604 | 'is_preview': 'false'
605 | , video_url: { url: 'none' }
606 | }
607 | Config.users[data.id].eventEmitter.emit('onProgress', obj);
608 | return;
609 | }
610 |
611 | if (Config.users[data.id].processedVideos >= Config.users[data.id].totalVideos) {
612 | if (Config.users[data.id].isPreview)
613 | this.processHDVideo(Config.users, data.id)
614 | else {
615 | this.processHDVideo(Config.users, data.id, Config.users[data.id].p_360, Config.users[data.id].p_480, Config.users[data.id].p_720, Config.users[data.id].p_1080)
616 |
617 | }
618 | }
619 |
620 | } catch (e) {
621 | throw (e)
622 | }
623 | }
624 | const queuefunction = function (err1, eq) {
625 |
626 | if (err1) {
627 | throw err1;
628 | }
629 |
630 | Config.ch.consume(eq.queue, onMessage.bind(this), {
631 | noAck: true
632 |
633 | });
634 |
635 | let obj = new Object()
636 | obj.socket = user.socket;
637 | if (!isPreview)
638 | obj.data = {
639 | 'status': 'inprogress', videos_progress: { '360p': user.p_360, '480p': user.p_480, '720p': user.p_720, '1080p': user.p_1080 }
640 | , videos_url: { '360p': 'none', '480p': 'none', '720p': 'none', '1080p': 'none' }
641 | }
642 | else
643 | obj.data = {
644 | 'status': 'in_progress',
645 | 'is_preview': 'true'
646 | , video_url: { url: 'none' }
647 | }
648 | user.eventEmitter.emit('onProgress', obj);
649 | let correlationId = Utils.generateUuid();
650 | let date = new Date()
651 | Config.ch.sendToQueue(queueName,
652 | Buffer.from(JSON.stringify({ tLimit: tLimit, commands: user.commands, id: id, date: date })), {
653 | correlationId: correlationId,
654 | replyTo: eq.queue, persistent: true
655 | }, function (e, r) {
656 |
657 |
658 | });
659 |
660 | }
661 | Config.ch.assertQueue('', {
662 | exclusive: true
663 | }, queuefunction.bind(this))
664 | } catch (e) {
665 | console.log("err", e)
666 |
667 | }
668 |
669 | }
670 | processHDVideo = function (users, id, p_360 = null, p_480 = null, p_720 = null, p_1080 = null) {
671 | let isPreview = false
672 | let finalLine = "";
673 | let user = users[id];
674 | if (p_1080 == null) {
675 | isPreview = true;
676 | finalLine = this.makeCommand(true, id);
677 | } else {
678 | finalLine = this.makeCommand(false, id);
679 | }
680 | user.total_ms = user.total_sec * 1000;
681 | const { FFMpeg_Wrapper } = require('./ffmpeg_wrapper.js');
682 | const args = finalLine;
683 | const ffmpegProgress = new FFMpeg_Wrapper();
684 | const ffmpeg = require('child_process').spawn("ffmpeg", args);
685 | function logProgress(progressData) {
686 | let c_progress = (progressData.time_ms / user.total_ms)
687 | let p1080_progress = parseInt(parseFloat(c_progress / 1.0) * 100)
688 |
689 | let obj = new Object()
690 | obj.socket = user.socket
691 | if (isPreview) {
692 |
693 | obj.data = {
694 | 'status': 'in_progress',
695 | 'is_preview': 'true'
696 | , video_url: { url: 'none' }
697 | }
698 | } else {
699 |
700 | obj.data = {
701 | 'status': 'inprogress',
702 | videos_progress: { '360p': user.p_360, '480p': user.p_480, '720p': user.p_720, '1080p': p1080_progress }
703 | , videos_url: { '360p': 'none', '480p': 'none', '720p': 'none', '1080p': 'none' }
704 | }
705 |
706 | }
707 | user.eventEmitter.emit('onProgress', obj);
708 | }
709 | ffmpeg.stderr.pipe(ffmpegProgress).on('data', logProgress);
710 | ffmpeg.on('close', code => {
711 | if (code) {
712 | let obj = new Object()
713 | obj.socket = user.socket
714 | if (!isPreview)
715 | obj.data = {
716 | 'status': 'error', videos_progress: { '360p': user.p_360, '480p': user.p_480, '720p': user.p_720, '1080p': user.p_1080 }
717 | , videos_url: { '360p': 'none', '480p': 'none', '720p': 'none', '1080p': 'none' }
718 | }
719 | else
720 | obj.data = {
721 | 'status': 'error',
722 | 'is_preview': 'false'
723 | , video_url: { url: 'none' }
724 | }
725 | user.eventEmitter.emit('onProgress', obj);
726 |
727 | console.error(`FFMPEG ERROR: ${ffmpegProgress.exitMessage}`);
728 | } else {
729 | if (!user.isPreview) {
730 | this.ffmpeg_run(user, Config.output_directory + path.sep + id + path.sep + "1080p.mp4", Config.output_directory + path.sep + id + path.sep, id)
731 | }
732 | let obj = new Object()
733 | obj.socket = user.socket
734 | if (isPreview) {
735 | obj.data = {
736 | 'status': 'completed',
737 | 'is_preview': 'true'
738 | , video_url: { url: "http://" + Config.socket_ip + "/" + id + "/" + "270p.mp4" }
739 | }
740 | user.eventEmitter.emit('onProgress', obj);
741 |
742 | user.eventEmitter.removeAllListeners();
743 | users.splice(id, 1)
744 | }
745 | let endTime = new Date() - this.startTime
746 | fs.appendFile(Config.output_directory + id + path.sep + "time.txt", id + "--" + endTime.toString(), function (err) {
747 | if (err) throw err;
748 | console.log('Saved!');
749 | });
750 | }
751 | });
752 |
753 | }
754 | makeCommand = function (isPreview, id) {
755 | let user = Config.users[id];
756 | user.total_sec = Math.ceil(user.total_sec)
757 | if (isPreview) {
758 | user.iWidth = Config.previewWidth;
759 | user.iHeight = Config.previewHeight;
760 | } else {
761 | user.iWidth = Config.hdWidth
762 | user.iHeight = Config.hdHeight
763 | }
764 | let imgType = "jpg"
765 | let finalAnswer = "";
766 | let addition = [];
767 | for (let i = 0; i < user["blockList"].length; i++) {
768 | if (user["blockList"][i].type == "logoImage") {
769 | addition.push("-thread_queue_size", "512", "-framerate", "30", "-i", Config.output_directory + id + path.sep + "data" + path.sep + "frames" + (i + 1) + path.sep + "fie-%04d.png");
770 | addition.push("-thread_queue_size", "512", "-framerate", "30", "-i", Config.output_directory + id + path.sep + "data" + path.sep + "frames" + (i + 1) + path.sep + "fim-%04d.png");
771 | addition.push("-thread_queue_size", "512", "-framerate", "30", "-i", Config.output_directory + id + path.sep + "data" + path.sep + "frames" + (i + 1) + path.sep + "logo-%04d.png");
772 | } else if (user["blockList"][i].type == "logoText") {
773 | addition.push("-thread_queue_size", "512", "-framerate", "30", "-i", Config.output_directory + id + path.sep + "data" + path.sep + "frames" + (i + 1) + path.sep + "fiebg.jpg");
774 | addition.push("-thread_queue_size", "512", "-framerate", "30", "-i", Config.output_directory + id + path.sep + "data" + path.sep + "frames" + (i + 1) + path.sep + "fim-%04d.png");
775 | addition.push("-thread_queue_size", "512", "-framerate", "30", "-i", Config.output_directory + id + path.sep + "data" + path.sep + "frames" + (i + 1) + path.sep + "logo-%04d.png");
776 |
777 | } else if (user["blockList"][i].type == "logoVideo") {
778 |
779 | addition.push("-thread_queue_size", "512", "-i", user["blockList"][i].url);
780 | addition.push("-thread_queue_size", "512", "-framerate", "30", "-i", Config.output_directory + id + path.sep + "data" + path.sep + "frames" + (i + 1) + path.sep + "fim-%04d.png");
781 | addition.push("-thread_queue_size", "512", "-framerate", "30", "-i", Config.output_directory + id + path.sep + "data" + path.sep + "frames" + (i + 1) + path.sep + "logo-%04d.png");
782 |
783 | } else if (user["blockList"][i].type == "video" || user["blockList"][i].type == "quoteVideo") {
784 |
785 | if (user["blockList"][i].background_settings.crop == "left" || user["blockList"][i].background_settings.crop == "right") {
786 | addition.push("-i", user["blockList"][i].url);
787 | addition.push("-framerate", "30", "-i", Config.output_directory + id + path.sep + "data" + path.sep + "frames" + (i + 1) + path.sep + "fim-%04d.png");
788 |
789 | } else {
790 | addition.push("-i", user["blockList"][i].url);
791 | addition.push("-framerate", "30", "-i", Config.output_directory + id + path.sep + "data" + path.sep + "frames" + (i + 1) + path.sep + "fim-%04d.png");
792 | }
793 |
794 | } else if (user["blockList"][i].type == "text") {
795 | if (i == 0) {
796 | addition.push("-framerate", "30", "-i", Config.output_directory + id + path.sep + "data" + path.sep + "frames" + (i + 1) + path.sep + "fim-%04d.jpg");
797 | } else {
798 | if (user["blockList"][i].background_settings.crop == "left" || user["blockList"][i].background_settings.crop == "right") {
799 | addition.push("-framerate", "30", "-i", Config.output_directory + id + path.sep + "data" + path.sep + "frames" + (i + 1) + path.sep + "fim-%04d.jpg");
800 | addition.push("-framerate", "30", "-i", Config.output_directory + id + path.sep + "data" + path.sep + "frames" + (i + 1) + path.sep + "fie-%04d.jpg");
801 | } else {
802 | addition.push("-framerate", "30", "-i", Config.output_directory + id + path.sep + "data" + path.sep + "frames" + (i + 1) + path.sep + "fim-%04d.jpg");
803 | }
804 | }
805 | }
806 | else if (user["blockList"][i].type == "photo" || user["blockList"][i].type == "quoteImage") {
807 | if (i == 0) {
808 | addition.push("-framerate", "30", "-i", Config.output_directory + id + path.sep + "data" + path.sep + "frames" + (i + 1) + path.sep + "fie-%04d." + imgType);
809 |
810 | addition.push("-framerate", "30", "-i", Config.output_directory + id + path.sep + "data" + path.sep + "frames" + (i + 1) + path.sep + "fim-%04d.png");
811 |
812 |
813 | } else {
814 | if (user["blockList"][i].background_settings.crop == "left" || user["blockList"][i].background_settings.crop == "right") {
815 |
816 |
817 | addition.push("-framerate", "30", "-i", Config.output_directory + id + path.sep + "data" + path.sep + "frames" + (i + 1) + path.sep + "fie-%04d.jpg");
818 | addition.push("-framerate", "30", "-i", Config.output_directory + id + path.sep + "data" + path.sep + "frames" + (i + 1) + path.sep + "fim-%04d.png");
819 |
820 | } else {
821 |
822 | addition.push("-framerate", "30", "-i", Config.output_directory + id + path.sep + "data" + path.sep + "frames" + (i + 1) + path.sep + "fie-%04d." + imgType);
823 | addition.push("-framerate", "30", "-i", Config.output_directory + id + path.sep + "data" + path.sep + "frames" + (i + 1) + path.sep + "fim-%04d.png");
824 |
825 |
826 | }
827 |
828 | }
829 | }
830 | }
831 |
832 |
833 |
834 | let check_first_index = false
835 | for (let i = 0; i < user["blockList"].length; i++) {
836 | if (user["blockList"][i].voice_over.exist) {
837 |
838 | addition.push("-i", user["blockList"][i].voice_over.local_source)
839 |
840 |
841 | }
842 |
843 | }
844 |
845 | if (this.global_data.local_src.length > 0) {
846 | if (this.global_data.loop) {
847 | addition.push("-stream_loop", "-1");
848 | }
849 | addition.push("-i", this.global_data.local_src);
850 | if (this.global_data.isTrim) {
851 | addition.push("-ss", this.global_data.trimValueStart, "-to", this.global_data.trimValueEnd)
852 | }
853 | }
854 | let lmS = 0;
855 | let f = 0
856 | let globalFilters = "brightness"
857 | let filter = ""
858 | if (globalFilters == "grayscale") {
859 | filter = ",format=gray"
860 | } else if (globalFilters == "brightness") {
861 | filter = ",eq=brightness=-0.01"
862 | }
863 | let delay_command = ""
864 | let enable_command = ""
865 | let currentTime = 0
866 | for (let i = 0; i < user["blockList"].length; i += 1) {
867 | if (i != 0) {
868 |
869 | f += parseFloat(user["blockList"][i - 1].timing)
870 | if (user.animation_style == "blankslate") {
871 | delay_command = "PTS-STARTPTS+" + ((f - 1)) + "/TB"
872 | enable_command = ":enable='between(t\," + ((f - 1.4)) + "," + user.total_sec + ")'"
873 | } else if (user.animation_style == "standout") {
874 |
875 | delay_command = "PTS-STARTPTS+" + ((f - 1)) + "/TB"
876 | enable_command = ":enable='between(t\," + ((f - 1.4)) + "," + user.total_sec + ")'"
877 | } else {
878 |
879 | if (user["blockList"][i].type != "text") {
880 | delay_command = "PTS-STARTPTS+" + (f + (0.5)) + "/TB"
881 |
882 | } else {
883 | delay_command = "PTS-STARTPTS+" + (f + (currentTime)) + "/TB"
884 | }
885 | }
886 | } else {
887 | if (user.animation_style == "blankslate") {
888 | delay_command = "PTS-STARTPTS"
889 |
890 | enable_command = ""
891 | } else {
892 | delay_command = "PTS-STARTPTS"
893 |
894 | }
895 | }
896 | let finalY = user["blockList"][i].linesListYAxis[0]
897 | if (user.animation_style == "blankslate") {
898 | finalY = 0
899 |
900 | }
901 |
902 | if (user["blockList"][i].type == "quoteImage" || user["blockList"][i].type == "quoteVideo" || user["blockList"][i].type == "text") {
903 | finalY = 0
904 | }
905 |
906 | if (i == 0) {
907 | if (user["blockList"][i].type == "text") {
908 |
909 | if (user["blockList"][i].background_settings.crop == "left") {
910 |
911 | finalAnswer += "[0:v][1:v]overlay=x=" + (user.iWidth / 2) + "[mv];";
912 | finalAnswer += "[mv]pad=iw*2:0[left" + (lmS + 2) + "];[left" + (lmS + 2) + "][" + (lmS + 1) + ":v]overlay=x=960[out" + (i + 1) + "];";
913 | lmS += 2;
914 | } else if (user["blockList"][i].background_settings.crop == "right") {
915 |
916 | finalAnswer += "[0:v][1:v]overlay=x=" + (user.iWidth / 2) + "[mv];";
917 | finalAnswer += "[mv]pad=(iw/2)*2:0[left" + (lmS + 1) + "];[left" + (lmS + 1) + "][" + (lmS + 2) + ":v]overlay=x=" + (user.iWidth / 2) + "[out" + (i + 1) + "];";
918 |
919 | lmS += 2;
920 | } else {
921 |
922 | lmS += 1;
923 |
924 | finalAnswer += "[0:v][1:v]overlay=y=" + finalY + "[out1];";
925 | }
926 | } else if (user["blockList"][i].type == "logoText") {
927 | finalAnswer += "[0:v][1:v]overlay[mv];";
928 | finalAnswer += "[mv][" + (lmS + 2) + ":v]overlay=(main_w-overlay_w)/2:H-h-" + ((50 / Config.hdHeight) * user.iHeight) + "[outelogo1];";
929 | finalAnswer += "[outelogo1][" + (lmS + 3) + ":v]overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2[out1];";
930 | lmS += 3
931 | } else if (user["blockList"][i].type == "logoImage") {
932 | finalAnswer += "[0:v][1:v]overlay[mv];";
933 | finalAnswer += "[mv][" + (lmS + 2) + ":v]overlay=(main_w-overlay_w)/2:H-h-" + ((50 / Config.hdHeight) * user.iHeight) + "[outelogo1];";
934 | finalAnswer += "[outelogo1][" + (lmS + 3) + ":v]overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2[out1];";
935 | lmS += 3
936 | } else if (user["blockList"][i].type == "logoVideo") {
937 | finalAnswer += "[0:v][1:v]overlay[mv];";
938 | finalAnswer += "[mv][" + (lmS + 2) + ":v]overlay=(main_w-overlay_w)/2:H-h-" + ((50 / Config.hdHeight) * user.iHeight) + "[outelogo1];";
939 | finalAnswer += "[outelogo1][" + (lmS + 3) + ":v]overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2[out1];";
940 | lmS += 3
941 | } else if (user["blockList"][i].type == "photo" || user["blockList"][i].type == "quoteImage") {
942 | if (user["blockList"][i].background_settings.crop == "left" || user["blockList"][i].background_settings.crop == "right") {
943 | if (user["blockList"][i].background_settings.crop == "left") {
944 |
945 | finalAnswer += "[0:v][1:v]overlay=x=0[mv];";
946 | finalAnswer += "[mv][" + (lmS + 2) + ":v]overlay=x=" + (user.iWidth / 2) + "[out1];";
947 |
948 | } else {
949 | finalAnswer += "[0:v][" + (lmS + 2) + ":v]overlay=x=0[mv];";
950 | finalAnswer += "[mv][1:v]overlay=x=" + (user.iWidth / 2) + "[out1];";
951 |
952 | }
953 | lmS += 2
954 | } else {
955 | finalAnswer += "[0:v][1:v]overlay[mv];";
956 | finalAnswer += "[" + (lmS + 2) + ":v]setpts=" + delay_command + "[outjm" + (i + 1) + "];";
957 | finalAnswer += "[mv][outjm" + (i + 1) + "]overlay=x=" + 0 + ":y=" + finalY + enable_command + "[out1];"
958 | lmS += 2;
959 | }
960 |
961 |
962 |
963 |
964 |
965 | } else if (user["blockList"][i].type == "video") {
966 |
967 | if (user["blockList"][i].background_settings.crop == "left") {
968 | finalAnswer += "[0:v][1:v]overlay=x=0[mv];";
969 | finalAnswer += "[mv][" + (lmS + 2) + ":v]overlay=x=" + (user.iWidth / 2) + "[out" + (i + 1) + "];";
970 |
971 | } else if (user["blockList"][i].background_settings.crop == "right") {
972 | finalAnswer += "[0:v][1:v]overlay=x=0[mv];";
973 | finalAnswer += "[mv]pad=(iw/2)*2:0[left" + (lmS + 1) + "];[left" + (lmS + 1) + "][" + (lmS + 2) + ":v]overlay=x=" + (user.iWidth / 2) + "[out" + (i + 1) + "];";
974 | } else {
975 | finalAnswer += "[0:v][1:v]overlay[mv];";
976 | finalAnswer += "[" + (lmS + 2) + ":v]setpts=" + delay_command + "[outjm" + (i + 1) + "];";
977 | finalAnswer += "[mv][outjm" + (i + 1) + "]overlay=x=0:y=" + finalY + enable_command + "[out1];";
978 | }
979 |
980 | lmS += 2;
981 | } else if (user["blockList"][i].type == "logoVideo") {
982 |
983 | finalAnswer += "[" + (lmS + 1) + ":v]setpts=" + delay_command + "[outjm" + (i + 2) + "];";
984 | finalAnswer += "[" + (lmS + 2) + ":v]setpts=PTS-STARTPTS+" + (f) + "/TB[outjm" + (i + 1) + "];";
985 | finalAnswer += "[" + (lmS + 3) + ":v]setpts=PTS-STARTPTS[outlogotext" + (i + 1) + "];";
986 | finalAnswer += "[outjm" + (i + 2) + "][outjm" + (i + 1) + "]overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2" + enable_command + "[outjmlogovideo" + (i + 1) + "];";
987 | finalAnswer += "[outjmlogovideo" + (i + 1) + "][outlogotext" + (i + 1) + "]overlay=(main_w-overlay_w)/2:H-h-" + ((200 / Config.hdHeight) * user.iHeight) + enable_command + "[out" + (i + 1) + "];";
988 | lmS += 3;
989 |
990 | }
991 |
992 | } else if (user["blockList"][i].type == "video" || user["blockList"][i].type == "quoteVideo") {
993 | let cropped = 0
994 | if (user["blockList"][i].background_settings.crop == "right") {
995 | cropped = user.iWidth + ":" + user.iHeight + ":" + (user.iWidth / 3) + ":0,pad=" + user.iWidth / 2 + "*2:0"
996 | finalAnswer += "[" + (lmS + 2) + ":v]crop=" + cropped + "[left" + (lmS + 2) + "];[left" + (lmS + 2) + "][" + (lmS + 1) + ":v]overlay=x=" + user.iWidth / 2 + "[out" + (i + 1) + "];";
997 |
998 | } else if (user["blockList"][i].background_settings.crop == "left") {
999 | cropped = (user.iWidth / 2) + ":" + user.iHeight + ":" + (user.iWidth / 3) + ":0,pad=" + user.iWidth / 2 + "*2:0"
1000 |
1001 | finalAnswer += "[" + (lmS + 1) + ":v]crop=" + cropped + "[left" + (lmS + 1) + "];[left" + (lmS + 1) + "][" + (lmS + 2) + ":v]overlay=x=" + user.iWidth / 2 + "[out" + (i + 1) + "];";
1002 |
1003 | } else {
1004 | finalAnswer += "[" + (lmS + 1) + ":v]setpts=" + delay_command + "[outjm" + (i + 2) + "];";
1005 |
1006 | finalAnswer += "[" + (lmS + 2) + ":v]setpts=PTS-STARTPTS+" + (f) + "/TB[outjm" + (i + 1) + "];";
1007 |
1008 | finalAnswer += "[outjm" + (i + 2) + "][outjm" + (i + 1) + "]overlay=x=" + 0 + ":y=" + finalY + enable_command + "[out" + (i + 1) + "];";
1009 | //finalAnswer += "[oust" + (i + 1) + "][outsub" + (i + 1) + "]overlay=x=" + 0 + ":y=" + ( finalY+offsetFFMPEGY) + "[out" + (i + 1) + "];";
1010 |
1011 |
1012 |
1013 | }
1014 |
1015 |
1016 | lmS += 2;
1017 |
1018 | } else if (user["blockList"][i].type == "logoImage") {
1019 | finalAnswer += "[" + (lmS + 1) + ":v]setpts=" + delay_command + "[outjm" + (i + 2) + "];";
1020 |
1021 | finalAnswer += "[" + (lmS + 2) + ":v]setpts=PTS-STARTPTS+" + (f) + "/TB[outjm" + (i + 1) + "];";
1022 | finalAnswer += "[" + (lmS + 3) + ":v]setpts=PTS-STARTPTS[outlogotext" + (i + 1) + "];";
1023 |
1024 |
1025 |
1026 | finalAnswer += "[outjm" + (i + 2) + "][outjm" + (i + 1) + "]overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2" + enable_command + "[outlogovideo" + (i + 1) + "];";
1027 | finalAnswer += "[outjmlogovideo" + (i + 1) + "][outlogotext" + (i + 1) + "]overlay=(main_w-overlay_w)/2:H-h-" + ((200 / Config.hdHeight) * user.iHeight) + enable_command + "[out" + (i + 1) + "];";
1028 | lmS += 3;
1029 | } else if (user["blockList"][i].type == "logoText") {
1030 | finalAnswer += "[" + (lmS + 1) + ":v]setpts=" + delay_command + "[outjm" + (i + 2) + "];";
1031 | finalAnswer += "[" + (lmS + 2) + ":v]setpts=PTS-STARTPTS+" + (f) + "/TB[outjm" + (i + 1) + "];";
1032 | finalAnswer += "[" + (lmS + 3) + ":v]setpts=PTS-STARTPTS[outlogotext" + (i + 1) + "];";
1033 | finalAnswer += "[outjm" + (i + 2) + "][outjm" + (i + 1) + "]overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2" + enable_command + "[outlogovideo" + (i + 1) + "];";
1034 | finalAnswer += "[outjmlogovideo" + (i + 1) + "][outlogotext" + (i + 1) + "]overlay=(main_w-overlay_w)/2:H-h-" + ((200 / Config.hdHeight) * user.iHeight) + enable_command + "[out" + (i + 1) + "];";
1035 | lmS += 3;
1036 | } else {
1037 | let cropped = 0;
1038 | if (user["blockList"][i].background_settings.crop == "left" || user["blockList"][i].background_settings.crop == "right") {
1039 |
1040 | if (user["blockList"][i].background_settings.crop == "left") {
1041 | cropped = 0;
1042 | finalAnswer += "[" + (lmS + 1) + ":v][" + (lmS + 2) + ":v]hstack=inputs=2[out" + (i + 1) + "];";
1043 | } else {
1044 | cropped = (user.iWidth / 2)
1045 | finalAnswer += "[" + (lmS + 2) + ":v][" + (lmS + 1) + ":v]hstack=inputs=2[out" + (i + 1) + "];";
1046 | }
1047 | lmS += 2;
1048 | } else {
1049 | if (user["blockList"][i].type != "text") {
1050 | finalAnswer += "[" + (lmS + 1) + ":v]setpts=" + delay_command + "[outdes" + (i + 1) + "];";
1051 | finalAnswer += "[" + (lmS + 2) + ":v]setpts=PTS-STARTPTS+" + (f) + "/TB[outjes" + (i + 1) + "];";
1052 | finalAnswer += "[outdes" + (i + 1) + "][outjes" + (i + 1) + "]overlay=y=" + finalY + enable_command + "[outes" + (i + 1) + "];"
1053 | } else {
1054 | finalAnswer += "[" + (lmS + 1) + ":v]setpts=PTS-STARTPTS+" + (f) + "/TB[outes" + (i + 1) + "];";
1055 | }
1056 |
1057 |
1058 | if (user["blockList"][i].type == "text") { lmS += 1 } else { lmS += 2 }
1059 |
1060 |
1061 |
1062 | }
1063 | ;
1064 | }
1065 |
1066 | }
1067 | let format = "outse"; f = 0;
1068 | for (let i = 0; i < user["blockList"].length; i++) {
1069 | if (i != 0) {
1070 | f += (user["blockList"][i - 1].timing)
1071 | }
1072 | if (user["blockList"][i].voice_over.exist) {
1073 | format = "outse"
1074 |
1075 | user.current_audio_index++
1076 | }
1077 | else {
1078 | format = "oute"
1079 | }
1080 | if (i == 0) {
1081 | finalAnswer += "[out1]setpts=PTS-STARTPTS" + filter + "[oute1];";
1082 | }
1083 | else
1084 | if (user["blockList"][i].type == "text") {
1085 |
1086 | if (user["blockList"][i].background_settings.crop == "left" || user["blockList"][i].background_settings.crop == "right") {
1087 | finalAnswer += "[out" + (i + 1) + "]setpts=PTS-STARTPTS+" + f + "/TB" + filter + "[" + format + (i + 1) + "];";
1088 | } else {
1089 | finalAnswer += "[outes" + (i + 1) + "]" + filter.substr(1, filter.length - 1) + "[" + format + (i + 1) + "];";
1090 | }
1091 |
1092 | } else if (user["blockList"][i].type == "photo" || user["blockList"][i].type == "quoteImage") {
1093 |
1094 | if (user["blockList"][i].background_settings.crop == "left" || user["blockList"][i].background_settings.crop == "right") {
1095 | finalAnswer += "[out" + (i + 1) + "]setpts=PTS-STARTPTS+" + (f + currentTime) + "/TB" + filter + "[" + format + (i + 1) + "];";
1096 | } else {
1097 | finalAnswer += "[outes" + (i + 1) + "]" + filter.substr(1, filter.length - 1) + "[" + format + (i + 1) + "];";
1098 | }
1099 |
1100 | } else if (user["blockList"][i].type == "video" || user["blockList"][i].type == "logoText" || user["blockList"][i].type == "logoImage" || user["blockList"][i].type == "logoVideo" || user["blockList"][i].type == "quoteVideo") {
1101 |
1102 | finalAnswer += "[out" + (i + 1) + "]setpts=PTS-STARTPTS+" + f + "/TB" + filter + "[" + format + (i + 1) + "];";
1103 |
1104 | }
1105 | }
1106 |
1107 | for (let i = 0; i < user["blockList"].length; i++) {
1108 | if (user["blockList"][i].voice_over.exist) {
1109 | if (!check_first_index) {
1110 | user.current_audio_index = lmS;
1111 | check_first_index = true;
1112 | }
1113 | addition.push("-i", user["blockList"][i].voice_over.local_source);
1114 | lmS++;
1115 |
1116 | }
1117 |
1118 | }
1119 | for (let i = 0; i < user["blockList"].length; i++) {
1120 | if (user["blockList"][i].voice_over.exist) {
1121 | finalAnswer += "[outse" + (i + 1) + ":a][" + user.current_audio_index + ":a]amerge=inputs=2" + "[oute" + (i + 1) + "]";
1122 | user.current_audio_index++;
1123 | }
1124 | }
1125 | let lastP = "[oute1]";
1126 | let nextParam = "oute";
1127 | let currentParam = "oute";
1128 | f = 0;
1129 | for (let ie = 1; ie <= user["blockList"].length; ie++) {
1130 | let i = ie - 1;
1131 | f += (user["blockList"][i].timing);
1132 | if (i == 0) {
1133 | nextParam = "outnje";
1134 |
1135 | }
1136 | if (i >= 1) {
1137 | currentParam = "outnje";
1138 | }
1139 |
1140 | if (i == user["blockList"].length - 2) {
1141 | if (user["blockList"].length == 2) {
1142 | nextParam = "oute"
1143 | }
1144 |
1145 | if (user["blockList"][i].type == "video" || user["blockList"][i].type == "logoText" ||
1146 | user["blockList"][i].type == "logoVideo" ||
1147 | user["blockList"][i].type == "logoImage"
1148 | || user["blockList"][i].type == "photo" || user["blockList"][i].type == "text" || user["blockList"][i].type == "quoteVideo" || user["blockList"][i].type == "quoteImage") {
1149 |
1150 | if (user.animation_style == "blankslate") {
1151 |
1152 | finalAnswer += "[" + nextParam + (i + 1) + "]format=rgba,fade=t=out:st=" + f + ":d=" + 2 + ":alpha=1[a" + nextParam + (i + 1) + "];";
1153 | finalAnswer += "[oute" + (i + 2) + "]format=rgba,fade=t=in:st=" + f + ":d=" + 2 + ":alpha=1[aoute" + (i + 2) + "];"
1154 | finalAnswer += "[a" + nextParam + (i + 1) + "][aoute" + (i + 2) + "]overlay=enable='between(t\\," + f + "," + (user.total_sec) + ")':y=0:x=0[outnjse" + (i + 1) + "];";
1155 |
1156 | } else {
1157 | finalAnswer += "[" + nextParam + (i + 1) + "][oute" + (i + 2) + "]overlay=enable='between(t\\," + f + "," + (user.total_sec) + ")':y=0:x=0[outnjse" + (i + 1) + "];";
1158 | }
1159 | } else {
1160 | finalAnswer += "[" + nextParam + (i + 1) + "][oute" + (i + 2) + "]overlay=enable='between(t\\," + f + "," + (user.total_sec) + ")'[outnjse" + (i + 1) + "];";
1161 |
1162 | }
1163 | lastP = "[outnjse" + (i + 1) + "]";
1164 |
1165 |
1166 | } else if (i != user["blockList"].length - 1) {
1167 | if (user["blockList"][i].type == "video" || user["blockList"][i].type == "quoteVideo" || user["blockList"][i].type == "logoText" ||
1168 | user["blockList"][i].type == "logoVideo" ||
1169 | user["blockList"][i].type == "logoImage" || user["blockList"][i].type == "quoteVideo") {
1170 |
1171 |
1172 |
1173 |
1174 | if (user["blockList"].length - 1 >= i + 1) {
1175 |
1176 | if (user["blockList"][i + 1].type == "video" || user["blockList"][i].type == "quoteVideo" || user["blockList"][i].type == "logoText" ||
1177 | user["blockList"][i].type == "logoVideo" ||
1178 | user["blockList"][i].type == "logoImage" || user["blockList"][i].type == "quoteVideo" || user["blockList"][i].type == "quoteImage" || user["blockList"][i + 1].type == "photo" || user["blockList"][i + 1].type == "text") {
1179 | let overLayY = ":y=0:x=0"
1180 | if (user["blockList"][i + 1].type == "photo") {
1181 | overLayY = ""
1182 |
1183 | }
1184 | if (user.animation_style == "blankslate") {
1185 |
1186 | finalAnswer += "[" + currentParam + (i + 1) + "]format=rgba,fade=t=out:st=" + f + ":d=" + 2 + ":alpha=1[a" + currentParam + (i + 1) + "]";
1187 | finalAnswer += ";[oute" + (i + 2) + "]format=rgba,fade=t=out:st=" + f + ":d=" + 2 + ":alpha=1[aoute" + (i + 2) + "];"
1188 | finalAnswer += "[a" + currentParam + (i + 1) + "][aoute" + (i + 2) + "]overlay=enable='between(t\\," + f + "," + (user.total_sec) + ")'" + overLayY + "[" + nextParam + (i + 2) + "];";
1189 |
1190 | } else {
1191 | finalAnswer += "[" + currentParam + (i + 1) + "][oute" + (i + 2) + "]overlay=enable='between(t\\," + f + "," + (user.total_sec) + ")'" + overLayY + "[" + nextParam + (i + 2) + "];";
1192 | }
1193 | lastP = "[outnje" + (i + 2) + "]";
1194 |
1195 | }
1196 | } else {
1197 | let overLayY = ":y=0:x=0"
1198 | finalAnswer += "[oute" + (i + 1) + "][oute" + (i + 2) + "]overlay=enable='between(t\\," + f + "," + (user.total_sec) + ")'" + overLayY + "[" + nextParam + (i + 2) + "];";
1199 | lastP = "[outnje" + (i + 2) + "]";
1200 |
1201 | }
1202 | // finalAnswer += "["+nextParam + (i+1) + "][oute" + (i + 2) + "]overlay=enable='between(t\\,"+f +","+(user .total_sec)+")':y='if(gte(t,"+f +"),if(gte(h-(t-"+f +")*(1/0.5)*h,0),h-(t-"+f +")*(1/0.5)*h,0))':x=0["+nextParam + (i + 2) + "];";
1203 | //lastP = "[outnje" + (i + 2) + "]";
1204 | } else if (user["blockList"][i].type == "photo" || user["blockList"][i].type == "quoteImage") {
1205 | if (user["blockList"].length - 1 >= i + 1) {
1206 | if (user["blockList"][i + 1].type == "video" || user["blockList"][i].type == "quoteVideo" || user["blockList"][i].type == "quoteImage" || user["blockList"][i + 1].type == "photo" || user["blockList"][i + 1].type == "text") {
1207 | let overLayY = ":y=0:x=0"
1208 | if (user["blockList"][i + 1].type == "photo" || user["blockList"][i].type == "quoteImage") {
1209 | overLayY = ""
1210 |
1211 | }
1212 |
1213 | if (user.animation_style == "blankslate") {
1214 |
1215 | finalAnswer += "[" + currentParam + (i + 1) + "]format=rgba,fade=t=out:st=" + f + ":d=" + 2 + ":alpha=1[a" + currentParam + (i + 1) + "]";
1216 | finalAnswer += ";[oute" + (i + 2) + "]format=rgba,fade=t=in:st=" + f + ":d=" + 2 + ":alpha=1[aoute" + (i + 2) + "];"
1217 | finalAnswer += "[a" + currentParam + (i + 1) + "][aoute" + (i + 2) + "]overlay=enable='between(t\\," + f + "," + (user.total_sec) + ")'" + overLayY + "[" + nextParam + (i + 2) + "];";
1218 |
1219 | } else {
1220 | finalAnswer += "[" + currentParam + (i + 1) + "][oute" + (i + 2) + "]overlay=enable='between(t\\," + f + "," + (user.total_sec) + ")'" + overLayY + "[" + nextParam + (i + 2) + "];";
1221 | }
1222 |
1223 | lastP = "[outnje" + (i + 2) + "]";
1224 |
1225 | }
1226 | } else {
1227 | if (user["blockList"][i].type == "photo" || user["blockList"][i].type == "quoteImage") {
1228 | overLayY = ""
1229 |
1230 | }
1231 |
1232 | if (user.animation_style == "blankslate") {
1233 |
1234 | finalAnswer += "[" + currentParam + (i + 1) + "]format=rgba,fade=t=out:st=" + f + ":d=" + 2 + ":alpha=1[a" + currentParam + (i + 1) + "]";
1235 | finalAnswer += ";[oute" + (i + 2) + "]format=rgba,fade=t=in:st=" + f + ":d=" + 2 + ":alpha=1[aoute" + (i + 2) + "];"
1236 | finalAnswer += "[a" + currentParam + (i + 1) + "][aoute" + (i + 2) + "]overlay=enable='between(t\\," + f + "," + (user.total_sec) + ")'" + overLayY + "[" + nextParam + (i + 2) + "];";
1237 |
1238 | } else {
1239 | finalAnswer += "[" + currentParam + (i + 1) + "][oute" + (i + 2) + "]overlay=enable='between(t\\," + f + "," + (user.total_sec) + ")'" + overLayY + "[" + nextParam + (i + 2) + "];";
1240 | }
1241 | lastP = "[outnje" + (i + 2) + "]";
1242 |
1243 | }
1244 |
1245 |
1246 | } else if (user["blockList"][i].type == "text") {
1247 | if (user["blockList"].length - 1 >= i + 1) {
1248 | if (user["blockList"][i + 1].type == "video" || user["blockList"][i].type == "quoteVideo" || user["blockList"][i].type == "quoteImage" || user["blockList"][i + 1].type == "photo" || user["blockList"][i + 1].type == "text") {
1249 | let overLayY = ":y=0:x=0"
1250 | if (user["blockList"][i + 1].type == "photo" || user["blockList"][i].type == "quoteImage") {
1251 | overLayY = ""
1252 |
1253 | }
1254 | finalAnswer += "[" + currentParam + (i + 1) + "][oute" + (i + 2) + "]overlay=enable='between(t\\," + f + "," + (user.total_sec) + ")'" + overLayY + "[" + nextParam + (i + 2) + "];";
1255 | lastP = "[outnje" + (i + 2) + "]";
1256 | }
1257 | } else {
1258 | if (user["blockList"][i].type == "photo" || user["blockList"][i].type == "quoteImage") {
1259 | overLayY = ""
1260 | }
1261 | if (user.animation_style == "blankslate") {
1262 | finalAnswer += "[oute" + (i + 1) + "]format=rgba,fade=t=out:st=" + f + ":d=" + 2 + ":alpha=1[aoute" + (i + 1) + "]";
1263 | finalAnswer += ";[oute" + (i + 2) + "]format=rgba,fade=t=in:st=" + f + ":d=" + 2 + ":alpha=1[aoute" + (i + 2) + "];"
1264 | finalAnswer += "[aoute" + (i + 1) + "][aoute" + (i + 2) + "]overlay=enable='between(t\\," + f + "," + (user.total_sec) + ")'" + overLayY + "[" + nextParam + (i + 2) + "];";
1265 |
1266 | } else {
1267 | finalAnswer += "[oute" + (i + 1) + "][oute" + (i + 2) + "]overlay=enable='between(t\\," + f + "," + (user.total_sec) + ")'" + overLayY + "[" + nextParam + (i + 2) + "];";
1268 | }
1269 |
1270 | lastP = "[outnje" + (i + 2) + "]";
1271 | }
1272 |
1273 |
1274 | }
1275 |
1276 | }
1277 | }
1278 | let ap = []
1279 | if (this.global_data.source.length > 0) {
1280 | ap.push("-map", (lmS + 1) + ":a")
1281 | }
1282 | let finalLine = ["-y", "-r", "30", "-f", "lavfi", "-i", "color=black:s=" + user.iWidth + "x" + user.iHeight]
1283 | finalLine.push(...addition);
1284 | let fileName = "1080p";
1285 | if (isPreview)
1286 | fileName = "270p";
1287 | globalFilters = "yuv444p";
1288 | finalLine.push("-filter_complex", finalAnswer.substr(0, finalAnswer.length - 1), "-map", lastP, ...ap, "-t", user.total_sec, "-profile:v", "baseline", "-level", "3.0", "-movflags", "+faststart", "-pix_fmt", "yuv420p", Config.output_directory + path.sep + id + path.sep + fileName + ".mp4");
1289 | return finalLine;
1290 | }
1291 | }
1292 | module.exports = AnimBulletin;
--------------------------------------------------------------------------------
/DemoOutputVideos/Type-Photo!AlignH-Center!AlignV-Center!Crop-Full/1080p.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shubhamdevhouse/Animated-VideoMaker/b89cc33c9cd1503cf576b0b0bb88bd8f3f29914c/DemoOutputVideos/Type-Photo!AlignH-Center!AlignV-Center!Crop-Full/1080p.mp4
--------------------------------------------------------------------------------
/DemoOutputVideos/Type-Photo!AlignH-Left!AlignV-Top!Crop-Full/1080p.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shubhamdevhouse/Animated-VideoMaker/b89cc33c9cd1503cf576b0b0bb88bd8f3f29914c/DemoOutputVideos/Type-Photo!AlignH-Left!AlignV-Top!Crop-Full/1080p.mp4
--------------------------------------------------------------------------------
/DemoOutputVideos/Type-Photo!AlignH-Right!AlignV-Bottom!Crop-Full/1080p.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shubhamdevhouse/Animated-VideoMaker/b89cc33c9cd1503cf576b0b0bb88bd8f3f29914c/DemoOutputVideos/Type-Photo!AlignH-Right!AlignV-Bottom!Crop-Full/1080p.mp4
--------------------------------------------------------------------------------
/DemoOutputVideos/Type-Video!AlignH-Center!AlignV-Center!Crop-Full/1080p.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shubhamdevhouse/Animated-VideoMaker/b89cc33c9cd1503cf576b0b0bb88bd8f3f29914c/DemoOutputVideos/Type-Video!AlignH-Center!AlignV-Center!Crop-Full/1080p.mp4
--------------------------------------------------------------------------------
/DemoOutputVideos/Type-Video!AlignH-Left!AlignV-Top!Crop-FitToFrame/1080p.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shubhamdevhouse/Animated-VideoMaker/b89cc33c9cd1503cf576b0b0bb88bd8f3f29914c/DemoOutputVideos/Type-Video!AlignH-Left!AlignV-Top!Crop-FitToFrame/1080p.mp4
--------------------------------------------------------------------------------
/DemoOutputVideos/Type-Video!AlignH-Left!AlignV-Top!Crop-Full/1080p.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shubhamdevhouse/Animated-VideoMaker/b89cc33c9cd1503cf576b0b0bb88bd8f3f29914c/DemoOutputVideos/Type-Video!AlignH-Left!AlignV-Top!Crop-Full/1080p.mp4
--------------------------------------------------------------------------------
/DemoOutputVideos/Type-Video!AlignH-Left!AlignV-Top!Crop-Left/1080p.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shubhamdevhouse/Animated-VideoMaker/b89cc33c9cd1503cf576b0b0bb88bd8f3f29914c/DemoOutputVideos/Type-Video!AlignH-Left!AlignV-Top!Crop-Left/1080p.mp4
--------------------------------------------------------------------------------
/DemoOutputVideos/Type-Video!AlignH-Left!AlignV-Top!Crop-Right/1080p.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shubhamdevhouse/Animated-VideoMaker/b89cc33c9cd1503cf576b0b0bb88bd8f3f29914c/DemoOutputVideos/Type-Video!AlignH-Left!AlignV-Top!Crop-Right/1080p.mp4
--------------------------------------------------------------------------------
/DemoOutputVideos/Type-Video!AlignH-Right!AlignV-Bottom!Crop-Full/1080p.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shubhamdevhouse/Animated-VideoMaker/b89cc33c9cd1503cf576b0b0bb88bd8f3f29914c/DemoOutputVideos/Type-Video!AlignH-Right!AlignV-Bottom!Crop-Full/1080p.mp4
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Shubham Dawra
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Animated VideoMaker
2 | ### Create animatied text videos like Animoto using NodeJS -> ImageMagick & Ffmpeg
3 |
4 | Note: On low configuration machine it can take time to process frames because it uses imagemagick to generate frame by frame transition or movement animation and after generating all blocks animation it merges them in a Video.
5 | # Installation
6 | # Prerequisite
7 | **Install ImageMagick-7.1.0-Q16**
8 | **Install Ffmpeg-20180209-e752da5**
9 | **Download "Roboto" font**
10 | Install RabbitMQ 3.8.2
11 | Install imagemagick & extract ffmpeg
12 | ```
13 | Open config.js and edit
14 | ffmpeg_path = "Installed path" (E:\\Ffmpeg\\ffmpeg.exe) Line : 3
15 | magick_path = "Installed path" (E:\\Imagemagick\\magick.exe) Line : 5
16 | convert_path = "Installed path" (E:\\Imagemagick\\convert.exe) Line : 4
17 | roboto_light = Robot Light font ttf file (E:\\Font\\Robot-Light.ttf) Line : 8
18 | roboto_bold = Robot Bold font ttf file (E:\\Font\\Robot-Bold.ttf) Line : 7
19 | socket_ip = Get current local ip of your local computer (ipconfig) Line : 10
20 | port = Port number must be same used in socket IP Line : 20
21 | ```
22 | Open console window cd in the directory & run npm install
23 |
24 | After that run command npm run start in one console window
25 |
26 | run second command in other console window npm run worker
27 |
28 | Run your ip address and port like http://192.168.1.107:82/assets/
29 |
30 | Put video or pic url in url box
31 |
32 | Select Type photo or video
33 |
34 | Put timing greater then 3 and less then 15 (Use less timing if you are on low configured machine because it take too much time too process frames and merge them in a video)
35 |
36 | **Font size = Main text font size**
37 |
38 | **Title = Animated text for main line**
39 |
40 | **Sub font size = Sub text font size**
41 |
42 | **Sub Title = Animated text for sub text line**
43 |
44 | **Horizontal alignment of text = Left Right or Center**
45 |
46 | **Vertical alignment of text = Top Bottom or Center**
47 |
48 | **Crop style you can check demo videos**
49 |
50 | **Click on Add Row** to add blocks like first is photo and second is video then photo or ...
51 |
52 | **Click on Submit HD Video** to generate frames and merge them in video in 1080,720,360,240 resolution
53 |
54 | # Demo Videos
55 |
56 | Video = Type || Alignment Horizontal = Left || Alignment Vertical = Top || Crop = Full
57 |
58 | https://user-images.githubusercontent.com/35697452/144758975-e5889178-a94d-4251-a88d-ea842378e59e.mp4
59 |
60 | Video = Type || Alignment Horizontal = Right || Alignment Vertical = Bottom || Crop = Full
61 |
62 | https://user-images.githubusercontent.com/35697452/144758981-95b17aad-44c2-4d9f-81a9-806392ef45c7.mp4
63 |
64 | Video = Type || Alignment Horizontal = Center || Alignment Vertical = Center || Crop = Full
65 |
66 | https://user-images.githubusercontent.com/35697452/144759017-28af9cf8-67ec-4ffb-b0e0-992885fc607f.mp4
67 |
68 | Video = Type || Alignment Horizontal = Left || Alignment Vertical = Top || Crop = Fitoframe
69 |
70 | https://user-images.githubusercontent.com/35697452/144759039-3b727d45-6fbb-4ded-a9ce-de1f129177da.mp4
71 |
72 | Video = Type || Alignment Horizontal = Left || Alignment Vertical = Top || Crop = Left
73 |
74 | https://user-images.githubusercontent.com/35697452/144759070-eaed6e25-4f8d-4b82-92bb-c58c2e61bae9.mp4
75 |
76 | Photo = Type || Alignment Horizontal = Left || Alignment Vertical = Top || Crop = Full
77 |
78 | https://user-images.githubusercontent.com/35697452/144759162-d7b1d94e-1c75-4c5b-9126-3756bf8382ea.mp4
79 |
80 | Photo = Type || Alignment Horizontal = Right || Alignment Vertical = Bottom || Crop = Full
81 |
82 | https://user-images.githubusercontent.com/35697452/144759177-bdbac2ef-16c6-43de-ac40-6632fb7be7d7.mp4
83 |
84 | Photo = Type || Alignment Horizontal = Center || Alignment Vertical = Center || Crop = Full
85 |
86 | https://user-images.githubusercontent.com/35697452/144759184-6b4241ac-5817-4bea-ac19-0a066db46740.mp4
87 |
88 |
89 |
90 | # Todo :
91 |
92 | ### More animation theme.
93 |
94 | ### Optimization & cleaning of code.
95 |
--------------------------------------------------------------------------------
/app.js:
--------------------------------------------------------------------------------
1 | const utils = require('./utils.js');
2 | const Config= require('./config.js');
3 | const AnimBulletin = require('./AnimationBulletin.js');
4 | const fs = require('fs').promises;
5 | let path = require('path');
6 | const express=require('express')
7 | let app =express();
8 | let amqp = require('amqplib/callback_api');
9 | app.use(express.json());
10 | app.use(function(req, res, next) {
11 | res.header("Access-Control-Allow-Origin", "*"); // update to match the domain you will make the request from
12 | res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
13 | next();
14 | });
15 | app.use('/assets',express.static(__dirname + path.sep+'assets'));
16 | let preview_status = [];
17 | let animBullet =new AnimBulletin("Bulletin");
18 | let dynamicJson='\'{"name":"Project Name","uploadedMedia":[{"type":"photo","thumbnail":"http://192.168.1.107:82/assets/Image/id/print.jpg","url":"http://192.168.1.107:82/assets/Image/id/print.jpg"},{"type":"video","thumbnail":"http://192.168.1.107:82/assets/Footage/id/o.jpg","url":"http://192.168.1.107:82/assets/Footage/id/720p-sample1.mp4"},{"type":"photo","thumbnail":"http://192.168.1.107:82/assets/Image/id/o.jpg","url":"http://192.168.1.107:82/assets/Image/id/o.jpg"},{"type":"video","thumbnail":"http://192.168.1.107:82/assets/Footage/id/360p-sample1.jpg","url":"http://192.168.1.107:82/assets/Footage/id/270p-sample1.mp4"}],"global":{"backgroundMusic":{"source":"http://192.168.1.107:82/assets/Audio/audio.mpeg","volume":0.5,"loop":true,"trimAudio":{"trim":false,"value":{"start":0,"end":34}}},"filter":"none","aspectRatio":"landscape","style":"hiRise","font":"Roboto","watermark":{"source":"xxx","position":"top-right","size":"medium","transparency":true}},"blocks":[]}\';';
19 | let server = require('http').Server(app);
20 | let io = require('socket.io')(server);
21 | server.listen(Config.port);
22 |
23 | let modifyIndex =()=>{
24 | let assetsTemplateIndex = __dirname + path.sep+'assets'+path.sep+'template_index';
25 | let assetsIndex = __dirname + path.sep+'assets'+path.sep+'index.html';
26 | fs.readFile(assetsTemplateIndex, 'utf8').then((data)=>{
27 | var result = data.replace(/192.168.1.107:82/g, Config.socket_ip);
28 |
29 | fs.writeFile(assetsIndex, result, 'utf8');
30 | });
31 |
32 | }
33 | let storeData = function (data, path) {
34 | fs.writeFile(path,JSON.stringify(data)).catch(function(){console.error(err)});
35 | }
36 | let writeFileData = function(is_preview,id,id_string){
37 | return new Promise(function(resolve,reject){
38 | console.log(Config.output_directory+'id',id,id_string);
39 | fs.writeFile(Config.output_directory+'id',id.toString()).then(()=>
40 | resolve({isPreview:is_preview,error:null, result:{status : "succeed",id:id_string}}))
41 | .catch(function(err){
42 | console.log(err);
43 | resolve({isPreview:is_preview,error:'error', result:{status : "error",id:id_string}});
44 | });
45 | })
46 | }
47 | let writeFolderId = function(is_preview,id) {
48 | return new Promise(function(resolve,reject){
49 | id=parseInt(id)+1;
50 | let id_string=id.toLocaleString('en-US', { minimumIntegerDigits: 10, useGrouping: false });
51 | let directory=Config.output_directory+id_string;
52 | utils.checkFileExists(directory).then(function(isExist){
53 | if(isExist){
54 | utils.deleteFolderRecursive(directory);
55 | fs.mkdir(directory).then(function(){
56 | fs.mkdir(directory+path.sep+"data"+path.sep);
57 | writeFileData(is_preview,id,id_string).then(function(val){
58 | resolve(val);
59 | });
60 | });
61 | }else{
62 | fs.mkdir(directory).then(function(){
63 | fs.mkdir(directory+path.sep+"data"+path.sep);
64 | writeFileData(is_preview,id,id_string).then(function(val){
65 | resolve(val);
66 | });
67 | }).catch(function(err){
68 | console.log(err);
69 | });
70 | }
71 | });
72 | });
73 | };
74 | modifyIndex();
75 | app.get('/:id/:file', function (req, res) {
76 | let id = req.params.id
77 | let file = req.params.file
78 | let fileDownload = __dirname + path.sep+'download' + path.sep+id+ path.sep+file;
79 | res.download(fileDownload);
80 |
81 |
82 | });
83 | app.get('/', function (req, res) {
84 | let jsonString='{"name":"Project Name","uploadedMedia":[{"type":"image","thumbnail":"http://localhost:82/assets/Image/id/print.jpg","url":"http://localhost:82/assets/Image/id/print.jpg"},{"type":"video","thumbnail":"http://localhost:82/assets/Footage/id/o.jpg","url":"http://localhost:82/assets/Footage/id/720p-sample1.mp4"},{"type":"image","thumbnail":"http://localhost:82/assets/Image/id/o.jpg","url":"http://localhost:82/assets/Image/id/o.jpg"},{"type":"video","thumbnail":"http://localhost:82/assets/Footage/id/360p-sample1.jpg","url":"http://localhost:82/assets/Footage/id/270p-sample1.mp4"}],"global":{"backgroundMusic":{"source":"http://localhost:82/assets/audio/audio.mpeg","volume":0.5,"loop":true,"trimAudio":{"trim":false,"value":{"start":0,"end":34}}},"filter":"none","aspectRatio":"landscape","style":"hiRise","font":"Roboto","watermark":{"source":"xxx","position":"top-right","size":"medium","transparency":true}},"blocks":[{"id":0,"type":"image","timing":3,"voiceover":{"present":false,"source":"","volume":1},"text":{"title":{"content":"Title text","fontSize":50,"color":"#ffffff"},"subTitle":{"content":"subtitle text","fontSize":20,"color":"#ffffff"},"legibility":false,"legibilityColor":"#000","accent":"#F8AF00","align":{"vertical":"center","horizontal":"center"}},"background":{"media":"http://localhost:82/assets/Image/id/print.jpg","scale":1,"position":{"x":0,"y":0},"rotate":0,"crop":"Fullscreen","color":"#ccc"}},{"id":1,"type":"video","timing":10,"trim":{"start":0,"end":10},"voiceover":{"present":false,"source":"","volume":1},"text":{"title":{"content":"Title text","fontSize":50,"color":"#ffffff"},"subTitle":{"content":"subtitle text","fontSize":20,"color":"#ffffff"},"legibility":false,"legibilityColor":"#000","accent":"#F8AF00","align":{"vertical":"center","horizontal":"center"}},"background":{"media":"http://localhost:82/assets/Footage/id/720p-sample1.mp4","sound":false,"volume":1,"scale":1,"position":{"x":0,"y":0},"rotate":0,"crop":"Fullscreen","color":"#ccc"}},{"id":2,"type":"image","timing":3,"voiceover":{"present":false,"source":"","volume":1},"text":{"title":{"content":"Title text","fontSize":50,"color":"#ffffff"},"subTitle":{"content":"subtitle text","fontSize":20,"color":"#ffffff"},"legibility":false,"legibilityColor":"#000","accent":"#F8AF00","align":{"vertical":"center","horizontal":"center"}},"background":{"media":"http://localhost:82/assets/Image/id/o.jpg","scale":1,"position":{"x":0,"y":0},"rotate":0,"crop":"Fullscreen","color":"#ccc"}},{"id":3,"type":"video","timing":10,"trim":{"start":0,"end":10},"voiceover":{"present":false,"source":"","volume":1},"text":{"title":{"content":"Title text","fontSize":50,"color":"#ffffff"},"subTitle":{"content":"subtitle text","fontSize":20,"color":"#ffffff"},"legibility":false,"legibilityColor":"#000","accent":"#F8AF00","align":{"vertical":"center","horizontal":"center"}},"background":{"media":"http://localhost:82/assets/Footage/id/270p-sample1.mp4","sound":false,"volume":1,"scale":1,"position":{"x":0,"y":0},"rotate":0,"crop":"Fullscreen","color":"#ccc"}}]}';
85 | res.send(
86 | "
"
87 | +"
")})
90 | app.post(/^\/(upload|preview)\_json$/, function (req, res) {
91 | let path=req.path.substring(1)
92 | if(path=="upload_json"){
93 | uploadJson(req.body,res,false)
94 | }else{
95 | uploadJson(req.body,res,true,false)
96 | }
97 | });
98 |
99 | let uploadJson = async function(json,res,isPreview=false,isTesting=false){
100 | console.log(isPreview,"PREVIEW");
101 | if(Config.connection!=null){
102 | processJson(json,res,isPreview,isTesting);
103 | }else{
104 | amqp.connect('amqp://localhost', function(error0, connection) {
105 | if (error0) {
106 | throw(error0);
107 | }
108 | connection.createChannel(function(error1, channel) {
109 | Config.ch=channel
110 | if (error1) {
111 | throw(error1);
112 | }
113 | processJson(json,res,isPreview,isTesting);
114 | })
115 | });
116 | }
117 | }
118 |
119 | let processJson = async function (json,res,is_preview=false,isTesting=false){
120 | let id="0";
121 | let pathUID=Config.output_directory+"id";
122 | let fileExistPromise = utils.checkFileExists(pathUID);
123 | fileExistPromise.then(function(value){
124 | let idNumberPromise = fs.readFile(pathUID);
125 | idNumberPromise.catch(function(err){
126 | }).then(function(idNumber){
127 | writeFolderId(is_preview,idNumber.toString().trim()).then(function(response){
128 | if(response.err){
129 | console.log("Already Exists");
130 | let js={id:"none",socket_url:Config.socket_ip};
131 | res.send(js);
132 | }else{
133 | console.log("Saved");
134 | id=response.result.id
135 | let js={id:response.result.id,socket_url:Config.socket_ip}
136 | res.send(js)
137 | storeData(json,path.join(__dirname, 'download')+ path.sep+id+ path.sep+"data"+path.sep+"data.json")
138 | preview_status[id] = response.isPreview;
139 | dataUploaded()
140 | }
141 | }).catch(function(obj){
142 | console.log(obj);
143 | });
144 | });
145 | })
146 | .catch(function(value){
147 | writeFolderId(is_preview,id.toString().trim()).then(function(value){
148 | if(value.err){
149 | console.log("Already Exists")
150 | let js={id:"none",socket_url:Config.socket_ip}
151 | res.send(js)
152 | }else{
153 | console.log("Saved")
154 | id=value.result.id
155 | let js={id:value.result.id,socket_url:Config.socket_ip}
156 | res.send(js)
157 | storeData(json,path.join(__dirname, 'download')+ path.sep+id+path.sep+"data"+path.sep+"data.json");
158 | preview_status[id] = value.isPreview;
159 | dataUploaded();
160 | }
161 | }).catch(function(obj){
162 | console.log(obj);
163 | });
164 | });
165 | }
166 |
167 | let dataUploaded = function(){
168 | io.use(function(socket, next){
169 | let id = socket.handshake.query.id
170 | let isPreview=preview_status[id];
171 | if(typeof(socket)==="undefined"){
172 | console.log("Undefined")
173 | }else{
174 | if(typeof(Config.users[id])==="undefined"){
175 | let obj={}
176 | obj.blockList=[]
177 | obj.socket = socket;
178 | Config.users[id]=(obj)
179 | if(isPreview){
180 | animBullet.run(id,true);
181 | }else{
182 | animBullet.run(id,false);
183 | }
184 | }
185 | }
186 |
187 |
188 | io.on('connection', function (socket) {
189 | if(!Config.users[id]){
190 | if(isPreview){
191 | Config.users[id].socket.emit('status', {'status':'started',
192 | 'is_preview':'true'
193 | ,video_url:{url:'none'} });
194 | }else{
195 | Config.users[id].socket.emit('status', {'status':'started',
196 | videos_progress:{'360p':0,'480p':0,'720p':0,'1080p':0}
197 | ,videos_url:{'360p':'none','480p':'none','720p':'none','1080p':'none'} });
198 | }
199 | console.log("Connected");
200 | }
201 | });
202 | next();
203 | });
204 | }
205 |
206 | io.on('disconnect', function () {
207 | Config.users[current.id].socket.removeAllListeners();
208 | Config.users[current.id].socket.disconnect()
209 | Config.users.splice(current.id,1)
210 | preview_status.splice(current.id,1)
211 | });
--------------------------------------------------------------------------------
/assets/Audio/audio.mpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shubhamdevhouse/Animated-VideoMaker/b89cc33c9cd1503cf576b0b0bb88bd8f3f29914c/assets/Audio/audio.mpeg
--------------------------------------------------------------------------------
/assets/Font/Roboto-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shubhamdevhouse/Animated-VideoMaker/b89cc33c9cd1503cf576b0b0bb88bd8f3f29914c/assets/Font/Roboto-Bold.ttf
--------------------------------------------------------------------------------
/assets/Font/Roboto-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shubhamdevhouse/Animated-VideoMaker/b89cc33c9cd1503cf576b0b0bb88bd8f3f29914c/assets/Font/Roboto-Light.ttf
--------------------------------------------------------------------------------
/assets/Footage/id/720p-sample1.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shubhamdevhouse/Animated-VideoMaker/b89cc33c9cd1503cf576b0b0bb88bd8f3f29914c/assets/Footage/id/720p-sample1.mp4
--------------------------------------------------------------------------------
/assets/Image/id/block_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shubhamdevhouse/Animated-VideoMaker/b89cc33c9cd1503cf576b0b0bb88bd8f3f29914c/assets/Image/id/block_1.jpg
--------------------------------------------------------------------------------
/assets/Image/id/block_3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shubhamdevhouse/Animated-VideoMaker/b89cc33c9cd1503cf576b0b0bb88bd8f3f29914c/assets/Image/id/block_3.jpg
--------------------------------------------------------------------------------
/assets/Image/id/o.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shubhamdevhouse/Animated-VideoMaker/b89cc33c9cd1503cf576b0b0bb88bd8f3f29914c/assets/Image/id/o.jpg
--------------------------------------------------------------------------------
/assets/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
232 |
233 |
234 |
235 |
236 | Source URL |
237 | Type |
238 | Timing |
239 | Title |
240 | Subtitle |
241 | Alignment Horizontal |
242 | Alignment Vertical |
243 | Crop |
244 | Style |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
329 |
330 |
335 |
--------------------------------------------------------------------------------
/assets/template_index:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
232 |
233 |
234 |
235 |
236 | Source URL |
237 | Type |
238 | Timing |
239 | Title |
240 | Subtitle |
241 | Alignment Horizontal |
242 | Alignment Vertical |
243 | Crop |
244 | Style |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
329 |
330 |
335 |
--------------------------------------------------------------------------------
/classes/Text.js:
--------------------------------------------------------------------------------
1 |
2 | const fs = require('fs');
3 | class Text {
4 |
5 | constructor(metricFile, fontSize = 50, defaultFontsize = 500) {
6 | this.fontSize = fontSize;
7 | this.defaultFontSize = defaultFontsize;
8 | this.text = "";
9 | this.lines = [];
10 | let self = this;
11 | fs.readFile(metricFile, { encoding: 'utf-8' }, function (err, data) {
12 | if (!err) {
13 | self.fontMetrics = JSON.parse(data);
14 | } else {
15 | console.log(err);
16 | }
17 | });
18 | }
19 | getMaxWidth = () => {
20 | return this.maxWidth;
21 | }
22 | setMaxWidth = (value) => {
23 | this.maxWidth = value;
24 | }
25 | getDefaultFontSize = () => {
26 | return this.defaultFontsize;
27 | }
28 | setDefaultFontSize = (value) => {
29 | this.defaultFontsize = value;
30 | }
31 | getFontSize = () => {
32 | return this.fontSize;
33 | }
34 | setFontSize = (value) => {
35 | this.fontSize = value;
36 | }
37 | getText = () => {
38 | return this.text;
39 | }
40 |
41 | setText = (value) => {
42 | this.text = value;
43 | }
44 |
45 | getMetricData = (word) => {
46 | let width = 0;
47 | let ascent = 0;
48 | let descent = 0;
49 |
50 | for (let i = 0; i < word.length; i++) {
51 | let charMetric = this.fontMetrics[word[i]];
52 | width += Math.round((charMetric.width / this.getDefaultFontSize()) * this.getFontSize());
53 | let optimizedAscent = Math.round((charMetric.ascent / this.getDefaultFontSize()) * this.getFontSize());
54 | let optimizedDescent = Math.round((charMetric.descent / this.getDefaultFontSize()) * this.getFontSize());
55 | if (optimizedAscent > ascent) {
56 | ascent = optimizedAscent;
57 | }
58 | if (optimizedDescent > descent) {
59 | descent = optimizedDescent;
60 | }
61 |
62 |
63 | }
64 | let metricObject = { width, ascent, descent };
65 | return metricObject;
66 | }
67 | validateWord = (splitted, word, index) => {
68 | let wordWidth = 0;
69 | if (index >= splitted.length) { return; }
70 | for (let i = 0; i < word.length; i++) {
71 | let charWidth = Math.round((this.fontMetrics[word[i]].width / this.getDefaultFontSize()) * this.getFontSize());
72 | if (wordWidth + charWidth >= this.getMaxWidth()) {
73 | let tempWord = word.substr(0, i);
74 | let restWord = word.substr(i);
75 | splitted.splice(index + 1, 0, restWord);
76 | splitted[index] = tempWord;
77 | break;
78 | } else { wordWidth += charWidth; }
79 | }
80 | this.validateWord(splitted, splitted[index + 1], index + 1);
81 |
82 | }
83 |
84 | getLine = (splitted, text, textWidth, index, oldMetricObj) => {
85 | let metricObj = this.getMetricData(splitted[index]);
86 |
87 | let wordWidth = metricObj.width;
88 | console.log(metricObj, "dataMetric");
89 | if (textWidth + wordWidth > this.getMaxWidth()) {
90 |
91 | let textSplit = text.split(" ");
92 | textSplit.pop();
93 |
94 | let textString = textSplit.join(" ");
95 | let widthWithSpace = textWidth + (textSplit.length * ((this.fontMetrics[" "].width / this.getDefaultFontSize()) * this.getFontSize()));
96 | console.log({ width: widthWithSpace, text: textString, ascent: oldMetricObj.ascent, descent: oldMetricObj.descent }, "NewLine");
97 |
98 | this.lines.push({ width: widthWithSpace, text: textString, ascent: oldMetricObj.ascent, descent: oldMetricObj.descent });
99 | return this.getLine(splitted, splitted[index], 0, index, metricObj);
100 |
101 | } else {
102 | if (index + 1 >= splitted.length) {
103 |
104 | let widthWithSpace = (wordWidth + textWidth) + ((text.split(" ").length - 1) * ((this.fontMetrics[" "].width / this.getDefaultFontSize()) * this.getFontSize()));
105 | console.log(wordWidth, textWidth, text, this.fontMetrics[" "].width);
106 | console.log({ width: widthWithSpace, text, ascent: metricObj.ascent, descent: metricObj.descent }, "NewLine");
107 | this.lines.push({ width: widthWithSpace, text, ascent: metricObj.ascent, descent: metricObj.descent });
108 | console.log(this.lines);
109 | return this.lines;
110 | }
111 |
112 | if (oldMetricObj.width > metricObj.width)
113 | metricObj.width = oldMetricObj.width
114 |
115 | if (oldMetricObj.ascent > metricObj.ascent)
116 | metricObj.ascent = oldMetricObj.ascent
117 |
118 | if (oldMetricObj.descent > metricObj.descent)
119 | metricObj.descent = oldMetricObj.descent
120 |
121 | return this.getLine(splitted, text + " " + splitted[index + 1], textWidth + wordWidth, index + 1, metricObj);
122 | }
123 | }
124 |
125 | generateText = (text, width, fontSize, defaultFontSize = 500) => {
126 | this.lines = [];
127 | this.setFontSize(fontSize);
128 | this.setMaxWidth(width);
129 | this.setDefaultFontSize(defaultFontSize);
130 | let splittedText = text.split(" ");
131 | this.validateWord(splittedText, splittedText[0], 0);
132 | return this.getLine(splittedText, splittedText[0], 0,0,{ width:0, ascent:0, descent:0 });
133 | }
134 |
135 |
136 |
137 |
138 | }
139 | module.exports = Text;
--------------------------------------------------------------------------------
/config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | class Config{
3 | static ffmpeg_path = "E:\\ffmpeg\\bin\\ffmpeg";
4 | static convert_path = "C:\\Program Files\\ImageMagick-7.1.0-Q16\\magick";
5 | static magick_path = "C:\\Program Files\\ImageMagick-7.1.0-Q16\\magick";
6 | static output_directory = path.join(__dirname, 'download')+path.sep;
7 | static roboto_bold = "E:\\animoto_reference\\Animated-VideoMaker\\assets\\Font\\Roboto-Bold.ttf";
8 | static roboto_light = "E:\\animoto_reference\\Animated-VideoMaker\\assets\\Font\\Roboto-Light.ttf";
9 | static roboto_bold_metric = "E:\\animoto_reference\\Animated-VideoMaker\\fontcode\\robotobold.json";
10 | static roboto_light_metric = "E:\\animoto_reference\\Animated-VideoMaker\\fontcode\\robotolight.json";
11 | static audio = "F:\\assets\\Audio\\audio.mpeg";
12 | static socket_ip="192.168.1.103:82";
13 | static users=[];
14 | static connecton=null;
15 | static ch=null;
16 | static extVideos=[".avi",".mov",".mp4"];
17 | static extImages=[".png",".jpg",".jpeg"];
18 | static hdWidth = 1920;
19 | static hdHeight = 1080;
20 | static previewWidth = 426;
21 | static previewHeight = 240;
22 | static port = 82;
23 | }
24 | module.exports=Config;
--------------------------------------------------------------------------------
/download/id:
--------------------------------------------------------------------------------
1 | 1
--------------------------------------------------------------------------------
/ffmpeg_wrapper.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | const stream_1 = require("stream");
4 | /**
5 | * convert HH:MM:SS.mss to milliseconds
6 | */
7 | function humanTime2msec(timeString) {
8 | const [h, m, s] = timeString.split(':').map(Number);
9 | return Math.round(h * 36e5 + m * 6e4 + s * 1e3);
10 | }
11 | /**
12 | *
13 | * @param data
14 | * @param duration video duration (milliseconds)
15 | */
16 | function parseProgress(data, duration,index) {
17 | if (data.startsWith('frame=')) {
18 | const evt = {};
19 | const info = data
20 | .replace(/=\s+/g, '=')
21 | .trim()
22 | .split(/\s+/g);
23 | info.forEach(kv => {
24 | const [k, v] = kv.split('=');
25 | switch (k) {
26 | case 'frame':
27 | case 'fps':
28 | evt[k] = +v;
29 | break;
30 | case 'bitrate':
31 | case 'speed':
32 | evt[k] = Number.parseFloat(v);
33 | break;
34 | case 'Lsize':
35 | case 'size':
36 | evt['size'] = Number.parseInt(v) * 1024;
37 | break;
38 | case 'total_size':
39 | evt['size'] = +v;
40 | break;
41 | case 'out_time':
42 | case 'time':
43 | evt['time'] = v;
44 | // eslint-disable-next-line @typescript-eslint/camelcase
45 | evt.time_ms = humanTime2msec(evt.time);
46 | break;
47 | default:
48 | if (v) {
49 | evt[k] = v;
50 | }
51 | break;
52 | }
53 | });
54 | evt.index=index
55 | if (duration) {
56 | evt.percentage = +((100 * evt.time_ms) / duration).toFixed(2);
57 | evt.remaining = Math.floor((duration - evt.time_ms) * evt.speed);
58 | }
59 | return evt;
60 | }
61 | return;
62 | }
63 | exports.parseProgress = parseProgress;
64 | /**
65 | * Extract progress status from FFMPEG stderr.
66 | * @public
67 | */
68 | class FFMpegProgress extends stream_1.Transform {
69 | /**
70 | * Creates an instance of FFMpegProgress.
71 | * @param duration - video duration (milliseconds)
72 | * If parameter is omitted - will attempt to auto-detect media duration
73 | */
74 | constructor(duration = 0,index=0) {
75 | super({
76 | readableObjectMode: true,
77 | writableObjectMode: true
78 | });
79 | this.duration = duration;
80 | this.index=index
81 | /**
82 | * last ffmpeg stderr message
83 | * @beta
84 | */
85 | this.exitMessage = '';
86 | }
87 | _transform(chunk, encoding, done) {
88 | const str = chunk.toString();
89 | const evt = parseProgress(str, this.duration,this.index);
90 | if (evt) {
91 | this.push(evt);
92 | }
93 | else {
94 | if (!this.duration && !evt) {
95 | const re = /(^|Duration: )(\d\d:\d\d:\d\d\.\d\d)/;
96 | const match = re.exec(str);
97 | if (match && match[2]) {
98 | this.duration = humanTime2msec(match[2]);
99 | }
100 | }
101 | this.exitMessage = str.split('\n').splice(-2)[0];
102 | }
103 | done();
104 | }
105 | }
106 | exports.FFMpeg_Wrapper = FFMpegProgress;
107 |
--------------------------------------------------------------------------------
/fontcode/generate.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const process = require( 'process' );
3 | const argv = key => {
4 | if ( process.argv.includes( `--${ key }` ) ) return true;
5 | const value = process.argv.find( element => element.startsWith( `--${ key }=` ) );
6 | if ( !value ) return null;
7 | return value.replace( `--${ key }=` , '' );
8 | }
9 | if(argv('font')==null){
10 | console.error("No font file found!");
11 | process.exit(1);
12 | }
13 | if(argv('output')==null){
14 | console.error("No output file name found!");
15 | process.exit(1);
16 | }
17 |
18 | const { createCanvas, registerFont } = require('canvas');
19 | //'../assets/Font/Roboto-Bold.ttf'
20 | registerFont(argv('font'), { family: 'Font' })
21 | let fontString = "~!@#$%^&*()-_+={}][|\`,./?;:'\"<>1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ";
22 | let fontData = {};
23 | const canvas = createCanvas(100, 100)
24 | const ctx = canvas.getContext('2d')
25 | ctx.font = '500px Font';
26 |
27 | for(let i=0;i{
37 | console.error(err);
38 | });
--------------------------------------------------------------------------------
/fontcode/metric.json:
--------------------------------------------------------------------------------
1 | {"0":{"baseLine":0,"width":11,"ascent":14,"descent":0},"1":{"baseLine":0,"width":11,"ascent":14,"descent":0},"2":{"baseLine":0,"width":11,"ascent":14,"descent":0},"3":{"baseLine":0,"width":11,"ascent":14,"descent":0},"4":{"baseLine":0,"width":11,"ascent":14,"descent":0},"5":{"baseLine":0,"width":11,"ascent":14,"descent":0},"6":{"baseLine":0,"width":11,"ascent":14,"descent":0},"7":{"baseLine":0,"width":11,"ascent":14,"descent":0},"8":{"baseLine":0,"width":11,"ascent":14,"descent":0},"9":{"baseLine":0,"width":11,"ascent":14,"descent":0},"~":{"baseLine":0,"width":13,"ascent":8,"descent":-4},"!":{"baseLine":0,"width":5,"ascent":14,"descent":0},"@":{"baseLine":0,"width":18,"ascent":14,"descent":4},"#":{"baseLine":0,"width":12,"ascent":14,"descent":0},"$":{"baseLine":0,"width":11,"ascent":16,"descent":2},"%":{"baseLine":0,"width":15,"ascent":14,"descent":0},"^":{"baseLine":0,"width":9,"ascent":14,"descent":-7},"&":{"baseLine":0,"width":13,"ascent":14,"descent":0},"*":{"baseLine":0,"width":9,"ascent":14,"descent":-6},"(":{"baseLine":0,"width":7,"ascent":16,"descent":4},")":{"baseLine":0,"width":7,"ascent":16,"descent":4},"-":{"baseLine":0,"width":8,"ascent":7,"descent":-5},"_":{"baseLine":0,"width":9,"ascent":0,"descent":2},"+":{"baseLine":0,"width":11,"ascent":12,"descent":-2},"=":{"baseLine":0,"width":11,"ascent":9,"descent":-3},"{":{"baseLine":0,"width":7,"ascent":16,"descent":4},"}":{"baseLine":0,"width":7,"ascent":16,"descent":4},"]":{"baseLine":0,"width":6,"ascent":17,"descent":3},"[":{"baseLine":0,"width":6,"ascent":17,"descent":3},"|":{"baseLine":0,"width":5,"ascent":14,"descent":3},"`":{"baseLine":0,"width":7,"ascent":15,"descent":-12},",":{"baseLine":0,"width":5,"ascent":3,"descent":3},".":{"baseLine":0,"width":6,"ascent":3,"descent":0},"/":{"baseLine":0,"width":7,"ascent":14,"descent":1},"?":{"baseLine":0,"width":10,"ascent":14,"descent":0},";":{"baseLine":0,"width":5,"ascent":11,"descent":3},":":{"baseLine":0,"width":6,"ascent":11,"descent":0},"'":{"baseLine":0,"width":3,"ascent":15,"descent":-10},"\"":{"baseLine":0,"width":6,"ascent":15,"descent":-10},"<":{"baseLine":0,"width":10,"ascent":11,"descent":-2},">":{"baseLine":0,"width":10,"ascent":11,"descent":-2},"a":{"baseLine":0,"width":11,"ascent":11,"descent":0},"b":{"baseLine":0,"width":11,"ascent":15,"descent":0},"c":{"baseLine":0,"width":10,"ascent":11,"descent":0},"d":{"baseLine":0,"width":11,"ascent":15,"descent":0},"e":{"baseLine":0,"width":11,"ascent":11,"descent":0},"f":{"baseLine":0,"width":7,"ascent":15,"descent":0},"g":{"baseLine":0,"width":11,"ascent":11,"descent":4},"h":{"baseLine":0,"width":11,"ascent":15,"descent":0},"i":{"baseLine":0,"width":5,"ascent":15,"descent":0},"j":{"baseLine":0,"width":5,"ascent":15,"descent":4},"k":{"baseLine":0,"width":11,"ascent":15,"descent":0},"l":{"baseLine":0,"width":5,"ascent":15,"descent":0},"m":{"baseLine":0,"width":17,"ascent":11,"descent":0},"n":{"baseLine":0,"width":11,"ascent":11,"descent":0},"o":{"baseLine":0,"width":11,"ascent":11,"descent":0},"p":{"baseLine":0,"width":11,"ascent":11,"descent":4},"q":{"baseLine":0,"width":11,"ascent":11,"descent":4},"r":{"baseLine":0,"width":7,"ascent":11,"descent":0},"s":{"baseLine":0,"width":10,"ascent":11,"descent":0},"t":{"baseLine":0,"width":7,"ascent":14,"descent":0},"u":{"baseLine":0,"width":11,"ascent":11,"descent":0},"v":{"baseLine":0,"width":10,"ascent":11,"descent":0},"w":{"baseLine":0,"width":15,"ascent":11,"descent":0},"x":{"baseLine":0,"width":10,"ascent":11,"descent":0},"y":{"baseLine":0,"width":10,"ascent":11,"descent":4},"z":{"baseLine":0,"width":10,"ascent":11,"descent":0},"A":{"baseLine":0,"width":13,"ascent":14,"descent":0},"B":{"baseLine":0,"width":13,"ascent":14,"descent":0},"C":{"baseLine":0,"width":13,"ascent":14,"descent":0},"D":{"baseLine":0,"width":13,"ascent":14,"descent":0},"E":{"baseLine":0,"width":11,"ascent":14,"descent":0},"F":{"baseLine":0,"width":11,"ascent":14,"descent":0},"G":{"baseLine":0,"width":14,"ascent":14,"descent":0},"H":{"baseLine":0,"width":14,"ascent":14,"descent":0},"I":{"baseLine":0,"width":6,"ascent":14,"descent":0},"J":{"baseLine":0,"width":11,"ascent":14,"descent":0},"K":{"baseLine":0,"width":13,"ascent":14,"descent":0},"L":{"baseLine":0,"width":11,"ascent":14,"descent":0},"M":{"baseLine":0,"width":18,"ascent":14,"descent":0},"N":{"baseLine":0,"width":14,"ascent":14,"descent":0},"O":{"baseLine":0,"width":14,"ascent":14,"descent":0},"P":{"baseLine":0,"width":13,"ascent":14,"descent":0},"Q":{"baseLine":0,"width":14,"ascent":14,"descent":2},"R":{"baseLine":0,"width":13,"ascent":14,"descent":0},"S":{"baseLine":0,"width":12,"ascent":14,"descent":0},"T":{"baseLine":0,"width":12,"ascent":14,"descent":0},"U":{"baseLine":0,"width":13,"ascent":14,"descent":0},"V":{"baseLine":0,"width":13,"ascent":14,"descent":0},"W":{"baseLine":0,"width":17,"ascent":14,"descent":0},"X":{"baseLine":0,"width":13,"ascent":14,"descent":0},"Y":{"baseLine":0,"width":12,"ascent":14,"descent":0},"Z":{"baseLine":0,"width":12,"ascent":14,"descent":0}," ":{"baseLine":0,"width":5,"ascent":0,"descent":1}}
--------------------------------------------------------------------------------
/fontcode/robotobold.json:
--------------------------------------------------------------------------------
1 | {"0":{"baseLine":-11,"width":287,"ascent":360,"descent":5},"1":{"baseLine":-11,"width":287,"ascent":356,"descent":0},"2":{"baseLine":-11,"width":287,"ascent":360,"descent":0},"3":{"baseLine":-11,"width":287,"ascent":360,"descent":5},"4":{"baseLine":-11,"width":287,"ascent":355,"descent":0},"5":{"baseLine":-11,"width":287,"ascent":355,"descent":5},"6":{"baseLine":-11,"width":287,"ascent":359,"descent":5},"7":{"baseLine":-11,"width":287,"ascent":355,"descent":0},"8":{"baseLine":-11,"width":287,"ascent":360,"descent":5},"9":{"baseLine":-11,"width":287,"ascent":360,"descent":3},"~":{"baseLine":-11,"width":324,"ascent":202,"descent":-93},"!":{"baseLine":-11,"width":136,"ascent":355,"descent":4},"@":{"baseLine":-11,"width":448,"ascent":346,"descent":110},"#":{"baseLine":-11,"width":298,"ascent":355,"descent":0},"$":{"baseLine":-11,"width":287,"ascent":412,"descent":53},"%":{"baseLine":-11,"width":369,"ascent":361,"descent":5},"^":{"baseLine":-11,"width":219,"ascent":355,"descent":-178},"&":{"baseLine":-11,"width":328,"ascent":360,"descent":5},"*":{"baseLine":-11,"width":227,"ascent":355,"descent":-139},"(":{"baseLine":-11,"width":176,"ascent":395,"descent":111},")":{"baseLine":-11,"width":176,"ascent":395,"descent":111},"-":{"baseLine":-11,"width":194,"ascent":181,"descent":-124},"_":{"baseLine":-11,"width":223,"ascent":0,"descent":55},"+":{"baseLine":-11,"width":273,"ascent":294,"descent":-35},"=":{"baseLine":-11,"width":286,"ascent":240,"descent":-77},"{":{"baseLine":-11,"width":165,"ascent":390,"descent":88},"}":{"baseLine":-11,"width":165,"ascent":390,"descent":88},"]":{"baseLine":-11,"width":139,"ascent":414,"descent":83},"[":{"baseLine":-11,"width":139,"ascent":414,"descent":83},"|":{"baseLine":-11,"width":126,"ascent":355,"descent":66},"`":{"baseLine":-11,"width":165,"ascent":375,"descent":-299},",":{"baseLine":-11,"width":122,"ascent":60,"descent":89},".":{"baseLine":-11,"width":145,"ascent":72,"descent":3},"/":{"baseLine":-11,"width":187,"ascent":355,"descent":31},"?":{"baseLine":-11,"width":249,"ascent":360,"descent":3},";":{"baseLine":-11,"width":131,"ascent":272,"descent":89},":":{"baseLine":-11,"width":141,"ascent":272,"descent":3},"'":{"baseLine":-11,"width":81,"ascent":375,"descent":-240},"\"":{"baseLine":-11,"width":160,"ascent":375,"descent":-241},"<":{"baseLine":-11,"width":254,"ascent":269,"descent":-33},">":{"baseLine":-11,"width":258,"ascent":269,"descent":-33},"a":{"baseLine":-11,"width":268,"ascent":269,"descent":5},"b":{"baseLine":-11,"width":281,"ascent":375,"descent":5},"c":{"baseLine":-11,"width":261,"ascent":269,"descent":5},"d":{"baseLine":-11,"width":282,"ascent":375,"descent":5},"e":{"baseLine":-11,"width":270,"ascent":269,"descent":5},"f":{"baseLine":-11,"width":179,"ascent":380,"descent":0},"g":{"baseLine":-11,"width":285,"ascent":269,"descent":104},"h":{"baseLine":-11,"width":280,"ascent":375,"descent":0},"i":{"baseLine":-11,"width":133,"ascent":370,"descent":0},"j":{"baseLine":-11,"width":130,"ascent":370,"descent":107},"k":{"baseLine":-11,"width":267,"ascent":375,"descent":0},"l":{"baseLine":-11,"width":133,"ascent":375,"descent":0},"m":{"baseLine":-11,"width":433,"ascent":269,"descent":0},"n":{"baseLine":-11,"width":280,"ascent":269,"descent":0},"o":{"baseLine":-11,"width":283,"ascent":269,"descent":5},"p":{"baseLine":-11,"width":281,"ascent":269,"descent":102},"q":{"baseLine":-11,"width":282,"ascent":269,"descent":102},"r":{"baseLine":-11,"width":182,"ascent":269,"descent":0},"s":{"baseLine":-11,"width":257,"ascent":269,"descent":5},"t":{"baseLine":-11,"width":169,"ascent":329,"descent":5},"u":{"baseLine":-11,"width":280,"ascent":264,"descent":5},"v":{"baseLine":-11,"width":253,"ascent":264,"descent":0},"w":{"baseLine":-11,"width":367,"ascent":264,"descent":0},"x":{"baseLine":-11,"width":254,"ascent":264,"descent":0},"y":{"baseLine":-11,"width":251,"ascent":264,"descent":107},"z":{"baseLine":-11,"width":254,"ascent":264,"descent":0},"A":{"baseLine":-11,"width":336,"ascent":355,"descent":0},"B":{"baseLine":-11,"width":319,"ascent":355,"descent":0},"C":{"baseLine":-11,"width":327,"ascent":360,"descent":5},"D":{"baseLine":-11,"width":325,"ascent":355,"descent":0},"E":{"baseLine":-11,"width":281,"ascent":355,"descent":0},"F":{"baseLine":-11,"width":274,"ascent":355,"descent":0},"G":{"baseLine":-11,"width":341,"ascent":360,"descent":5},"H":{"baseLine":-11,"width":353,"ascent":355,"descent":0},"I":{"baseLine":-11,"width":146,"ascent":355,"descent":0},"J":{"baseLine":-11,"width":279,"ascent":355,"descent":5},"K":{"baseLine":-11,"width":317,"ascent":355,"descent":0},"L":{"baseLine":-11,"width":271,"ascent":355,"descent":0},"M":{"baseLine":-11,"width":438,"ascent":355,"descent":0},"N":{"baseLine":-11,"width":353,"ascent":355,"descent":0},"O":{"baseLine":-11,"width":345,"ascent":360,"descent":5},"P":{"baseLine":-11,"width":323,"ascent":355,"descent":0},"Q":{"baseLine":-11,"width":345,"ascent":360,"descent":64},"R":{"baseLine":-11,"width":319,"ascent":355,"descent":0},"S":{"baseLine":-11,"width":307,"ascent":360,"descent":5},"T":{"baseLine":-11,"width":309,"ascent":355,"descent":0},"U":{"baseLine":-11,"width":329,"ascent":355,"descent":5},"V":{"baseLine":-11,"width":327,"ascent":355,"descent":0},"W":{"baseLine":-11,"width":437,"ascent":355,"descent":0},"X":{"baseLine":-11,"width":318,"ascent":355,"descent":0},"Y":{"baseLine":-11,"width":309,"ascent":355,"descent":0},"Z":{"baseLine":-11,"width":303,"ascent":355,"descent":0}," ":{"baseLine":-11,"width":125,"ascent":0,"descent":1}}
--------------------------------------------------------------------------------
/fontcode/robotolight.json:
--------------------------------------------------------------------------------
1 | {"0":{"baseLine":-11,"width":287,"ascent":360,"descent":5},"1":{"baseLine":-11,"width":287,"ascent":356,"descent":0},"2":{"baseLine":-11,"width":287,"ascent":360,"descent":0},"3":{"baseLine":-11,"width":287,"ascent":360,"descent":5},"4":{"baseLine":-11,"width":287,"ascent":355,"descent":0},"5":{"baseLine":-11,"width":287,"ascent":355,"descent":5},"6":{"baseLine":-11,"width":287,"ascent":359,"descent":5},"7":{"baseLine":-11,"width":287,"ascent":355,"descent":0},"8":{"baseLine":-11,"width":287,"ascent":360,"descent":5},"9":{"baseLine":-11,"width":287,"ascent":360,"descent":3},"~":{"baseLine":-11,"width":324,"ascent":202,"descent":-93},"!":{"baseLine":-11,"width":136,"ascent":355,"descent":4},"@":{"baseLine":-11,"width":448,"ascent":346,"descent":110},"#":{"baseLine":-11,"width":298,"ascent":355,"descent":0},"$":{"baseLine":-11,"width":287,"ascent":412,"descent":53},"%":{"baseLine":-11,"width":369,"ascent":361,"descent":5},"^":{"baseLine":-11,"width":219,"ascent":355,"descent":-178},"&":{"baseLine":-11,"width":328,"ascent":360,"descent":5},"*":{"baseLine":-11,"width":227,"ascent":355,"descent":-139},"(":{"baseLine":-11,"width":176,"ascent":395,"descent":111},")":{"baseLine":-11,"width":176,"ascent":395,"descent":111},"-":{"baseLine":-11,"width":194,"ascent":181,"descent":-124},"_":{"baseLine":-11,"width":223,"ascent":0,"descent":55},"+":{"baseLine":-11,"width":273,"ascent":294,"descent":-35},"=":{"baseLine":-11,"width":286,"ascent":240,"descent":-77},"{":{"baseLine":-11,"width":165,"ascent":390,"descent":88},"}":{"baseLine":-11,"width":165,"ascent":390,"descent":88},"]":{"baseLine":-11,"width":139,"ascent":414,"descent":83},"[":{"baseLine":-11,"width":139,"ascent":414,"descent":83},"|":{"baseLine":-11,"width":126,"ascent":355,"descent":66},"`":{"baseLine":-11,"width":165,"ascent":375,"descent":-299},",":{"baseLine":-11,"width":122,"ascent":60,"descent":89},".":{"baseLine":-11,"width":145,"ascent":72,"descent":3},"/":{"baseLine":-11,"width":187,"ascent":355,"descent":31},"?":{"baseLine":-11,"width":249,"ascent":360,"descent":3},";":{"baseLine":-11,"width":131,"ascent":272,"descent":89},":":{"baseLine":-11,"width":141,"ascent":272,"descent":3},"'":{"baseLine":-11,"width":81,"ascent":375,"descent":-240},"\"":{"baseLine":-11,"width":160,"ascent":375,"descent":-241},"<":{"baseLine":-11,"width":254,"ascent":269,"descent":-33},">":{"baseLine":-11,"width":258,"ascent":269,"descent":-33},"a":{"baseLine":-11,"width":268,"ascent":269,"descent":5},"b":{"baseLine":-11,"width":281,"ascent":375,"descent":5},"c":{"baseLine":-11,"width":261,"ascent":269,"descent":5},"d":{"baseLine":-11,"width":282,"ascent":375,"descent":5},"e":{"baseLine":-11,"width":270,"ascent":269,"descent":5},"f":{"baseLine":-11,"width":179,"ascent":380,"descent":0},"g":{"baseLine":-11,"width":285,"ascent":269,"descent":104},"h":{"baseLine":-11,"width":280,"ascent":375,"descent":0},"i":{"baseLine":-11,"width":133,"ascent":370,"descent":0},"j":{"baseLine":-11,"width":130,"ascent":370,"descent":107},"k":{"baseLine":-11,"width":267,"ascent":375,"descent":0},"l":{"baseLine":-11,"width":133,"ascent":375,"descent":0},"m":{"baseLine":-11,"width":433,"ascent":269,"descent":0},"n":{"baseLine":-11,"width":280,"ascent":269,"descent":0},"o":{"baseLine":-11,"width":283,"ascent":269,"descent":5},"p":{"baseLine":-11,"width":281,"ascent":269,"descent":102},"q":{"baseLine":-11,"width":282,"ascent":269,"descent":102},"r":{"baseLine":-11,"width":182,"ascent":269,"descent":0},"s":{"baseLine":-11,"width":257,"ascent":269,"descent":5},"t":{"baseLine":-11,"width":169,"ascent":329,"descent":5},"u":{"baseLine":-11,"width":280,"ascent":264,"descent":5},"v":{"baseLine":-11,"width":253,"ascent":264,"descent":0},"w":{"baseLine":-11,"width":367,"ascent":264,"descent":0},"x":{"baseLine":-11,"width":254,"ascent":264,"descent":0},"y":{"baseLine":-11,"width":251,"ascent":264,"descent":107},"z":{"baseLine":-11,"width":254,"ascent":264,"descent":0},"A":{"baseLine":-11,"width":336,"ascent":355,"descent":0},"B":{"baseLine":-11,"width":319,"ascent":355,"descent":0},"C":{"baseLine":-11,"width":327,"ascent":360,"descent":5},"D":{"baseLine":-11,"width":325,"ascent":355,"descent":0},"E":{"baseLine":-11,"width":281,"ascent":355,"descent":0},"F":{"baseLine":-11,"width":274,"ascent":355,"descent":0},"G":{"baseLine":-11,"width":341,"ascent":360,"descent":5},"H":{"baseLine":-11,"width":353,"ascent":355,"descent":0},"I":{"baseLine":-11,"width":146,"ascent":355,"descent":0},"J":{"baseLine":-11,"width":279,"ascent":355,"descent":5},"K":{"baseLine":-11,"width":317,"ascent":355,"descent":0},"L":{"baseLine":-11,"width":271,"ascent":355,"descent":0},"M":{"baseLine":-11,"width":438,"ascent":355,"descent":0},"N":{"baseLine":-11,"width":353,"ascent":355,"descent":0},"O":{"baseLine":-11,"width":345,"ascent":360,"descent":5},"P":{"baseLine":-11,"width":323,"ascent":355,"descent":0},"Q":{"baseLine":-11,"width":345,"ascent":360,"descent":64},"R":{"baseLine":-11,"width":319,"ascent":355,"descent":0},"S":{"baseLine":-11,"width":307,"ascent":360,"descent":5},"T":{"baseLine":-11,"width":309,"ascent":355,"descent":0},"U":{"baseLine":-11,"width":329,"ascent":355,"descent":5},"V":{"baseLine":-11,"width":327,"ascent":355,"descent":0},"W":{"baseLine":-11,"width":437,"ascent":355,"descent":0},"X":{"baseLine":-11,"width":318,"ascent":355,"descent":0},"Y":{"baseLine":-11,"width":309,"ascent":355,"descent":0},"Z":{"baseLine":-11,"width":303,"ascent":355,"descent":0}," ":{"baseLine":-11,"width":125,"ascent":0,"descent":1}}
--------------------------------------------------------------------------------
/multi_worker.js:
--------------------------------------------------------------------------------
1 | const worker=require("./worker.js")
2 | worker();
3 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "animoto_clone",
3 | "version": "1.0.0",
4 | "main": "app.js",
5 | "scripts": {
6 | "start": "nodemon --max_old_space_size=4096 app.js",
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "worker": "nodemon --max_old_space_size=2094 multi_worker.js"
9 | },
10 | "nodemonConfig": {
11 | "ignore": [
12 | "download/*"
13 | ]
14 | },
15 | "keywords": [],
16 | "author": "",
17 | "license": "ISC",
18 | "dependencies": {
19 | "@mixmaxhq/promise-pool": "^2.0.0",
20 | "amqplib": "^0.5.5",
21 | "canvas": "^2.9.1",
22 | "detect-kerning": "^2.1.2",
23 | "dotenv": "^8.2.0",
24 | "express": "^4.17.1",
25 | "fontkit": "^1.8.0",
26 | "gearmanode": "^0.9.2",
27 | "get-video-dimensions": "^1.0.0",
28 | "image-size": "^0.8.3",
29 | "moment": "^2.24.0",
30 | "moment-duration-format": "^2.3.2",
31 | "rimraf": "^3.0.2",
32 | "socket.io": "^2.3.0",
33 | "winston": "^0.7.1",
34 | "yargs": "^15.0.2"
35 | },
36 | "devDependencies": {
37 | "font-metrics": "^0.4.3"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/utils.js:
--------------------------------------------------------------------------------
1 | const config = require('./config.js')
2 |
3 | const http = require('http');
4 | const https = require('https');
5 | const fs = require('fs')
6 | const getDimensions = require('get-video-dimensions');
7 | const url = require("url");
8 | const Path = require('path');
9 | const Stream = require('stream').Transform
10 | class Utils {
11 | static block = { title: "", subtitle: "", type: "", url: "", width: 0, height: 0 }
12 | static tgmStruct =
13 | {
14 | currentGM: 0.0, i: 0, tgmPre: 0.0,
15 | tgmValuePre: 0.0,
16 | isRun: false,
17 | tgm: 0.0,
18 | tgmValue: 0.0,
19 | _tgm: 0.0,
20 | _tgmValue: 0.0,
21 |
22 | };
23 |
24 | static getVideoSize = async function (file) {
25 | const dimensions = await getDimensions(file);
26 | return dimensions;
27 |
28 | }
29 | static generateRandomID = function () {
30 | // Math.random should be unique because of its seeding algorithm.
31 | // Convert it to base 36 (numbers + letters), and grab the first 9 characters
32 | // after the decimal.
33 | return '_' + Math.random().toString(36).substr(2, 9);
34 | };
35 | static generateUuid = function () {
36 | return Math.random().toString() +
37 | Math.random().toString() +
38 | Math.random().toString();
39 | }
40 |
41 | static runProcessWithProgress = function (argv, callback) {
42 | return new Promise((resolve, reject) => {
43 | var spawn = require('child_process').spawn
44 | var prc = spawn(config.ffmpeg_path, argv);
45 |
46 |
47 |
48 | prc.on('error', function () {
49 | console.log("Failed to start child.");
50 | });
51 | var data = "";
52 | prc.stdout.setEncoding('utf8');
53 | prc.stdout.on('data', function (datae) {
54 | var str = datae.toString()
55 | var lines = str.split(/(\r?\n)/g)
56 | data += lines.join("");
57 |
58 | });
59 | prc.stderr.on('data', function (datae) {
60 |
61 | var lines = datae.toString(); data += lines;
62 | callback(lines, data);
63 |
64 | });
65 |
66 | prc.stdout.on('end', function () {
67 |
68 | resolve(data)
69 | });
70 | prc.on('exit', function () {
71 |
72 | })
73 | prc.on('close', function (code) {
74 | reject(code);
75 |
76 | });
77 |
78 | })
79 | }
80 |
81 | static runProcess = function (name, argv) {
82 |
83 | return new Promise((resolve, reject) => {
84 | var spawn = require('child_process').spawn
85 | var prc = ""
86 |
87 | if (name == "ffmpeg") {
88 | prc = spawn(config.ffmpeg_path, argv);
89 |
90 |
91 | } else if (name == "convert") {
92 | console.log(argv.join(' '));
93 | prc = spawn(config.convert_path, argv);
94 | } else if (name == "magick") {
95 | prc = spawn(config.magick_path, argv);
96 | }
97 | var data = "";
98 | try {
99 | prc.stdout.setEncoding('utf8');
100 | } catch (e) {
101 | throw (e)
102 |
103 | }
104 | prc.stdout.on('data', function (datae) {
105 | var str = datae.toString()
106 | var lines = str.split(/(\r?\n)/g)
107 | data += lines.join("");
108 |
109 | });
110 | prc.stderr.on('data', function (datae) {
111 | //Here is where the error output goes
112 |
113 | var lines = datae.toString();
114 | data += lines;
115 |
116 | });
117 |
118 | prc.stdout.on('end', function () {
119 |
120 | });
121 | prc.on('exit', function () {
122 | resolve(data)
123 | })
124 | prc.on('close', function (code) {
125 | // resolve(data)
126 | reject(code)
127 |
128 | });
129 |
130 | })
131 | }
132 |
133 | static deleteFolderRecursive = function (path) {
134 | if (fs.existsSync(path)) {
135 | fs.readdirSync(path).forEach((file, index) => {
136 | const curPath = Path.join(path, file);
137 | if (fs.lstatSync(curPath).isDirectory()) { // recurse
138 | Utils.deleteFolderRecursive(curPath);
139 | } else { // delete file
140 | fs.unlinkSync(curPath);
141 | }
142 | });
143 | fs.rmdirSync(path);
144 | }
145 | };
146 | static hexToRgb(hex) {
147 | // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
148 | var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
149 | hex = hex.replace(shorthandRegex, function (m, r, g, b) {
150 | return r + r + g + g + b + b;
151 | });
152 |
153 | var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
154 | return result ? {
155 | r: parseInt(result[1], 16),
156 | g: parseInt(result[2], 16),
157 | b: parseInt(result[3], 16)
158 | } : null;
159 | }
160 | static async readFile(path) {
161 | return new Promise((resolve, reject) => {
162 | fs.readFile(path, 'utf8', function (err, data) {
163 | if (err) {
164 | reject(err);
165 | }
166 | resolve(data);
167 | });
168 | });
169 | }
170 |
171 | // function returns a Promise
172 | static getPromise(urlLink, fileName) {
173 | return new Promise((resolve, reject) => {
174 | var urlVal = new URL(urlLink);
175 | var parsed = url.parse(urlLink);
176 | var client = http;
177 | client = (urlVal.protocol == "https:") ? https : client;
178 |
179 | const request = client.get(urlLink, function (response) {
180 |
181 | var data = new Stream();
182 |
183 | response.on('data', function (chunk) {
184 | data.push(chunk);
185 | });
186 |
187 | response.on('end', function () {
188 | resolve("success");
189 |
190 | fs.writeFileSync(fileName, data.read());
191 | });
192 | response.on('error', (error) => {
193 | console.log("errorcode")
194 | reject(error);
195 | });
196 | });
197 | });
198 | }
199 |
200 | static async makeSynchronousRequest(url, file) {
201 | try {
202 | let http_promise = Utils.getPromise(url, file);
203 | await http_promise;
204 |
205 | }
206 | catch (error) {
207 | // Promise rejected
208 | console.log(error);
209 | }
210 | }
211 | static componentToHex(c) {
212 | var hex = c.toString(16);
213 | return hex.length == 1 ? "0" + hex : hex;
214 | }
215 | static rgbToHex(r, g, b) {
216 | return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
217 | }
218 | static checkFileExists(file) {
219 | return fs.promises.access(file, fs.constants.F_OK)
220 | .then(() => (true))
221 | .catch(() => (false))
222 | }
223 | //Get data in between functions from index start & end
224 | static getDataInBetweenInt(text,iFrom,iTo){
225 | let result = text.substr(iFrom, iTo );
226 | return result;
227 | }
228 | //Get data in between
229 | static getDataInBetween(text, startText,endText){
230 | let iFrom = this.getDataStartPoint(text,startText);
231 | let iTo = this.getDataEndPoint(text,endText);
232 | let result = this.getDataInBetweenInt(text,iFrom, iTo - iFrom );
233 | return result;
234 |
235 | }
236 | //Get index position
237 | static getDataEndPoint(text,endText,isLast = true,startIndex = 0){
238 | if(isLast){
239 | return text.lastIndexOf(endText);
240 | }else{
241 | return text.indexOf(endText,startIndex);
242 | }
243 | }
244 | //Get index position with length
245 | static getDataStartPoint(text,startText){
246 | return text.indexOf(startText) + startText.length;
247 | }
248 |
249 | //module.exports = { runProcess,block,deleteFolderRecursive ,runProcessWithProgress,readFile,hexToRgb,rgbToHex,makeSynchronousRequest,getVideoSize,checkFileExists,generateUuid}
250 | }
251 | module.exports=Utils;
--------------------------------------------------------------------------------
/worker.js:
--------------------------------------------------------------------------------
1 | const { Worker } = require('worker_threads');
2 | let amqp = require('amqplib/callback_api');
3 | let totalLimit = 0;
4 | const processFrames = function (date, id, commands, windex, wind, limit, channel, msg, isWorkDone, currentIndex) {
5 | if (!isWorkDone) {
6 | for (let ie = currentIndex; ie < limit; ie++) {
7 | runAgain = false;
8 | if (ie >= commands.length) { return; }
9 | new Promise((resolve, reject) => {
10 | const port = new Worker(('./workerChild.js'), {
11 | workerData: { name: commands[ie].name, cmd: commands[ie].cmd }
12 | });
13 | port.on('message', (data) => {
14 | if (data != null && typeof (data) !== 'undefined' && data.toString().includes("error/convert.c")) {
15 | channel.sendToQueue(msg.properties.replyTo,
16 | Buffer.from(JSON.stringify({ status: 'error', id: id, message: "Incorrect data" })), {
17 | correlationId: msg.properties.correlationId
18 | });
19 | channel.ack(msg);
20 | isWorkDone = true;
21 | }
22 | });
23 | port.on('error', reject);
24 | port.on('exit', (code) => {
25 | console.log(wind, windex, currentIndex, limit);
26 | currentIndex++;
27 | if (wind == windex - 2) {
28 | if (currentIndex * (wind + 1) >= limit * (wind + 1)) {
29 | wind++;
30 | date = new Date();
31 | processFrames(date, id, commands, windex, wind, commands.length, channel, msg, isWorkDone, currentIndex);
32 | }
33 | } else if (wind < windex - 2) {
34 | if (currentIndex * (wind + 1) >= limit * (wind + 1)) {
35 | limit += totalLimit;
36 | wind++;
37 | date = new Date();
38 | processFrames(date, id, commands, windex, wind, limit, channel, msg, isWorkDone, currentIndex);
39 | }
40 | }
41 | if (currentIndex >= commands.length) {
42 | channel.sendToQueue(msg.properties.replyTo,
43 | Buffer.from(JSON.stringify({ status: 'success', id: id })), {
44 | correlationId: msg.properties.correlationId
45 | });
46 | channel.ack(msg);
47 | isWorkDone = true;
48 | return;
49 | }
50 | if (code !== 0)
51 | reject(new Error(`Worker stopped with exit code ${code}`));
52 | });
53 | });
54 | }
55 | }
56 | }
57 | function worker() {
58 | currentIndex = 0;
59 | amqp.connect('amqp://localhost', function (error, connection) {
60 | console.log(error);
61 | connection.createChannel(function (error, channel) {
62 | let queue = 'render_cmd_dev';
63 | channel.assertQueue(queue, {
64 | durable: false
65 | });
66 | channel.prefetch(1);
67 | console.log(" [*] Waiting for messages in %s. To exit press CTRL+C", queue);
68 | channel.consume(queue, function reply(msg) {
69 | let content = JSON.parse(msg.content.toString());
70 |
71 | if(typeof(content.commands)!=='undefined'){
72 | console.log(content);
73 | totalLimit = content.tLimit;
74 | let commands = content.commands;
75 | let id = content.id;
76 | let date = content.date;
77 | let isWorkDone = false;
78 | let windex = content.commands.length < totalLimit ? 1 : parseInt(content.commands.length / totalLimit)
79 | if (windex == 1) {
80 | channel.ack(msg);
81 | } else {
82 | console.log("RUN", windex, date, id, windex, 0, totalLimit)
83 | processFrames(date, id, commands, windex, 0, totalLimit, channel, msg, isWorkDone, currentIndex);
84 | }
85 | } else {
86 | channel.ack(msg);
87 | }
88 | });
89 |
90 |
91 | });
92 | });
93 | }
94 | module.exports = worker
--------------------------------------------------------------------------------
/workerChild.js:
--------------------------------------------------------------------------------
1 | const utils=require('./utils.js')
2 | const {parentPort,workerData}=require('worker_threads');
3 | utils.runProcess(workerData.name,workerData.cmd).then((data)=>{
4 | if(typeof(workerData.j)!=='undefined'){
5 | parentPort.postMessage({ j:workerData.j,id:workerData.id,index:workerData.index,fileName: workerData.name,file_name:workerData.file_name,cmd:workerData.cmd, status: 'Done' })
6 | }else{
7 | parentPort.postMessage({ id:workerData.id,index:workerData.index,fileName: workerData.name,file_name:workerData.file_name,cmd:workerData.cmd, status: 'Done' })
8 | }
9 | })
10 |
11 |
12 |
--------------------------------------------------------------------------------