@vpalmisano/webrtcperf 4.2.0 → 4.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,15 @@
1
1
  import { Config } from './config';
2
+ import { Server } from './server';
2
3
  import { Stats } from './stats';
3
- export declare function setupApplication(config: Config): Promise<{
4
- stats: Stats;
5
- stop: () => Promise<void>;
6
- }>;
4
+ import { EventEmitter } from 'events';
5
+ export declare class Application extends EventEmitter {
6
+ readonly config: Config;
7
+ readonly stats: Stats;
8
+ readonly server?: Server;
9
+ private mediaPaths;
10
+ constructor(config: Config);
11
+ start(): Promise<void>;
12
+ private startSession;
13
+ private postTest;
14
+ stop(canceled?: boolean): Promise<void>;
15
+ }
package/build/src/app.js CHANGED
@@ -3,12 +3,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.setupApplication = setupApplication;
6
+ exports.Application = void 0;
7
7
  const throttler_1 = require("@vpalmisano/throttler");
8
8
  const change_case_1 = require("change-case");
9
9
  const fs_1 = __importDefault(require("fs"));
10
10
  const json5_1 = __importDefault(require("json5"));
11
- const word_wrap_1 = __importDefault(require("word-wrap"));
12
11
  const config_1 = require("./config");
13
12
  const media_1 = require("./media");
14
13
  const server_1 = require("./server");
@@ -18,168 +17,215 @@ const utils_1 = require("./utils");
18
17
  const visqol_1 = require("./visqol");
19
18
  const vmaf_1 = require("./vmaf");
20
19
  const path_1 = __importDefault(require("path"));
20
+ const marked_terminal_1 = require("marked-terminal");
21
+ const events_1 = require("events");
22
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
23
+ const { marked } = require('marked');
24
+ marked.use((0, marked_terminal_1.markedTerminal)({ reflowText: true, tab: 2 }));
21
25
  const log = (0, utils_1.logger)('webrtcperf');
