shiveshnavin commited on
Commit
0f62cae
·
1 Parent(s): 2e90118

Add result upload

Browse files
Files changed (9) hide show
  1. .gitignore +5 -2
  2. app.js +44 -9
  3. common-utils +1 -1
  4. ffmpeg-fix.js +1 -1
  5. index.html +44 -4
  6. index.js +2 -1
  7. package-lock.json +255 -8
  8. package.json +12 -11
  9. server.js +47 -3
.gitignore CHANGED
@@ -4,11 +4,14 @@ dist
4
  .env
5
  @@export_177ba1326b.zip
6
  # Ignore the output video from Git but not videos you import into src/.
7
- out
 
8
  ffmpeg/
9
  public/
10
  **.zip
11
  yarn.lock
12
  package-lock.json
13
  functions/*.log
14
- **.log
 
 
 
4
  .env
5
  @@export_177ba1326b.zip
6
  # Ignore the output video from Git but not videos you import into src/.
7
+ out/**
8
+ out/
9
  ffmpeg/
10
  public/
11
  **.zip
12
  yarn.lock
13
  package-lock.json
14
  functions/*.log
15
+ **.log
16
+ uploads/
17
+ uploads/**
app.js CHANGED
@@ -3,7 +3,7 @@ const stream = require('stream');
3
  const bodyParser = require('body-parser');
4
  const fs = require('fs');
5
  const path = require('path');
6
- const { Utils } = require('common-utils');
7
  const { ZipFiles, UnzipFiles } = require('common-utils');
8
  const OracleStorage = require('./common-creds/oracle/storage.json');
9
  const axios = require('axios');
@@ -146,14 +146,36 @@ app.all('/render', async (req, res) => {
146
  }
147
  let manuObj = JSON.parse(fs.readFileSync(manuFile).toString())
148
  modifyFiles(manuObj)
 
149
 
150
  if (!skipRender) {
151
- doRender((result) => {
152
- res.send({
 
 
 
 
 
 
 
 
153
  status: result,
154
  job_id: manuObj.id
155
- })
156
- })
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  }
158
  else {
159
  console.log('Skipping render')
@@ -183,9 +205,11 @@ const oracleAPI = OracleStorage.semibit_media.url
183
  if (!fs.existsSync(uploadDir)) {
184
  fs.mkdirSync(uploadDir);
185
  }
 
186
  app.post('/upload', async (req, res) => {
187
  try {
188
  const file = req.files.file;
 
189
 
190
  const readStream = fs.createReadStream(file.path);
191
  const writeStream = fs.createWriteStream(path.join(uploadDir, file.name));
@@ -195,7 +219,6 @@ app.post('/upload', async (req, res) => {
195
  writeStream.on('finish', resolve);
196
  });
197
 
198
- const uploadUrl = oracleAPI + encodeURIComponent(file.name);
199
  const fileData = fs.readFileSync(path.join(uploadDir, file.name));
200
 
201
  await axios.put(uploadUrl, fileData);
@@ -213,25 +236,37 @@ app.post('/upload', async (req, res) => {
213
  });
214
 
215
 
216
- function doRender(status) {
 
 
 
 
 
 
 
 
 
217
  const npmScript = 'render-build';
218
  const childProcess = exec(`npm run ${npmScript}`);
219
 
220
  console.log('Starting render')
221
  childProcess.stdout.on('data', (data) => {
 
222
  console.log(data.toString());
223
  });
224
 
225
  childProcess.stderr.on('data', (data) => {
 
226
  console.error(data.toString());
227
  });
228
 
229
  // Listen for the completion of the child process
230
  childProcess.on('close', (code) => {
231
  console.log('Render finished')
232
-
233
- if (status)
234
  status(code)
 
235
  if (code === 0) {
236
  console.log(`'${npmScript}' completed successfully.`);
237
  } else {
 
3
  const bodyParser = require('body-parser');
4
  const fs = require('fs');
5
  const path = require('path');
6
+ const { Utils, FileUploader } = require('common-utils');
7
  const { ZipFiles, UnzipFiles } = require('common-utils');
8
  const OracleStorage = require('./common-creds/oracle/storage.json');
9
  const axios = require('axios');
 
146
  }
147
  let manuObj = JSON.parse(fs.readFileSync(manuFile).toString())
148
  modifyFiles(manuObj)
149
+ const uploader = new FileUploader('oracle', OracleStorage.semibit_media)
150
 
151
  if (!skipRender) {
152
+ res.writeHead(200, manuObj.id, {
153
+ 'job_id': manuObj.id,
154
+ 'content-type': 'application/json'
155
+ })
156
+ res.write(JSON.stringify({
157
+ status: 2,
158
+ job_id: manuObj.id
159
+ }))
160
+ let cb = async (result) => {
161
+ res.write(JSON.stringify({
162
  status: result,
163
  job_id: manuObj.id
164
+ }))
165
+ fs.renameSync('out/video.mp4', `out/${manuObj.id}.mp4`)
166
+ let uploadResult = await uploader.upload(`out/${manuObj.id}.mp4`)
167
+ sendToObserver(manuObj.id, uploadResult.url)
168
+ res.end()
169
+ }
170
+ if (req.query.async) {
171
+ cb = async () => {
172
+ fs.renameSync('out/video.mp4', `out/${manuObj.id}.mp4`)
173
+ let uploadResult = await uploader.upload(`out/${manuObj.id}.mp4`)
174
+ sendToObserver(manuObj.id, uploadResult.url)
175
+ //todo > publish webhook
176
+ }
177
+ }
178
+ doRender(manuObj.id, cb)
179
  }
180
  else {
181
  console.log('Skipping render')
 
205
  if (!fs.existsSync(uploadDir)) {
206
  fs.mkdirSync(uploadDir);
207
  }
208
+
209
  app.post('/upload', async (req, res) => {
210
  try {
211
  const file = req.files.file;
212
+ const uploadUrl = oracleAPI + encodeURIComponent(file.name);
213
 
214
  const readStream = fs.createReadStream(file.path);
215
  const writeStream = fs.createWriteStream(path.join(uploadDir, file.name));
 
219
  writeStream.on('finish', resolve);
220
  });
221
 
 
222
  const fileData = fs.readFileSync(path.join(uploadDir, file.name));
223
 
224
  await axios.put(uploadUrl, fileData);
 
236
  });
237
 
238
 
239
+ function sendToObserver(jobId, data) {
240
+ if (app.observer) {
241
+ app.observer(jobId, {
242
+ jod_id: jobId,
243
+ message_type: 'info',
244
+ message: data
245
+ })
246
+ }
247
+ }
248
+ function doRender(jobId, status) {
249
  const npmScript = 'render-build';
250
  const childProcess = exec(`npm run ${npmScript}`);
251
 
252
  console.log('Starting render')
253
  childProcess.stdout.on('data', (data) => {
254
+ sendToObserver(jobId, data)
255
  console.log(data.toString());
256
  });
257
 
258
  childProcess.stderr.on('data', (data) => {
259
+ sendToObserver(jobId, data)
260
  console.error(data.toString());
261
  });
262
 
263
  // Listen for the completion of the child process
264
  childProcess.on('close', (code) => {
265
  console.log('Render finished')
266
+ sendToObserver(jobId, code === 0 ? 'completed' : 'failed')
267
+ if (status) {
268
  status(code)
269
+ }
270
  if (code === 0) {
271
  console.log(`'${npmScript}' completed successfully.`);
272
  } else {
common-utils CHANGED
@@ -1 +1 @@
1
- Subproject commit e1bd46fb06769f2a9f887e396a176a54a293e309
 
1
+ Subproject commit 4a3802a43509d4e7314a27af9217864fca35c687
ffmpeg-fix.js CHANGED
@@ -39,7 +39,7 @@ async function findAndCreateSymlink(targetExecutable, ffmpegPath) {
39
  const symlinkPath = path.join(filePath, 'ffmpeg', 'remotion', 'bin', targetExecutable);
40
  // await createSymlink(ffmpegPath, symlinkPath);
41
  fs.copyFileSync(ffmpegPath, symlinkPath)
42
- console.log('Coped to', symlinkPath)
43
  }
44
  });
45
  } catch (error) {
 
39
  const symlinkPath = path.join(filePath, 'ffmpeg', 'remotion', 'bin', targetExecutable);
40
  // await createSymlink(ffmpegPath, symlinkPath);
41
  fs.copyFileSync(ffmpegPath, symlinkPath)
42
+ console.log('Copied to', symlinkPath)
43
  }
44
  });
45
  } catch (error) {
index.html CHANGED
@@ -5,13 +5,14 @@
5
  <meta charset="UTF-8">
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
  <title>Semibit Media Render Farm</title>
 
8
  <link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.indigo-pink.min.css">
9
  </head>
10
 
11
  <body>
12
  <div class="mdl-layout mdl-js-layout mdl-color--grey-100">
13
  <main style="margin-top:100px" class="mdl-layout__content">
14
- <div class="mdl-card mdl-shadow--6dp" style="max-width: 400px; margin: 0 auto; padding: 16px;">
15
  <h3 style="text-align: center;">Render Asset
16
  Bundle</h3>
17
  <div class="mdl-textfield mdl-js-textfield">
@@ -21,7 +22,16 @@
21
  Upload
22
  </button>
23
  <p id="statusMessage" style="margin-top: 16px;"></p>
 
 
 
 
 
 
 
 
24
  </div>
 
25
  </main>
26
  </div>
27
 
@@ -53,12 +63,18 @@
53
 
54
  if (response.ok) {
55
  statusMessage.textContent = 'File uploaded successfully! Triggering Render';
56
- let renderUrl = window.location.href + '/render?fileUrl=' + encodeURIComponent(uploadUrl)
57
  response = await fetch(renderUrl);
58
- if (response.ok)
 
 
 
 
59
  response.text().then(t => {
60
- statusMessage.innerHTML = 'Render triggered succesfully.<br>' + t;
 
61
  })
 
62
  else
63
  statusMessage.textContent = 'Render Failed ' + response.statusText;
64
 
@@ -71,6 +87,30 @@
71
  }
72
  }
73
  </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  </body>
75
 
76
  </html>
 
5
  <meta charset="UTF-8">
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
  <title>Semibit Media Render Farm</title>
8
+ <script src="https://cdn.socket.io/4.5.4/socket.io.min.js"></script>
9
  <link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.indigo-pink.min.css">
10
  </head>
11
 
12
  <body>
13
  <div class="mdl-layout mdl-js-layout mdl-color--grey-100">
14
  <main style="margin-top:100px" class="mdl-layout__content">
15
+ <div class="mdl-card mdl-shadow--6dp" style="max-width:80%; margin: 0 auto; padding: 16px;">
16
  <h3 style="text-align: center;">Render Asset
17
  Bundle</h3>
18
  <div class="mdl-textfield mdl-js-textfield">
 
22
  Upload
23
  </button>
24
  <p id="statusMessage" style="margin-top: 16px;"></p>
25
+
26
+
27
+ <h4>Job Status Subscription</h4>
28
+ <label for="jobId">Enter Job ID:</label>
29
+ <input type="text" id="jobId" name="jobId" required>
30
+ <button id="subscribeJob" type="button">Subscribe</button>
31
+ <h4>Job Status Updates</h4>
32
+ <p id="statusUpdates"></p>
33
  </div>
34
+
35
  </main>
36
  </div>
37
 
 
63
 
64
  if (response.ok) {
65
  statusMessage.textContent = 'File uploaded successfully! Triggering Render';
66
+ let renderUrl = window.location.origin + '/render?fileUrl=' + encodeURIComponent(uploadUrl)
67
  response = await fetch(renderUrl);
68
+ if (response.ok) {
69
+ let jobId = response.statusText
70
+ document.getElementById('jobId').value = jobId
71
+ const subscriptionForm = document.getElementById('subscribeJob');
72
+ subscriptionForm.click()
73
  response.text().then(t => {
74
+ let rep = JSON.parse(t)
75
+ statusMessage.innerHTML = 'Render completed succesfully.<br>' + t;
76
  })
77
+ }
78
  else
79
  statusMessage.textContent = 'Render Failed ' + response.statusText;
80
 
 
87
  }
88
  }
89
  </script>
90
+
91
+
92
+
93
+
94
+ <script>
95
+ const socket = io();
96
+ const subscriptionForm = document.getElementById('subscribeJob');
97
+ subscriptionForm.addEventListener('click', (event) => {
98
+ event.preventDefault();
99
+ const jobId = document.getElementById('jobId').value;
100
+ socket.emit('subscribe_job', jobId);
101
+ });
102
+
103
+ const listItem = document.createElement('span');
104
+ listItem.textContent = `Connected`;
105
+ statusUpdates.appendChild(listItem);
106
+ socket.on('job_status', (data) => {
107
+ const statusUpdates = document.getElementById('statusUpdates');
108
+ let str = data.msg?.message
109
+ if (typeof str == "object")
110
+ str = JSON.stringify(str)
111
+ listItem.textContent = `${str}`;
112
+ });
113
+ </script>
114
  </body>
115
 
116
  </html>
index.js CHANGED
@@ -8,7 +8,8 @@ setGlobalOptions({
8
  region: "us-central1",
9
  memory: "4GiB",
10
  maxInstances: 1,
11
- minInstances: 0
 
12
  });
13
 
14
  initializeApp();
 
8
  region: "us-central1",
9
  memory: "4GiB",
10
  maxInstances: 1,
11
+ minInstances: 0,
12
+ timeoutSeconds: 3500
13
  });
14
 
15
  initializeApp();
package-lock.json CHANGED
@@ -37,13 +37,14 @@
37
  "remotion": "4.0.19",
38
  "remotion-animated": "^2.0.0",
39
  "remotion-transition-series": "^0.0.10",
 
40
  "styled-components": "^6.0.5",
41
  "ts-node-dev": "^2.0.0",
42
  "typescript": "^4.9.4",
43
  "which": "^3.0.1",
 
44
  "zod": "^3.21.4"
45
  },
46
- "devDependencies": {},
47
  "engines": {
48
  "node": "16"
49
  }
@@ -3989,6 +3990,26 @@
3989
  "node": ">= 8"
3990
  }
3991
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3992
  "node_modules/@remotion/tailwind": {
3993
  "version": "4.0.19",
3994
  "resolved": "https://registry.npmjs.org/@remotion/tailwind/-/tailwind-4.0.19.tgz",
@@ -4017,6 +4038,11 @@
4017
  "zod": "^3.0.0"
4018
  }
4019
  },
 
 
 
 
 
4020
  "node_modules/@tootallnate/once": {
4021
  "version": "2.0.0",
4022
  "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
@@ -4063,6 +4089,11 @@
4063
  "@types/node": "*"
4064
  }
4065
  },
 
 
 
 
 
4066
  "node_modules/@types/cors": {
4067
  "version": "2.8.13",
4068
  "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz",
@@ -5192,6 +5223,14 @@
5192
  }
5193
  ]
5194
  },
 
 
 
 
 
 
 
 
5195
  "node_modules/bcrypt-pbkdf": {
5196
  "version": "1.0.2",
5197
  "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
@@ -6192,6 +6231,62 @@
6192
  "once": "^1.4.0"
6193
  }
6194
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6195
  "node_modules/enhanced-resolve": {
6196
  "version": "5.15.0",
6197
  "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
@@ -14193,6 +14288,63 @@
14193
  "node": ">=8"
14194
  }
14195
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14196
  "node_modules/source-map": {
14197
  "version": "0.6.1",
14198
  "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -15504,15 +15656,15 @@
15504
  "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
15505
  },
15506
  "node_modules/ws": {
15507
- "version": "8.7.0",
15508
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.7.0.tgz",
15509
- "integrity": "sha512-c2gsP0PRwcLFzUiA8Mkr37/MI7ilIlHQxaEAtd0uNMbVMoy8puJyafRlm0bV9MbGSabUPeLrRRaqIBcFcA2Pqg==",
15510
  "engines": {
15511
  "node": ">=10.0.0"
15512
  },
15513
  "peerDependencies": {
15514
  "bufferutil": "^4.0.1",
15515
- "utf-8-validate": "^5.0.2"
15516
  },
15517
  "peerDependenciesMeta": {
15518
  "bufferutil": {
@@ -18094,6 +18246,12 @@
18094
  "requires": {
18095
  "whatwg-url": "^7.0.0"
18096
  }
 
 
 
 
 
 
18097
  }
18098
  }
18099
  },
@@ -18119,6 +18277,11 @@
18119
  "remotion": "4.0.19"
18120
  }
18121
  },
 
 
 
 
 
18122
  "@tootallnate/once": {
18123
  "version": "2.0.0",
18124
  "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
@@ -18162,6 +18325,11 @@
18162
  "@types/node": "*"
18163
  }
18164
  },
 
 
 
 
 
18165
  "@types/cors": {
18166
  "version": "2.8.13",
18167
  "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz",
@@ -19025,6 +19193,11 @@
19025
  "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
19026
  "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
19027
  },
 
 
 
 
 
19028
  "bcrypt-pbkdf": {
19029
  "version": "1.0.2",
19030
  "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
@@ -19755,6 +19928,41 @@
19755
  "once": "^1.4.0"
19756
  }
19757
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19758
  "enhanced-resolve": {
19759
  "version": "5.15.0",
19760
  "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
@@ -25223,6 +25431,45 @@
25223
  "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
25224
  "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="
25225
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25226
  "source-map": {
25227
  "version": "0.6.1",
25228
  "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -26165,9 +26412,9 @@
26165
  "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
26166
  },
26167
  "ws": {
26168
- "version": "8.7.0",
26169
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.7.0.tgz",
26170
- "integrity": "sha512-c2gsP0PRwcLFzUiA8Mkr37/MI7ilIlHQxaEAtd0uNMbVMoy8puJyafRlm0bV9MbGSabUPeLrRRaqIBcFcA2Pqg==",
26171
  "requires": {}
26172
  },
26173
  "xmlcreate": {
 
37
  "remotion": "4.0.19",
38
  "remotion-animated": "^2.0.0",
39
  "remotion-transition-series": "^0.0.10",
40
+ "socket.io": "^4.7.2",
41
  "styled-components": "^6.0.5",
42
  "ts-node-dev": "^2.0.0",
43
  "typescript": "^4.9.4",
44
  "which": "^3.0.1",
45
+ "ws": "^8.13.0",
46
  "zod": "^3.21.4"
47
  },
 
48
  "engines": {
49
  "node": "16"
50
  }
 
3990
  "node": ">= 8"
3991
  }
3992
  },
3993
+ "node_modules/@remotion/renderer/node_modules/ws": {
3994
+ "version": "8.7.0",
3995
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.7.0.tgz",
3996
+ "integrity": "sha512-c2gsP0PRwcLFzUiA8Mkr37/MI7ilIlHQxaEAtd0uNMbVMoy8puJyafRlm0bV9MbGSabUPeLrRRaqIBcFcA2Pqg==",
3997
+ "engines": {
3998
+ "node": ">=10.0.0"
3999
+ },
4000
+ "peerDependencies": {
4001
+ "bufferutil": "^4.0.1",
4002
+ "utf-8-validate": "^5.0.2"
4003
+ },
4004
+ "peerDependenciesMeta": {
4005
+ "bufferutil": {
4006
+ "optional": true
4007
+ },
4008
+ "utf-8-validate": {
4009
+ "optional": true
4010
+ }
4011
+ }
4012
+ },
4013
  "node_modules/@remotion/tailwind": {
4014
  "version": "4.0.19",
4015
  "resolved": "https://registry.npmjs.org/@remotion/tailwind/-/tailwind-4.0.19.tgz",
 
4038
  "zod": "^3.0.0"
4039
  }
4040
  },
4041
+ "node_modules/@socket.io/component-emitter": {
4042
+ "version": "3.1.0",
4043
+ "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
4044
+ "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg=="
4045
+ },
4046
  "node_modules/@tootallnate/once": {
4047
  "version": "2.0.0",
4048
  "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
 
4089
  "@types/node": "*"
4090
  }
4091
  },
4092
+ "node_modules/@types/cookie": {
4093
+ "version": "0.4.1",
4094
+ "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz",
4095
+ "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q=="
4096
+ },
4097
  "node_modules/@types/cors": {
4098
  "version": "2.8.13",
4099
  "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz",
 
5223
  }
5224
  ]
5225
  },
5226
+ "node_modules/base64id": {
5227
+ "version": "2.0.0",
5228
+ "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
5229
+ "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==",
5230
+ "engines": {
5231
+ "node": "^4.5.0 || >= 5.9"
5232
+ }
5233
+ },
5234
  "node_modules/bcrypt-pbkdf": {
5235
  "version": "1.0.2",
5236
  "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
 
6231
  "once": "^1.4.0"
6232
  }
6233
  },
6234
+ "node_modules/engine.io": {
6235
+ "version": "6.5.2",
6236
+ "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.2.tgz",
6237
+ "integrity": "sha512-IXsMcGpw/xRfjra46sVZVHiSWo/nJ/3g1337q9KNXtS6YRzbW5yIzTCb9DjhrBe7r3GZQR0I4+nq+4ODk5g/cA==",
6238
+ "dependencies": {
6239
+ "@types/cookie": "^0.4.1",
6240
+ "@types/cors": "^2.8.12",
6241
+ "@types/node": ">=10.0.0",
6242
+ "accepts": "~1.3.4",
6243
+ "base64id": "2.0.0",
6244
+ "cookie": "~0.4.1",
6245
+ "cors": "~2.8.5",
6246
+ "debug": "~4.3.1",
6247
+ "engine.io-parser": "~5.2.1",
6248
+ "ws": "~8.11.0"
6249
+ },
6250
+ "engines": {
6251
+ "node": ">=10.2.0"
6252
+ }
6253
+ },
6254
+ "node_modules/engine.io-parser": {
6255
+ "version": "5.2.1",
6256
+ "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz",
6257
+ "integrity": "sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ==",
6258
+ "engines": {
6259
+ "node": ">=10.0.0"
6260
+ }
6261
+ },
6262
+ "node_modules/engine.io/node_modules/cookie": {
6263
+ "version": "0.4.2",
6264
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
6265
+ "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==",
6266
+ "engines": {
6267
+ "node": ">= 0.6"
6268
+ }
6269
+ },
6270
+ "node_modules/engine.io/node_modules/ws": {
6271
+ "version": "8.11.0",
6272
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
6273
+ "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
6274
+ "engines": {
6275
+ "node": ">=10.0.0"
6276
+ },
6277
+ "peerDependencies": {
6278
+ "bufferutil": "^4.0.1",
6279
+ "utf-8-validate": "^5.0.2"
6280
+ },
6281
+ "peerDependenciesMeta": {
6282
+ "bufferutil": {
6283
+ "optional": true
6284
+ },
6285
+ "utf-8-validate": {
6286
+ "optional": true
6287
+ }
6288
+ }
6289
+ },
6290
  "node_modules/enhanced-resolve": {
6291
  "version": "5.15.0",
6292
  "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
 
14288
  "node": ">=8"
14289
  }
14290
  },
14291
+ "node_modules/socket.io": {
14292
+ "version": "4.7.2",
14293
+ "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.2.tgz",
14294
+ "integrity": "sha512-bvKVS29/I5fl2FGLNHuXlQaUH/BlzX1IN6S+NKLNZpBsPZIDH+90eQmCs2Railn4YUiww4SzUedJ6+uzwFnKLw==",
14295
+ "dependencies": {
14296
+ "accepts": "~1.3.4",
14297
+ "base64id": "~2.0.0",
14298
+ "cors": "~2.8.5",
14299
+ "debug": "~4.3.2",
14300
+ "engine.io": "~6.5.2",
14301
+ "socket.io-adapter": "~2.5.2",
14302
+ "socket.io-parser": "~4.2.4"
14303
+ },
14304
+ "engines": {
14305
+ "node": ">=10.2.0"
14306
+ }
14307
+ },
14308
+ "node_modules/socket.io-adapter": {
14309
+ "version": "2.5.2",
14310
+ "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz",
14311
+ "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==",
14312
+ "dependencies": {
14313
+ "ws": "~8.11.0"
14314
+ }
14315
+ },
14316
+ "node_modules/socket.io-adapter/node_modules/ws": {
14317
+ "version": "8.11.0",
14318
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
14319
+ "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
14320
+ "engines": {
14321
+ "node": ">=10.0.0"
14322
+ },
14323
+ "peerDependencies": {
14324
+ "bufferutil": "^4.0.1",
14325
+ "utf-8-validate": "^5.0.2"
14326
+ },
14327
+ "peerDependenciesMeta": {
14328
+ "bufferutil": {
14329
+ "optional": true
14330
+ },
14331
+ "utf-8-validate": {
14332
+ "optional": true
14333
+ }
14334
+ }
14335
+ },
14336
+ "node_modules/socket.io-parser": {
14337
+ "version": "4.2.4",
14338
+ "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
14339
+ "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
14340
+ "dependencies": {
14341
+ "@socket.io/component-emitter": "~3.1.0",
14342
+ "debug": "~4.3.1"
14343
+ },
14344
+ "engines": {
14345
+ "node": ">=10.0.0"
14346
+ }
14347
+ },
14348
  "node_modules/source-map": {
14349
  "version": "0.6.1",
14350
  "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
 
15656
  "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
15657
  },
15658
  "node_modules/ws": {
15659
+ "version": "8.13.0",
15660
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz",
15661
+ "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==",
15662
  "engines": {
15663
  "node": ">=10.0.0"
15664
  },
15665
  "peerDependencies": {
15666
  "bufferutil": "^4.0.1",
15667
+ "utf-8-validate": ">=5.0.2"
15668
  },
15669
  "peerDependenciesMeta": {
15670
  "bufferutil": {
 
18246
  "requires": {
18247
  "whatwg-url": "^7.0.0"
18248
  }
18249
+ },
18250
+ "ws": {
18251
+ "version": "8.7.0",
18252
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.7.0.tgz",
18253
+ "integrity": "sha512-c2gsP0PRwcLFzUiA8Mkr37/MI7ilIlHQxaEAtd0uNMbVMoy8puJyafRlm0bV9MbGSabUPeLrRRaqIBcFcA2Pqg==",
18254
+ "requires": {}
18255
  }
18256
  }
18257
  },
 
18277
  "remotion": "4.0.19"
18278
  }
18279
  },
18280
+ "@socket.io/component-emitter": {
18281
+ "version": "3.1.0",
18282
+ "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
18283
+ "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg=="
18284
+ },
18285
  "@tootallnate/once": {
18286
  "version": "2.0.0",
18287
  "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
 
18325
  "@types/node": "*"
18326
  }
18327
  },
18328
+ "@types/cookie": {
18329
+ "version": "0.4.1",
18330
+ "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz",
18331
+ "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q=="
18332
+ },
18333
  "@types/cors": {
18334
  "version": "2.8.13",
18335
  "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz",
 
19193
  "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
19194
  "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
19195
  },
19196
+ "base64id": {
19197
+ "version": "2.0.0",
19198
+ "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
19199
+ "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog=="
19200
+ },
19201
  "bcrypt-pbkdf": {
19202
  "version": "1.0.2",
19203
  "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
 
19928
  "once": "^1.4.0"
19929
  }
19930
  },
19931
+ "engine.io": {
19932
+ "version": "6.5.2",
19933
+ "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.2.tgz",
19934
+ "integrity": "sha512-IXsMcGpw/xRfjra46sVZVHiSWo/nJ/3g1337q9KNXtS6YRzbW5yIzTCb9DjhrBe7r3GZQR0I4+nq+4ODk5g/cA==",
19935
+ "requires": {
19936
+ "@types/cookie": "^0.4.1",
19937
+ "@types/cors": "^2.8.12",
19938
+ "@types/node": ">=10.0.0",
19939
+ "accepts": "~1.3.4",
19940
+ "base64id": "2.0.0",
19941
+ "cookie": "~0.4.1",
19942
+ "cors": "~2.8.5",
19943
+ "debug": "~4.3.1",
19944
+ "engine.io-parser": "~5.2.1",
19945
+ "ws": "~8.11.0"
19946
+ },
19947
+ "dependencies": {
19948
+ "cookie": {
19949
+ "version": "0.4.2",
19950
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
19951
+ "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA=="
19952
+ },
19953
+ "ws": {
19954
+ "version": "8.11.0",
19955
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
19956
+ "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
19957
+ "requires": {}
19958
+ }
19959
+ }
19960
+ },
19961
+ "engine.io-parser": {
19962
+ "version": "5.2.1",
19963
+ "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz",
19964
+ "integrity": "sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ=="
19965
+ },
19966
  "enhanced-resolve": {
19967
  "version": "5.15.0",
19968
  "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
 
25431
  "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
25432
  "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="
25433
  },
25434
+ "socket.io": {
25435
+ "version": "4.7.2",
25436
+ "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.2.tgz",
25437
+ "integrity": "sha512-bvKVS29/I5fl2FGLNHuXlQaUH/BlzX1IN6S+NKLNZpBsPZIDH+90eQmCs2Railn4YUiww4SzUedJ6+uzwFnKLw==",
25438
+ "requires": {
25439
+ "accepts": "~1.3.4",
25440
+ "base64id": "~2.0.0",
25441
+ "cors": "~2.8.5",
25442
+ "debug": "~4.3.2",
25443
+ "engine.io": "~6.5.2",
25444
+ "socket.io-adapter": "~2.5.2",
25445
+ "socket.io-parser": "~4.2.4"
25446
+ }
25447
+ },
25448
+ "socket.io-adapter": {
25449
+ "version": "2.5.2",
25450
+ "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz",
25451
+ "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==",
25452
+ "requires": {
25453
+ "ws": "~8.11.0"
25454
+ },
25455
+ "dependencies": {
25456
+ "ws": {
25457
+ "version": "8.11.0",
25458
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
25459
+ "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
25460
+ "requires": {}
25461
+ }
25462
+ }
25463
+ },
25464
+ "socket.io-parser": {
25465
+ "version": "4.2.4",
25466
+ "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
25467
+ "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
25468
+ "requires": {
25469
+ "@socket.io/component-emitter": "~3.1.0",
25470
+ "debug": "~4.3.1"
25471
+ }
25472
+ },
25473
  "source-map": {
25474
  "version": "0.6.1",
25475
  "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
 
26412
  "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
26413
  },
26414
  "ws": {
26415
+ "version": "8.13.0",
26416
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz",
26417
+ "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==",
26418
  "requires": {}
26419
  },
26420
  "xmlcreate": {
package.json CHANGED
@@ -8,7 +8,7 @@
8
  "scripts": {
9
  "start": "node server.js",
10
  "preview": "remotion studio",
11
- "render-build": "remotion render --image-format=jpeg --quality=70 --gl=angle SemibitComposition ",
12
  "render-still": "remotion still --image-format=jpeg SemibitCompositionPoster ",
13
  "upgrade": "remotion upgrade",
14
  "postinstall": "cd node_modules/common-utils && npm run build && cd ../../ && node ffmpeg-fix.js",
@@ -31,39 +31,40 @@
31
  }
32
  },
33
  "dependencies": {
34
- "@remotion/cli": "4.0.19",
35
- "@remotion/eslint-config": "4.0.19",
36
- "@remotion/tailwind": "4.0.19",
37
- "@types/react": "^18.0.26",
38
- "@types/web": "^0.0.86",
39
- "remotion": "4.0.19",
40
- "typescript": "^4.9.4",
41
- "firebase-admin": "^11.9.0",
42
- "firebase-functions": "^4.4.1",
43
  "@ffmpeg-installer/ffmpeg": "^1.1.0",
44
  "@remotion/bundler": "4.0.19",
 
 
45
  "@remotion/google-fonts": "4.0.19",
46
  "@remotion/noise": "4.0.19",
47
  "@remotion/preload": "4.0.19",
 
48
  "@remotion/zod-types": "4.0.19",
 
 
49
  "axios": "^1.4.0",
50
  "body-parser": "^1.20.2",
51
  "common-utils": "file:common-utils",
52
  "express": "^4.18.2",
53
  "ffbinaries": "^1.1.5",
 
 
54
  "fs-extra": "^11.1.1",
55
  "i": "^0.3.7",
56
  "npm": "^9.8.1",
57
  "path": "^0.12.7",
58
  "react": "^18.0.0",
59
  "react-dom": "^18.0.0",
 
60
  "remotion-animated": "^2.0.0",
61
  "remotion-transition-series": "^0.0.10",
 
62
  "styled-components": "^6.0.5",
63
  "ts-node-dev": "^2.0.0",
 
64
  "which": "^3.0.1",
 
65
  "zod": "^3.21.4"
66
  },
67
- "devDependencies": {},
68
  "packageManager": "npm@8.19.4"
69
  }
 
8
  "scripts": {
9
  "start": "node server.js",
10
  "preview": "remotion studio",
11
+ "render-build": "remotion render --image-format=jpeg --quality=70 --gl=angle SemibitComposition out/video.mp4",
12
  "render-still": "remotion still --image-format=jpeg SemibitCompositionPoster ",
13
  "upgrade": "remotion upgrade",
14
  "postinstall": "cd node_modules/common-utils && npm run build && cd ../../ && node ffmpeg-fix.js",
 
31
  }
32
  },
33
  "dependencies": {
 
 
 
 
 
 
 
 
 
34
  "@ffmpeg-installer/ffmpeg": "^1.1.0",
35
  "@remotion/bundler": "4.0.19",
36
+ "@remotion/cli": "4.0.19",
37
+ "@remotion/eslint-config": "4.0.19",
38
  "@remotion/google-fonts": "4.0.19",
39
  "@remotion/noise": "4.0.19",
40
  "@remotion/preload": "4.0.19",
41
+ "@remotion/tailwind": "4.0.19",
42
  "@remotion/zod-types": "4.0.19",
43
+ "@types/react": "^18.0.26",
44
+ "@types/web": "^0.0.86",
45
  "axios": "^1.4.0",
46
  "body-parser": "^1.20.2",
47
  "common-utils": "file:common-utils",
48
  "express": "^4.18.2",
49
  "ffbinaries": "^1.1.5",
50
+ "firebase-admin": "^11.9.0",
51
+ "firebase-functions": "^4.4.1",
52
  "fs-extra": "^11.1.1",
53
  "i": "^0.3.7",
54
  "npm": "^9.8.1",
55
  "path": "^0.12.7",
56
  "react": "^18.0.0",
57
  "react-dom": "^18.0.0",
58
+ "remotion": "4.0.19",
59
  "remotion-animated": "^2.0.0",
60
  "remotion-transition-series": "^0.0.10",
61
+ "socket.io": "^4.7.2",
62
  "styled-components": "^6.0.5",
63
  "ts-node-dev": "^2.0.0",
64
+ "typescript": "^4.9.4",
65
  "which": "^3.0.1",
66
+ "ws": "^8.13.0",
67
  "zod": "^3.21.4"
68
  },
 
69
  "packageManager": "npm@8.19.4"
70
  }
server.js CHANGED
@@ -1,5 +1,49 @@
1
  const app = require('./app')
2
  let port = process.env.PORT || 8083
3
- app.listen(port, () => {
4
- console.log("Remote renderer listenting at port", port)
5
- })
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  const app = require('./app')
2
  let port = process.env.PORT || 8083
3
+
4
+ const express = require('express');
5
+ const http = require('http');
6
+ const socketIO = require('socket.io');
7
+
8
+ const server = http.createServer(app);
9
+ const io = socketIO(server);
10
+
11
+ const usersSubscribedToJobs = new Map();
12
+
13
+ app.observer = (job_id, msg) => {
14
+ const subscribers = usersSubscribedToJobs.get(job_id);
15
+ if (subscribers) {
16
+ subscribers.forEach((socket) => {
17
+ socket.emit('job_status', { job_id, msg });
18
+ });
19
+ }
20
+ };
21
+
22
+ io.on('connection', (socket) => {
23
+ console.log('A user connected');
24
+ socket.on('subscribe_job', (job_id) => {
25
+ if (!usersSubscribedToJobs.has(job_id)) {
26
+ usersSubscribedToJobs.set(job_id, new Set());
27
+ }
28
+ usersSubscribedToJobs.get(job_id).add(socket);
29
+ console.log(`User subscribed to job: ${job_id}`);
30
+ });
31
+
32
+ socket.on('unsubscribe_job', (job_id) => {
33
+ if (usersSubscribedToJobs.has(job_id)) {
34
+ usersSubscribedToJobs.get(job_id).delete(socket);
35
+ console.log(`User unsubscribed from job: ${job_id}`);
36
+ }
37
+ });
38
+
39
+ socket.on('disconnect', () => {
40
+ console.log('User disconnected');
41
+ usersSubscribedToJobs.forEach((subscribers, job_id) => {
42
+ subscribers.delete(socket);
43
+ });
44
+ });
45
+ });
46
+
47
+ server.listen(port, () => {
48
+ console.log(`Server listening on port ${port}`);
49
+ });