22
26
  function showHelpOrVersion() {
23
- if (process.argv.findIndex(a => a.localeCompare('--help') === 0) !== -1) {
27
+ if (process.argv.includes('--help') || process.argv.includes('-h')) {
24
28
  const docs = (0, config_1.getConfigDocs)();
25
- let out = `Params:\n --version\n It shows the package version.\n`;
29
+ let out = marked.parse(`**Webrtcperf parameters**
30
+
31
+ \`--version\` It shows the package version.
32
+ `);
26
33
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
27
34
  Object.entries(docs).forEach(([name, value]) => {
28
- out += ` --${(0, change_case_1.paramCase)(name)}
29
- ${(0, word_wrap_1.default)(value.doc, { width: 72, indent: ' ' })}
30
- Default: ${value.default}\n`;
35
+ out += marked.parse(`
36
+ \`--${(0, change_case_1.paramCase)(name)}\`
37
+ ${value.doc}
38
+ Default value: \`${value.default}\`
39
+ `);
31
40
  });
32
41
  console.log(out);
33
42
  process.exit(0);
34
43
  }
35
- else if (process.argv.findIndex(a => a.localeCompare('--version') === 0) !== -1) {
44
+ else if (process.argv.includes('--version') || process.argv.includes('-v')) {
36
45
  const version = json5_1.default.parse(fs_1.default.readFileSync((0, utils_1.resolvePackagePath)('package.json')).toString()).version;
37
46
  console.log(version);
38
47
  process.exit(0);
39
48
  }
40
49
  }
41
- async function postTest(config) {
42
- // vmaf score.
43
- if (config.vmafPath) {
44
- console.log('Calculating VMAF score...');
45
- try {
46
- await (0, vmaf_1.calculateVmafScore)(config);
50
+ class Application extends events_1.EventEmitter {
51
+ config;
52
+ stats;
53
+ server;
54
+ mediaPaths = [];
55
+ constructor(config) {
56
+ super();
57
+ if (!config.startTimestamp) {
58
+ config.startTimestamp = Date.now();
47
59
  }
48
- catch (err) {
49
- log.error(`vmaf score error: ${err.stack}`);
60
+ this.config = config;
61
+ this.stats = new stats_1.Stats(config);
62
+ if (config.serverPort) {
63
+ this.server = new server_1.Server(config, this.stats);
50
64
  }
51
65
  }
52
- // visqol score
53
- if (config.visqolPath) {
54
- console.log('Calculating Visqol score...');
55
- try {
56
- await (0, visqol_1.calculateVisqolScore)(config);
66
+ async start() {
67
+ log.debug(`start (runDuration: ${this.config.runDuration})`);
68
+ await this.stats.start();
69
+ if (this.server) {
70
+ await this.server.start();
57
71
  }
58
- catch (err) {
59
- log.error(`visqol score error: ${err.stack}`);
72
+ const config = this.config;
73
+ // Handle vmaf commands.
74
+ if (config.vmafPrepareVideo) {
75
+ await (0, vmaf_1.prepareVideo)(config, true);
60
76
  }
61
- }
62
- }
63
- async function setupApplication(config) {
64
- if (!config.startTimestamp) {
65
- config.startTimestamp = Date.now();
66
- }
67
- // Stats.
68
- const stats = new stats_1.Stats(config);
69
- await stats.start();
70
- // Control server.
71
- let server;
72
- if (config.serverPort) {
73
- server = new server_1.Server(config, stats);
74
- await server.start();
75
- }
76
- // If sessions are set, prepare fake video/audio and start sessions.
77
- if (config.sessions > 0) {
78
- // Prepare fake video and audio.
79
- const mediaPaths = [];
80
- if (config.videoPath) {
81
- for (const videoPath of config.videoPath.split(',')) {
82
- const ret = await (0, media_1.prepareFakeMedia)({ ...config, videoPath });
83
- mediaPaths.push(ret);
84
- }
77
+ if (config.vmafProcessVideo) {
78
+ await (0, vmaf_1.convertToIvf)(config.vmafProcessVideo, config.vmafVideoCrop, config.vmafKeepSourceFiles, config.vmafSkipDuplicated);
85
79
  }
86
- // Network throttle.
87
- if (config.throttleConfig) {
88
- await (0, throttler_1.startThrottle)(config.throttleConfig);
80
+ // Handle sessions.
81
+ if (config.sessions > 0) {
82
+ // Prepare fake video and audio.
83
+ if (config.videoPath && !this.mediaPaths.length) {
84
+ for (const videoPath of config.videoPath.split(',')) {
85
+ const ret = await (0, media_1.prepareFakeMedia)({ ...config, videoPath });
86
+ this.mediaPaths.push(ret);
87
+ }
88
+ }
89
+ // Network throttle.
90
+ if (config.throttleConfig) {
91
+ await (0, throttler_1.startThrottle)(config.throttleConfig);
92
+ }
93
+ // Download browser if necessary.
94
+ if (!config.chromiumUrl && !config.chromiumPath) {
95
+ await (0, utils_1.checkChromeExecutable)();
96
+ }
97
+ // Start the local sessions.
98
+ if (config.randomAudioPeriod) {
99
+ (0, utils_1.startRandomActivateAudio)(this.stats.sessions, config.randomAudioPeriod, config.randomAudioProbability, config.randomAudioRange);
100
+ }
101
+ const spawnPeriod = 1000 / config.spawnRate;
102
+ log.debug(`Starting ${config.sessions} sessions (spawnPeriod: ${spawnPeriod}ms)`);
103
+ const startTime = Date.now();
104
+ for (let i = 0; i < config.sessions; i += 1) {
105
+ const id = this.stats.consumeSessionId(config.tabsPerSession);
106
+ await this.startSession(id, spawnPeriod);
107
+ // If not the last session, sleep.
108
+ if (i < config.sessions - 1) {
109
+ await (0, utils_1.sleep)(spawnPeriod);
110
+ }
111
+ }
112
+ const elapsed = Math.round((Date.now() - startTime) / 1000);
113
+ const spawnRate = (config.sessions * config.tabsPerSession) / elapsed;
114
+ log.debug(`${config.sessions * config.tabsPerSession} pages started in ${elapsed}s (${spawnRate.toFixed(2)}/s)`);
89
115
  }
90
- // Download browser if necessary.
91
- if (!config.chromiumUrl && !config.chromiumPath) {
92
- await (0, utils_1.checkChromeExecutable)();
116
+ if (config.runDuration || config.vmafPath || config.visqolPath) {
117
+ setTimeout(() => this.stop(), config.runDuration * 1000);
93
118
  }
94
- // Start session function.
95
- const startLocalSession = async (id, spawnPeriod) => {
96
- const throttleIndex = (0, throttler_1.getSessionThrottleIndex)(id);
97
- const mediaPath = mediaPaths.length ? mediaPaths[id % mediaPaths.length] : undefined;
98
- const session = new session_1.Session({
99
- ...config,
100
- mediaPath,
101
- spawnPeriod,
102
- id,
103
- throttleIndex,
104
- });
105
- session.once('stop', () => {
106
- console.warn(`Session ${id} stopped, reloading...`);
107
- setTimeout(startLocalSession, spawnPeriod, id);
108
- });
109
- stats.addSession(session);
110
- await session.start();
111
- };
112
- // Start the local sessions.
113
- if (config.randomAudioPeriod) {
114
- (0, utils_1.startRandomActivateAudio)(stats.sessions, config.randomAudioPeriod, config.randomAudioProbability, config.randomAudioRange);
119
+ }
120
+ async startSession(id, spawnPeriod) {
121
+ log.debug(`startSession ${id}`);
122
+ const throttleIndex = (0, throttler_1.getSessionThrottleIndex)(id);
123
+ const mediaPath = this.mediaPaths.length ? this.mediaPaths[id % this.mediaPaths.length] : undefined;
124
+ const session = new session_1.Session({
125
+ ...this.config,
126
+ mediaPath,
127
+ spawnPeriod,
128
+ id,
129
+ throttleIndex,
130
+ });
131
+ session.once('stop', () => {
132
+ console.warn(`Session ${id} stopped, reloading...`);
133
+ setTimeout(() => this.startSession(id, spawnPeriod), spawnPeriod);
134
+ });
135
+ this.stats.addSession(session);
136
+ await session.start();
137
+ }
138
+ async postTest() {
139
+ log.debug('postTest');
140
+ // vmaf score.
141
+ if (this.config.vmafPath) {
142
+ console.log('Calculating VMAF score...');
143
+ try {
144
+ await (0, vmaf_1.calculateVmafScore)(this.config);
145
+ }
146
+ catch (err) {
147
+ log.error(`vmaf score error: ${err.stack}`);
148
+ }
115
149
  }
116
- const spawnPeriod = 1000 / config.spawnRate;
117
- log.debug(`Starting ${config.sessions} sessions (spawnPeriod: ${spawnPeriod}ms)`);
118
- const startTime = Date.now();
119
- for (let i = 0; i < config.sessions; i += 1) {
120
- const id = stats.consumeSessionId(config.tabsPerSession);
121
- await startLocalSession(id, spawnPeriod);
122
- // If not the last session, sleep
123
- if (i < config.sessions - 1) {
124
- await (0, utils_1.sleep)(spawnPeriod);
150
+ // visqol score
151
+ if (this.config.visqolPath) {
152
+ console.log('Calculating Visqol score...');
153
+ try {
154
+ await (0, visqol_1.calculateVisqolScore)(this.config);
155
+ }
156
+ catch (err) {
157
+ log.error(`visqol score error: ${err.stack}`);
125
158
  }
126
159
  }
127
- const elapsed = Math.round((Date.now() - startTime) / 1000);
128
- const spawnRate = (config.sessions * config.tabsPerSession) / elapsed;
129
- log.debug(`${config.sessions * config.tabsPerSession} pages started in ${elapsed}s (${spawnRate.toFixed(2)}/s)`);
130
160
  }
131
- return {
132
- stats,
133
- stop: async () => {
134
- log.debug('Stopping');
135
- (0, utils_1.stopRandomActivateAudio)();
136
- await stats.stop();
137
- if (config.throttleConfig) {
138
- await (0, throttler_1.stopThrottle)();
161
+ async stop(canceled = false) {
162
+ log.debug(`stop (canceled: ${canceled})`);
163
+ (0, utils_1.stopRandomActivateAudio)();
164
+ await this.stats.stop();
165
+ if (this.config.throttleConfig) {
166
+ await (0, throttler_1.stopThrottle)();
167
+ }
168
+ (0, utils_1.stopTimers)();
169
+ await this.postTest();
170
+ // Copy docker logs to data directory.
171
+ if (this.config.pageLogPath) {
172
+ try {
173
+ const logPath = await (0, utils_1.getDockerLogsPath)();
174
+ const dataDir = path_1.default.dirname(this.config.pageLogPath);
175
+ await fs_1.default.promises.cp(logPath, path_1.default.resolve(dataDir, 'docker.log'));
139
176
  }
140
- (0, utils_1.stopTimers)();
141
- await postTest(config);
142
- // Copy docker logs to data directory.
143
- if (config.pageLogPath) {
144
- try {
145
- const logPath = await (0, utils_1.getDockerLogsPath)();
146
- const dataDir = path_1.default.dirname(config.pageLogPath);
147
- await fs_1.default.promises.cp(logPath, path_1.default.resolve(dataDir, 'docker.log'));
148
- }
149
- catch (err) {
150
- log.debug(`docker logs not found: ${err.message}`);
151
- }
177
+ catch (err) {
178
+ log.debug(`docker logs not found: ${err.message}`);
152
179
  }
153
- server?.stop();
154
- log.debug('Stopped');
155
- },
156
- };
180
+ }
181
+ this.server?.stop();
182
+ this.emit('stop', canceled);
183
+ }
157
184
  }
185
+ exports.Application = Application;
158
186
  /**
159
187
  * Main function
160
188
  */
161
189
  async function main() {
162
190
  showHelpOrVersion();
163
- const config = process.argv[2] === '--prompt'
164
- ? await (0, config_1.loadConfigFromPrompt)(process.argv.slice(3).join(' '))
165
- : await (0, config_1.loadConfig)(process.argv[2]);
166
- if (config.vmafPrepareVideo) {
167
- await (0, vmaf_1.prepareVideo)(config, true);
168
- process.exit(0);
191
+ let configs;
192
+ if (process.argv.slice(2).includes('--prompt')) {
193
+ const params = await (0, config_1.loadConfigFromPrompt)(process.argv
194
+ .slice(2)
195
+ .filter(s => !['--prompt', '--dry-run'].includes(s))
196
+ .join(' '));
197
+ if (process.argv.slice(2).includes('--dry-run')) {
198
+ console.log(json5_1.default.stringify(params, null, 2));
199
+ process.exit(0);
200
+ }
201
+ configs = await (0, config_1.loadConfig)(undefined, params);
169
202
  }
170
- if (config.vmafProcessVideo) {
171
- await (0, vmaf_1.convertToIvf)(config.vmafProcessVideo, config.vmafVideoCrop, config.vmafKeepSourceFiles, config.vmafSkipDuplicated);
172
- process.exit(0);
203
+ else {
204
+ configs = await (0, config_1.loadConfig)(process.argv[2]);
173
205
  }
174
- const { stop: stopApplication } = await setupApplication(config);
206
+ if (!configs.length)
207
+ throw new Error('No configuration found');
208
+ let application;
209
+ const runNext = () => {
210
+ const config = configs.splice(0, 1)[0];
211
+ application = new Application(config);
212
+ application.once('stop', canceled => {
213
+ if (!canceled && configs.length) {
214
+ log.info(`Application stopped, running next (${configs.length} left)...`);
215
+ runNext();
216
+ }
217
+ else {
218
+ process.exit(0);
219
+ }
220
+ });
221
+ return application.start();
222
+ };
175
223
  const stop = async () => {
176
224
  console.log('Exiting...');
177
- await stopApplication();
178
- process.exit(0);
225
+ await application.stop(true);
179
226
  };
180
227
  (0, utils_1.registerExitHandler)(() => stop());
181
- // Stop after a configured duration.
182
- setTimeout(stop, config.runDuration * 1000);
228
+ await runNext();
183
229
  // Command line interface.
184
230
  if (process.stdin && process.stdin.setRawMode) {
185
231
  console.log('Press [q] to quit or [x] to exit immediately');
@@ -1 +1 @@
1
- {"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/app.ts"],"names":[],"mappings":"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","sourcesContent":["import { getSessionThrottleIndex, startThrottle, stopThrottle } from '@vpalmisano/throttler'\nimport { paramCase } from 'change-case'\nimport fs from 'fs'\nimport json5 from 'json5'\nimport wrap from 'word-wrap'\n\nimport { Config, getConfigDocs, loadConfig, loadConfigFromPrompt } from './config'\nimport { MediaPath, prepareFakeMedia } from './media'\nimport { Server } from './server'\nimport { Session } from './session'\nimport { Stats } from './stats'\nimport {\n checkChromeExecutable,\n getDockerLogsPath,\n logger,\n registerExitHandler,\n resolvePackagePath,\n sleep,\n startRandomActivateAudio,\n stopRandomActivateAudio,\n stopTimers,\n} from './utils'\nimport { calculateVisqolScore } from './visqol'\nimport { calculateVmafScore, convertToIvf, prepareVideo } from './vmaf'\nimport path from 'path'\n\nconst log = logger('webrtcperf')\n\nfunction showHelpOrVersion(): void {\n if (process.argv.findIndex(a => a.localeCompare('--help') === 0) !== -1) {\n const docs = getConfigDocs()\n let out = `Params:\\n --version\\n It shows the package version.\\n`\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n Object.entries(docs).forEach(([name, value]: [string, any]) => {\n out += ` --${paramCase(name)}\n${wrap(value.doc, { width: 72, indent: ' ' })}\n Default: ${value.default}\\n`\n })\n console.log(out)\n process.exit(0)\n } else if (process.argv.findIndex(a => a.localeCompare('--version') === 0) !== -1) {\n const version = json5.parse(fs.readFileSync(resolvePackagePath('package.json')).toString()).version\n console.log(version)\n process.exit(0)\n }\n}\n\nasync function postTest(config: Config): Promise<void> {\n // vmaf score.\n if (config.vmafPath) {\n console.log('Calculating VMAF score...')\n try {\n await calculateVmafScore(config)\n } catch (err: unknown) {\n log.error(`vmaf score error: ${(err as Error).stack}`)\n }\n }\n\n // visqol score\n if (config.visqolPath) {\n console.log('Calculating Visqol score...')\n try {\n await calculateVisqolScore(config)\n } catch (err: unknown) {\n log.error(`visqol score error: ${(err as Error).stack}`)\n }\n }\n}\n\nexport async function setupApplication(config: Config): Promise<{ stats: Stats; stop: () => Promise<void> }> {\n if (!config.startTimestamp) {\n config.startTimestamp = Date.now()\n }\n\n // Stats.\n const stats = new Stats(config)\n await stats.start()\n\n // Control server.\n let server: Server | undefined\n if (config.serverPort) {\n server = new Server(config, stats)\n await server.start()\n }\n\n // If sessions are set, prepare fake video/audio and start sessions.\n if (config.sessions > 0) {\n // Prepare fake video and audio.\n const mediaPaths: MediaPath[] = []\n if (config.videoPath) {\n for (const videoPath of config.videoPath.split(',')) {\n const ret = await prepareFakeMedia({ ...config, videoPath })\n mediaPaths.push(ret)\n }\n }\n\n // Network throttle.\n if (config.throttleConfig) {\n await startThrottle(config.throttleConfig)\n }\n\n // Download browser if necessary.\n if (!config.chromiumUrl && !config.chromiumPath) {\n await checkChromeExecutable()\n }\n\n // Start session function.\n const startLocalSession = async (id: number, spawnPeriod: number): Promise<void> => {\n const throttleIndex = getSessionThrottleIndex(id)\n const mediaPath = mediaPaths.length ? mediaPaths[id % mediaPaths.length] : undefined\n const session = new Session({\n ...config,\n mediaPath,\n spawnPeriod,\n id,\n throttleIndex,\n })\n session.once('stop', () => {\n console.warn(`Session ${id} stopped, reloading...`)\n setTimeout(startLocalSession, spawnPeriod, id)\n })\n stats.addSession(session)\n await session.start()\n }\n\n // Start the local sessions.\n if (config.randomAudioPeriod) {\n startRandomActivateAudio(\n stats.sessions,\n config.randomAudioPeriod,\n config.randomAudioProbability,\n config.randomAudioRange,\n )\n }\n const spawnPeriod = 1000 / config.spawnRate\n log.debug(`Starting ${config.sessions} sessions (spawnPeriod: ${spawnPeriod}ms)`)\n const startTime = Date.now()\n for (let i = 0; i < config.sessions; i += 1) {\n const id = stats.consumeSessionId(config.tabsPerSession)\n await startLocalSession(id, spawnPeriod)\n // If not the last session, sleep\n if (i < config.sessions - 1) {\n await sleep(spawnPeriod)\n }\n }\n const elapsed = Math.round((Date.now() - startTime) / 1000)\n const spawnRate = (config.sessions * config.tabsPerSession) / elapsed\n log.debug(`${config.sessions * config.tabsPerSession} pages started in ${elapsed}s (${spawnRate.toFixed(2)}/s)`)\n }\n\n return {\n stats,\n stop: async (): Promise<void> => {\n log.debug('Stopping')\n\n stopRandomActivateAudio()\n\n await stats.stop()\n\n if (config.throttleConfig) {\n await stopThrottle()\n }\n\n stopTimers()\n\n await postTest(config)\n\n // Copy docker logs to data directory.\n if (config.pageLogPath) {\n try {\n const logPath = await getDockerLogsPath()\n const dataDir = path.dirname(config.pageLogPath)\n await fs.promises.cp(logPath, path.resolve(dataDir, 'docker.log'))\n } catch (err: unknown) {\n log.debug(`docker logs not found: ${(err as Error).message}`)\n }\n }\n\n server?.stop()\n\n log.debug('Stopped')\n },\n }\n}\n\n/**\n * Main function\n */\nasync function main(): Promise<void> {\n showHelpOrVersion()\n\n const config =\n process.argv[2] === '--prompt'\n ? await loadConfigFromPrompt(process.argv.slice(3).join(' '))\n : await loadConfig(process.argv[2])\n\n if (config.vmafPrepareVideo) {\n await prepareVideo(config, true)\n process.exit(0)\n }\n\n if (config.vmafProcessVideo) {\n await convertToIvf(\n config.vmafProcessVideo,\n config.vmafVideoCrop,\n config.vmafKeepSourceFiles,\n config.vmafSkipDuplicated,\n )\n process.exit(0)\n }\n\n const { stop: stopApplication } = await setupApplication(config)\n\n const stop = async (): Promise<void> => {\n console.log('Exiting...')\n\n await stopApplication()\n\n process.exit(0)\n }\n registerExitHandler(() => stop())\n\n // Stop after a configured duration.\n setTimeout(stop, config.runDuration * 1000)\n\n // Command line interface.\n if (process.stdin && process.stdin.setRawMode) {\n console.log('Press [q] to quit or [x] to exit immediately')\n process.stdin.setRawMode(true)\n process.stdin.resume()\n process.stdin.on('data', async data => {\n log.debug('[stdin]', data[0])\n if (data[0] === 'q'.charCodeAt(0)) {\n try {\n await stop()\n } catch (err: unknown) {\n log.error(`stop error: ${(err as Error).stack}`)\n process.exit(1)\n }\n } else if (data[0] === 'x'.charCodeAt(0)) {\n process.exit(1)\n }\n })\n }\n}\n\nif (require.main === module) {\n main().catch(err => {\n console.error(err)\n process.exit(-1)\n })\n}\n"]}
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/app.ts"],"names":[],"mappings":"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","sourcesContent":["import { getSessionThrottleIndex, startThrottle, stopThrottle } from '@vpalmisano/throttler'\nimport { paramCase } from 'change-case'\nimport fs from 'fs'\nimport json5 from 'json5'\n\nimport { Config, getConfigDocs, loadConfig, loadConfigFromPrompt } from './config'\nimport { MediaPath, prepareFakeMedia } from './media'\nimport { Server } from './server'\nimport { Session } from './session'\nimport { Stats } from './stats'\nimport {\n checkChromeExecutable,\n getDockerLogsPath,\n logger,\n registerExitHandler,\n resolvePackagePath,\n sleep,\n startRandomActivateAudio,\n stopRandomActivateAudio,\n stopTimers,\n} from './utils'\nimport { calculateVisqolScore } from './visqol'\nimport { calculateVmafScore, convertToIvf, prepareVideo } from './vmaf'\nimport path from 'path'\nimport { markedTerminal } from 'marked-terminal'\nimport { EventEmitter } from 'events'\n\n// eslint-disable-next-line @typescript-eslint/no-require-imports\nconst { marked } = require('marked')\nmarked.use(markedTerminal({ reflowText: true, tab: 2 }))\n\nconst log = logger('webrtcperf')\n\nfunction showHelpOrVersion(): void {\n if (process.argv.includes('--help') || process.argv.includes('-h')) {\n const docs = getConfigDocs()\n let out = marked.parse(`**Webrtcperf parameters**\n\n\\`--version\\` It shows the package version.\n`)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n Object.entries(docs).forEach(([name, value]: [string, any]) => {\n out += marked.parse(\n `\n\\`--${paramCase(name)}\\`\n${value.doc}\nDefault value: \\`${value.default}\\`\n`,\n )\n })\n console.log(out)\n process.exit(0)\n } else if (process.argv.includes('--version') || process.argv.includes('-v')) {\n const version = json5.parse(fs.readFileSync(resolvePackagePath('package.json')).toString()).version\n console.log(version)\n process.exit(0)\n }\n}\n\nexport class Application extends EventEmitter {\n readonly config: Config\n readonly stats: Stats\n readonly server?: Server\n private mediaPaths: MediaPath[] = []\n\n constructor(config: Config) {\n super()\n if (!config.startTimestamp) {\n config.startTimestamp = Date.now()\n }\n this.config = config\n this.stats = new Stats(config)\n if (config.serverPort) {\n this.server = new Server(config, this.stats)\n }\n }\n\n async start() {\n log.debug(`start (runDuration: ${this.config.runDuration})`)\n await this.stats.start()\n if (this.server) {\n await this.server.start()\n }\n const config = this.config\n\n // Handle vmaf commands.\n if (config.vmafPrepareVideo) {\n await prepareVideo(config, true)\n }\n if (config.vmafProcessVideo) {\n await convertToIvf(\n config.vmafProcessVideo,\n config.vmafVideoCrop,\n config.vmafKeepSourceFiles,\n config.vmafSkipDuplicated,\n )\n }\n\n // Handle sessions.\n if (config.sessions > 0) {\n // Prepare fake video and audio.\n if (config.videoPath && !this.mediaPaths.length) {\n for (const videoPath of config.videoPath.split(',')) {\n const ret = await prepareFakeMedia({ ...config, videoPath })\n this.mediaPaths.push(ret)\n }\n }\n\n // Network throttle.\n if (config.throttleConfig) {\n await startThrottle(config.throttleConfig)\n }\n\n // Download browser if necessary.\n if (!config.chromiumUrl && !config.chromiumPath) {\n await checkChromeExecutable()\n }\n\n // Start the local sessions.\n if (config.randomAudioPeriod) {\n startRandomActivateAudio(\n this.stats.sessions,\n config.randomAudioPeriod,\n config.randomAudioProbability,\n config.randomAudioRange,\n )\n }\n const spawnPeriod = 1000 / config.spawnRate\n log.debug(`Starting ${config.sessions} sessions (spawnPeriod: ${spawnPeriod}ms)`)\n const startTime = Date.now()\n for (let i = 0; i < config.sessions; i += 1) {\n const id = this.stats.consumeSessionId(config.tabsPerSession)\n await this.startSession(id, spawnPeriod)\n // If not the last session, sleep.\n if (i < config.sessions - 1) {\n await sleep(spawnPeriod)\n }\n }\n const elapsed = Math.round((Date.now() - startTime) / 1000)\n const spawnRate = (config.sessions * config.tabsPerSession) / elapsed\n log.debug(`${config.sessions * config.tabsPerSession} pages started in ${elapsed}s (${spawnRate.toFixed(2)}/s)`)\n }\n\n if (config.runDuration || config.vmafPath || config.visqolPath) {\n setTimeout(() => this.stop(), config.runDuration * 1000)\n }\n }\n\n private async startSession(id: number, spawnPeriod: number) {\n log.debug(`startSession ${id}`)\n const throttleIndex = getSessionThrottleIndex(id)\n const mediaPath = this.mediaPaths.length ? this.mediaPaths[id % this.mediaPaths.length] : undefined\n const session = new Session({\n ...this.config,\n mediaPath,\n spawnPeriod,\n id,\n throttleIndex,\n })\n session.once('stop', () => {\n console.warn(`Session ${id} stopped, reloading...`)\n setTimeout(() => this.startSession(id, spawnPeriod), spawnPeriod)\n })\n this.stats.addSession(session)\n await session.start()\n }\n\n private async postTest() {\n log.debug('postTest')\n\n // vmaf score.\n if (this.config.vmafPath) {\n console.log('Calculating VMAF score...')\n try {\n await calculateVmafScore(this.config)\n } catch (err: unknown) {\n log.error(`vmaf score error: ${(err as Error).stack}`)\n }\n }\n\n // visqol score\n if (this.config.visqolPath) {\n console.log('Calculating Visqol score...')\n try {\n await calculateVisqolScore(this.config)\n } catch (err: unknown) {\n log.error(`visqol score error: ${(err as Error).stack}`)\n }\n }\n }\n\n async stop(canceled = false) {\n log.debug(`stop (canceled: ${canceled})`)\n\n stopRandomActivateAudio()\n\n await this.stats.stop()\n\n if (this.config.throttleConfig) {\n await stopThrottle()\n }\n\n stopTimers()\n\n await this.postTest()\n\n // Copy docker logs to data directory.\n if (this.config.pageLogPath) {\n try {\n const logPath = await getDockerLogsPath()\n const dataDir = path.dirname(this.config.pageLogPath)\n await fs.promises.cp(logPath, path.resolve(dataDir, 'docker.log'))\n } catch (err: unknown) {\n log.debug(`docker logs not found: ${(err as Error).message}`)\n }\n }\n\n this.server?.stop()\n\n this.emit('stop', canceled)\n }\n}\n\n/**\n * Main function\n */\nasync function main(): Promise<void> {\n showHelpOrVersion()\n\n let configs: Config[]\n\n if (process.argv.slice(2).includes('--prompt')) {\n const params = await loadConfigFromPrompt(\n process.argv\n .slice(2)\n .filter(s => !['--prompt', '--dry-run'].includes(s))\n .join(' '),\n )\n if (process.argv.slice(2).includes('--dry-run')) {\n console.log(json5.stringify(params, null, 2))\n process.exit(0)\n }\n configs = await loadConfig(undefined, params)\n } else {\n configs = await loadConfig(process.argv[2])\n }\n\n if (!configs.length) throw new Error('No configuration found')\n\n let application: Application\n const runNext = () => {\n const config = configs.splice(0, 1)[0]\n\n application = new Application(config)\n application.once('stop', canceled => {\n if (!canceled && configs.length) {\n log.info(`Application stopped, running next (${configs.length} left)...`)\n runNext()\n } else {\n process.exit(0)\n }\n })\n return application.start()\n }\n\n const stop = async () => {\n console.log('Exiting...')\n await application.stop(true)\n }\n registerExitHandler(() => stop())\n\n await runNext()\n\n // Command line interface.\n if (process.stdin && process.stdin.setRawMode) {\n console.log('Press [q] to quit or [x] to exit immediately')\n process.stdin.setRawMode(true)\n process.stdin.resume()\n process.stdin.on('data', async data => {\n log.debug('[stdin]', data[0])\n if (data[0] === 'q'.charCodeAt(0)) {\n try {\n await stop()\n } catch (err: unknown) {\n log.error(`stop error: ${(err as Error).stack}`)\n process.exit(1)\n }\n } else if (data[0] === 'x'.charCodeAt(0)) {\n process.exit(1)\n }\n })\n }\n}\n\nif (require.main === module) {\n main().catch(err => {\n console.error(err)\n process.exit(-1)\n })\n}\n"]}
@@ -102,95 +102,6 @@ export type Config = typeof _schemaProperties;
102
102
  /**
103
103
  * Loads the config object.
104
104
  */
105
- export declare function loadConfig(filePath?: string, values?: any): Promise<Config>;
106
- export declare function loadConfigFromPrompt(prompt: string): Promise<{
107
- url: string;
108
- urlQuery: string;
109
- customUrlHandler: string;
110
- videoPath: string;
111
- videoWidth: number;
112
- videoHeight: number;
113
- videoFramerate: number;
114
- videoSeek: number;
115
- videoDuration: number;
116
- videoCacheRaw: boolean;
117
- videoCachePath: string;
118
- videoFormat: string;
119
- useFakeMedia: boolean;
120
- runDuration: number;
121
- throttleConfig: string;
122
- randomAudioPeriod: number;
123
- randomAudioProbability: number;
124
- randomAudioRange: string;
125
- chromiumPath: string;
126
- chromiumVersion: any;
127
- chromiumUrl: string;
128
- chromiumFieldTrials: string;
129
- windowWidth: number;
130
- windowHeight: number;
131
- deviceScaleFactor: number;
132
- maxVideoDecoders: number;
133
- maxVideoDecodersRange: string;
134
- incognito: boolean;
135
- display: string;
136
- sessions: number;
137
- tabsPerSession: number;
138
- startSessionId: number;
139
- startTimestamp: number;
140
- enableDetailedStats: string;
141
- spawnRate: number;
142
- showPageLog: boolean;
143
- pageLogFilter: string;
144
- pageLogPath: string;
145
- enableBrowserLogging: string;
146
- userAgent: string;
147
- scriptPath: string;
148
- scriptParams: string;
149
- disabledVideoCodecs: string;
150
- localStorage: string;
151
- sessionStorage: string;
152
- clearCookies: boolean;
153
- enableGpu: string;
154
- blockedUrls: string;
155
- extraHeaders: string;
156
- responseModifiers: string;
157
- downloadResponses: string;
158
- extraCSS: string;
159
- cookies: string;
160
- overridePermissions: string;
161
- hardwareConcurrency: number;
162
- debuggingPort: number;
163
- debuggingAddress: string;
164
- emulateCpuThrottling: number;
165
- showStats: boolean;
166
- statsPath: string;
167
- detailedStatsPath: string;
168
- statsInterval: number;
169
- rtcStatsTimeout: number;
170
- customMetrics: string;
171
- prometheusPushgateway: string;
172
- prometheusPushgatewayJobName: string;
173
- prometheusPushgatewayAuth: string;
174
- prometheusPushgatewayGzip: boolean;
175
- alertRules: string;
176
- alertRulesOutput: string;
177
- alertRulesFailPercentile: number;
178
- pushStatsUrl: string;
179
- pushStatsId: string;
180
- serverPort: number;
181
- serverSecret: string;
182
- serverUseHttps: boolean;
183
- serverData: string;
184
- vmafPath: string;
185
- vmafPreview: boolean;
186
- vmafKeepIntermediateFiles: boolean;
187
- vmafKeepSourceFiles: boolean;
188
- vmafSkipDuplicated: boolean;
189
- vmafCrop: string;
190
- vmafPrepareVideo: string;
191
- vmafProcessVideo: string;
192
- vmafVideoCrop: string;
193
- visqolPath: string;
194
- visqolKeepSourceFiles: boolean;
195
- }>;
105
+ export declare function loadConfig(filePath?: string, values?: any): Promise<Config[]>;
106
+ export declare function loadConfigFromPrompt(prompt: string): Promise<any>;
196
107
  export {};