@vpalmisano/webrtcperf 4.5.2 → 4.6.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.
- package/app.min.js +1 -1
- package/build/src/app.js +8 -3
- package/build/src/app.js.map +1 -1
- package/build/src/config.d.ts +1 -0
- package/build/src/config.js +9 -1
- package/build/src/config.js.map +1 -1
- package/build/src/docker.js +18 -1
- package/build/src/docker.js.map +1 -1
- package/build/src/plot.js +13 -4
- package/build/src/plot.js.map +1 -1
- package/build/src/rtcstats.d.ts +4 -0
- package/build/src/rtcstats.js +6 -3
- package/build/src/rtcstats.js.map +1 -1
- package/build/src/scenarios.d.ts +2 -1
- package/build/src/scenarios.js +1 -1
- package/build/src/scenarios.js.map +1 -1
- package/build/src/server.js +5 -5
- package/build/src/server.js.map +1 -1
- package/build/src/session.d.ts +3 -1
- package/build/src/session.js +27 -2
- package/build/src/session.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +15 -15
- package/src/app.ts +7 -3
- package/src/config.ts +9 -1
- package/src/docker.ts +20 -1
- package/src/plot.ts +12 -4
- package/src/rtcstats.ts +6 -3
- package/src/scenarios.ts +1 -1
- package/src/server.ts +5 -5
- package/src/session.ts +29 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vpalmisano/webrtcperf",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.6.2",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/vpalmisano/webrtcperf.git"
|
|
@@ -51,10 +51,10 @@
|
|
|
51
51
|
},
|
|
52
52
|
"license": "AGPL-3.0-or-later",
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@google/genai": "^1.
|
|
54
|
+
"@google/genai": "^1.22.0",
|
|
55
55
|
"@puppeteer/browsers": "^2.10.10",
|
|
56
56
|
"@vpalmisano/throttler": "0.0.14",
|
|
57
|
-
"@vpalmisano/webrtcperf-js": "^1.1.
|
|
57
|
+
"@vpalmisano/webrtcperf-js": "^1.1.16",
|
|
58
58
|
"axios": "^1.12.2",
|
|
59
59
|
"chalk-template": "^1.1.2",
|
|
60
60
|
"change-case": "^4.1.2",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"convict": "^6.2.4",
|
|
63
63
|
"convict-format-with-validator": "^6.2.0",
|
|
64
64
|
"debug-level": "^4.1.1",
|
|
65
|
-
"dockerode": "^4.0.
|
|
65
|
+
"dockerode": "^4.0.9",
|
|
66
66
|
"express": "^5.1.0",
|
|
67
67
|
"express-basic-auth": "^1.2.1",
|
|
68
68
|
"fast-stats": "^0.0.7",
|
|
@@ -78,8 +78,8 @@
|
|
|
78
78
|
"pidtree": "^0.6.0",
|
|
79
79
|
"pidusage": "^4.0.1",
|
|
80
80
|
"prom-client": "^15.1.3",
|
|
81
|
-
"puppeteer": "^24.
|
|
82
|
-
"puppeteer-core": "^24.
|
|
81
|
+
"puppeteer": "^24.23.0",
|
|
82
|
+
"puppeteer-core": "^24.23.0",
|
|
83
83
|
"puppeteer-extra": "^3.3.6",
|
|
84
84
|
"puppeteer-extra-plugin-stealth": "^2.11.2",
|
|
85
85
|
"puppeteer-intercept-and-modify-requests": "^1.3.1",
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
"yaml": "^2.8.1"
|
|
91
91
|
},
|
|
92
92
|
"devDependencies": {
|
|
93
|
-
"@eslint/js": "^9.
|
|
93
|
+
"@eslint/js": "^9.37.0",
|
|
94
94
|
"@types/basic-auth": "^1.1.3",
|
|
95
95
|
"@types/compression": "^1.8.1",
|
|
96
96
|
"@types/convict": "^6.1.6",
|
|
@@ -98,18 +98,18 @@
|
|
|
98
98
|
"@types/dockerode": "^3.3.44",
|
|
99
99
|
"@types/fast-stats": "^0.0.35",
|
|
100
100
|
"@types/marked-terminal": "^6.1.1",
|
|
101
|
-
"@types/node": "^20.19.
|
|
101
|
+
"@types/node": "^20.19.19",
|
|
102
102
|
"@types/node-os-utils": "^1.3.4",
|
|
103
103
|
"@types/pidusage": "^2.0.5",
|
|
104
104
|
"@types/sdp-transform": "^2.15.0",
|
|
105
105
|
"@types/sprintf-js": "^1.1.4",
|
|
106
106
|
"@types/tar-fs": "^2.0.4",
|
|
107
107
|
"@types/ws": "^8.18.1",
|
|
108
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
109
|
-
"@typescript-eslint/parser": "^8.
|
|
108
|
+
"@typescript-eslint/eslint-plugin": "^8.45.0",
|
|
109
|
+
"@typescript-eslint/parser": "^8.45.0",
|
|
110
110
|
"@vpalmisano/typedoc-cookie-consent": "^0.0.4",
|
|
111
111
|
"@vpalmisano/typedoc-plugin-ga": "^1.0.6",
|
|
112
|
-
"eslint": "^9.
|
|
112
|
+
"eslint": "^9.37.0",
|
|
113
113
|
"eslint-config-prettier": "^10.1.8",
|
|
114
114
|
"eslint-import-resolver-typescript": "^4.4.4",
|
|
115
115
|
"eslint-plugin-import": "^2.32.0",
|
|
@@ -121,16 +121,16 @@
|
|
|
121
121
|
"terser-webpack-plugin": "^5.3.14",
|
|
122
122
|
"ts-loader": "^9.5.4",
|
|
123
123
|
"typedoc": "^0.28.13",
|
|
124
|
-
"typescript": "^5.9.
|
|
125
|
-
"typescript-eslint": "^8.
|
|
126
|
-
"webpack": "^5.
|
|
124
|
+
"typescript": "^5.9.3",
|
|
125
|
+
"typescript-eslint": "^8.45.0",
|
|
126
|
+
"webpack": "^5.102.0",
|
|
127
127
|
"webpack-cli": "^6.0.1",
|
|
128
128
|
"webpack-node-externals": "^3.0.0",
|
|
129
129
|
"yarn-upgrade-minor": "^1.0.13"
|
|
130
130
|
},
|
|
131
131
|
"optionalDependencies": {
|
|
132
132
|
"chart.js": "^4.5.0",
|
|
133
|
-
"chartjs-chart-error-bars": "^4.4.
|
|
133
|
+
"chartjs-chart-error-bars": "^4.4.5",
|
|
134
134
|
"skia-canvas": "^3.0.8",
|
|
135
135
|
"zeromq": "^6.5.0"
|
|
136
136
|
}
|
package/src/app.ts
CHANGED
|
@@ -292,7 +292,7 @@ async function main(): Promise<void> {
|
|
|
292
292
|
}
|
|
293
293
|
|
|
294
294
|
const stop = async () => {
|
|
295
|
-
|
|
295
|
+
log.info('Exiting...')
|
|
296
296
|
await application.stop(true)
|
|
297
297
|
}
|
|
298
298
|
registerExitHandler(() => stop())
|
|
@@ -301,12 +301,15 @@ async function main(): Promise<void> {
|
|
|
301
301
|
|
|
302
302
|
// Command line interface.
|
|
303
303
|
if (process.stdin && process.stdin.setRawMode) {
|
|
304
|
-
console.log('Press [q] to
|
|
304
|
+
console.log('Press [e] to exit after the current test, [q] to exit immediately or [x] to force exit.')
|
|
305
305
|
process.stdin.setRawMode(true)
|
|
306
306
|
process.stdin.resume()
|
|
307
307
|
process.stdin.on('data', async data => {
|
|
308
308
|
log.debug('[stdin]', data[0])
|
|
309
|
-
if (data[0] === '
|
|
309
|
+
if (data[0] === 'e'.charCodeAt(0)) {
|
|
310
|
+
log.info(`Exiting after the current test (${i + 1}/${total})...`)
|
|
311
|
+
configs.splice(0)
|
|
312
|
+
} else if (data[0] === 'q'.charCodeAt(0)) {
|
|
310
313
|
try {
|
|
311
314
|
await stop()
|
|
312
315
|
} catch (err: unknown) {
|
|
@@ -314,6 +317,7 @@ async function main(): Promise<void> {
|
|
|
314
317
|
process.exit(1)
|
|
315
318
|
}
|
|
316
319
|
} else if (data[0] === 'x'.charCodeAt(0)) {
|
|
320
|
+
log.info('Force exiting...')
|
|
317
321
|
process.exit(1)
|
|
318
322
|
}
|
|
319
323
|
})
|
package/src/config.ts
CHANGED
|
@@ -442,13 +442,21 @@ on the console. Regexp string allowed.`,
|
|
|
442
442
|
arg: 'page-log-path',
|
|
443
443
|
},
|
|
444
444
|
enableBrowserLogging: {
|
|
445
|
-
doc: `It enables the Chromium browser logging for the specified session indexes. It requires the
|
|
445
|
+
doc: `It enables the Chromium browser logging for the specified session indexes. It requires the pageLogPath option to be set.`,
|
|
446
446
|
format: 'index',
|
|
447
447
|
nullable: true,
|
|
448
448
|
default: '',
|
|
449
449
|
env: 'ENABLE_BROWSER_LOGGING',
|
|
450
450
|
arg: 'enable-browser-logging',
|
|
451
451
|
},
|
|
452
|
+
enableRtpDump: {
|
|
453
|
+
doc: `It enables the RTP dump for the specified session indexes. It requires the enableBrowserLogging option to be set. The text2pcap utility is required to convert the RTP dump to pcap format.`,
|
|
454
|
+
format: 'index',
|
|
455
|
+
nullable: true,
|
|
456
|
+
default: '',
|
|
457
|
+
env: 'ENABLE_RTP_DUMP',
|
|
458
|
+
arg: 'enable-rtp-dump',
|
|
459
|
+
},
|
|
452
460
|
userAgent: {
|
|
453
461
|
doc: `The user agent override.`,
|
|
454
462
|
format: String,
|
package/src/docker.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { loadConfig } from './config'
|
|
|
4
4
|
import { runShellCommand } from '@vpalmisano/throttler'
|
|
5
5
|
import os from 'os'
|
|
6
6
|
import fs from 'fs'
|
|
7
|
+
import { Writable } from 'stream'
|
|
7
8
|
|
|
8
9
|
const log = logger('webrtcperf:docker')
|
|
9
10
|
|
|
@@ -57,6 +58,10 @@ export async function runWithDocker(argv: string[]) {
|
|
|
57
58
|
'VIDEO_CACHE_PATH=/root/.webrtcperf/cache',
|
|
58
59
|
]
|
|
59
60
|
|
|
61
|
+
if (process.env.URL) {
|
|
62
|
+
env.push(`URL=${process.env.URL}`)
|
|
63
|
+
}
|
|
64
|
+
|
|
60
65
|
if (configs[0].prometheusPushgateway.startsWith('http://localhost')) {
|
|
61
66
|
env.push('PROMETHEUS_PUSHGATEWAY=http://pushgateway:9091')
|
|
62
67
|
}
|
|
@@ -110,7 +115,21 @@ export async function runWithDocker(argv: string[]) {
|
|
|
110
115
|
})
|
|
111
116
|
|
|
112
117
|
process.stdin.pipe(stream)
|
|
113
|
-
stream.pipe(
|
|
118
|
+
stream.pipe(
|
|
119
|
+
new Writable({
|
|
120
|
+
write: (chunk, _encoding, callback) => {
|
|
121
|
+
const s = chunk.toString('utf-8').trim()
|
|
122
|
+
try {
|
|
123
|
+
const data = JSON.parse(s)
|
|
124
|
+
log.info(data.msg.trim())
|
|
125
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
126
|
+
} catch (_err) {
|
|
127
|
+
log.info(s)
|
|
128
|
+
}
|
|
129
|
+
callback()
|
|
130
|
+
},
|
|
131
|
+
}),
|
|
132
|
+
)
|
|
114
133
|
|
|
115
134
|
await new Promise(resolve => {
|
|
116
135
|
container.wait((err: Error, data: { StatusCode: number }) => {
|
package/src/plot.ts
CHANGED
|
@@ -334,8 +334,16 @@ export async function plotDetailedStatsDashboard(statsFile: string, outFile = 'p
|
|
|
334
334
|
build(graph.id, graph.title, graph.yLabel, graph.processValue, graph.width)
|
|
335
335
|
})
|
|
336
336
|
|
|
337
|
-
const
|
|
338
|
-
|
|
337
|
+
const dirName = path.basename(path.dirname(statsFile))
|
|
338
|
+
let title = dirName
|
|
339
|
+
let description = ''
|
|
340
|
+
try {
|
|
341
|
+
const [_, id, scenario] = dirName.split('_')
|
|
342
|
+
title = id
|
|
343
|
+
description = formatThrottleRule(parseThrottleRule(scenario), true, false)
|
|
344
|
+
} catch (error) {
|
|
345
|
+
log.debug(`Invalid directory name: ${dirName}`, error)
|
|
346
|
+
}
|
|
339
347
|
|
|
340
348
|
const data = `\
|
|
341
349
|
<!DOCTYPE html>
|
|
@@ -343,7 +351,7 @@ export async function plotDetailedStatsDashboard(statsFile: string, outFile = 'p
|
|
|
343
351
|
<head>
|
|
344
352
|
<meta charset="UTF-8">
|
|
345
353
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
346
|
-
<title>${
|
|
354
|
+
<title>${title} (${description})</title>
|
|
347
355
|
<link rel="icon" href="https://raw.githubusercontent.com/vpalmisano/webrtcperf/devel/media/logo.svg">
|
|
348
356
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
349
357
|
<script src="https://cdn.jsdelivr.net/npm/chartjs-chart-error-bars"></script>
|
|
@@ -359,7 +367,7 @@ export async function plotDetailedStatsDashboard(statsFile: string, outFile = 'p
|
|
|
359
367
|
<v-app>
|
|
360
368
|
<v-main>
|
|
361
369
|
<v-app-bar color="primary" density="compact">
|
|
362
|
-
<v-app-bar-title><b>${
|
|
370
|
+
<v-app-bar-title><b>${title}</b>${description ? ` (${description})` : ''}</v-app-bar-title>
|
|
363
371
|
<template v-slot:append>
|
|
364
372
|
<v-select color="primary" :items="participants" v-model="selected" density="compact" variant="solo" hide-details="auto"></v-select>
|
|
365
373
|
</template>
|
package/src/rtcstats.ts
CHANGED
|
@@ -260,7 +260,8 @@ export enum RtcStatsMetricNames {
|
|
|
260
260
|
videoFirCountSent = 'videoFirCountSent',
|
|
261
261
|
videoPliCountSent = 'videoPliCountSent',
|
|
262
262
|
videoDecodeLatency = 'videoDecodeLatency',
|
|
263
|
-
|
|
263
|
+
videoFramesDecoded = 'videoFramesDecoded',
|
|
264
|
+
videoFramesDropped = 'videoFramesDropped',
|
|
264
265
|
videoRecvFrames = 'videoRecvFrames',
|
|
265
266
|
videoRecvFps = 'videoRecvFps',
|
|
266
267
|
videoRecvAvgJitterBufferDelay = 'videoRecvAvgJitterBufferDelay',
|
|
@@ -285,7 +286,8 @@ export enum RtcStatsMetricNames {
|
|
|
285
286
|
screenFirCountSent = 'screenFirCountSent',
|
|
286
287
|
screenPliCountSent = 'screenPliCountSent',
|
|
287
288
|
screenDecodeLatency = 'screenDecodeLatency',
|
|
288
|
-
|
|
289
|
+
screenFramesDecoded = 'screenFramesDecoded',
|
|
290
|
+
screenFramesDropped = 'screenFramesDropped',
|
|
289
291
|
screenRecvFrames = 'screenRecvFrames',
|
|
290
292
|
screenRecvFps = 'screenRecvFps',
|
|
291
293
|
screenRecvAvgJitterBufferDelay = 'screenRecvAvgJitterBufferDelay',
|
|
@@ -437,7 +439,8 @@ export function updateRtcStats(
|
|
|
437
439
|
})
|
|
438
440
|
}
|
|
439
441
|
if (inboundRtp.kind === 'video' && inboundRtp.keyFramesDecoded > 0) {
|
|
440
|
-
|
|
442
|
+
setStats(stats, (prefix + 'FramesDecoded') as RtcStatsMetricNames, key, inboundRtp.framesDecoded)
|
|
443
|
+
setStats(stats, (prefix + 'FramesDropped') as RtcStatsMetricNames, key, inboundRtp.framesDropped)
|
|
441
444
|
setStats(stats, (prefix + 'RecvFrames') as RtcStatsMetricNames, key, inboundRtp.framesReceived)
|
|
442
445
|
setStats(stats, (prefix + 'RecvFps') as RtcStatsMetricNames, key, inboundRtp.framesPerSecond)
|
|
443
446
|
setStats(stats, (prefix + 'RecvHeight') as RtcStatsMetricNames, key, inboundRtp.frameHeight)
|
package/src/scenarios.ts
CHANGED
|
@@ -259,7 +259,7 @@ export async function plotStatsSummary(stats: StatsSummary[]) {
|
|
|
259
259
|
export async function twoParticipantsWithRateLossDelay(
|
|
260
260
|
id: string,
|
|
261
261
|
{ rate, loss, delay, direction }: { rate: number; loss: number; delay: number; direction: ThrottleDirection },
|
|
262
|
-
repeat
|
|
262
|
+
repeat = 1,
|
|
263
263
|
) {
|
|
264
264
|
const throttle: ThrottleConfig = {}
|
|
265
265
|
const queue = 25
|
package/src/server.ts
CHANGED
|
@@ -241,7 +241,7 @@ export class Server {
|
|
|
241
241
|
throw new Error(`Session not found: "${sessionId}"`)
|
|
242
242
|
}
|
|
243
243
|
const filePath = await session.pageScreenshot(pageId, format)
|
|
244
|
-
res.sendFile(path.resolve(filePath))
|
|
244
|
+
res.sendFile(path.resolve(filePath), { dotfiles: 'allow' })
|
|
245
245
|
} catch (err) {
|
|
246
246
|
next(err)
|
|
247
247
|
}
|
|
@@ -365,7 +365,7 @@ export class Server {
|
|
|
365
365
|
if (req.query.range && !req.headers.range) {
|
|
366
366
|
req.headers.range = `bytes=${req.query.range}`
|
|
367
367
|
}
|
|
368
|
-
res.sendFile(path.resolve(this.pageLogPath))
|
|
368
|
+
res.sendFile(path.resolve(this.pageLogPath), { dotfiles: 'allow' })
|
|
369
369
|
}
|
|
370
370
|
|
|
371
371
|
/**
|
|
@@ -386,7 +386,7 @@ export class Server {
|
|
|
386
386
|
if (req.query.range && !req.headers.range) {
|
|
387
387
|
req.headers.range = `bytes=${req.query.range}`
|
|
388
388
|
}
|
|
389
|
-
res.sendFile(path.resolve(logPath))
|
|
389
|
+
res.sendFile(path.resolve(logPath), { dotfiles: 'allow' })
|
|
390
390
|
} catch (err) {
|
|
391
391
|
next(err)
|
|
392
392
|
}
|
|
@@ -441,7 +441,7 @@ export class Server {
|
|
|
441
441
|
if (req.query.range && !req.headers.range) {
|
|
442
442
|
req.headers.range = `bytes=${req.query.range}`
|
|
443
443
|
}
|
|
444
|
-
res.sendFile(fpath)
|
|
444
|
+
res.sendFile(fpath, { dotfiles: 'allow' })
|
|
445
445
|
}
|
|
446
446
|
|
|
447
447
|
private getDataArchive(req: express.Request, res: express.Response, next: express.NextFunction): void {
|
|
@@ -465,7 +465,7 @@ export class Server {
|
|
|
465
465
|
if (req.query.range && !req.headers.range) {
|
|
466
466
|
req.headers.range = `bytes=${req.query.range}`
|
|
467
467
|
}
|
|
468
|
-
res.sendFile(fpath)
|
|
468
|
+
res.sendFile(fpath, { dotfiles: 'allow' })
|
|
469
469
|
}
|
|
470
470
|
|
|
471
471
|
/**
|
package/src/session.ts
CHANGED
|
@@ -43,6 +43,7 @@ import {
|
|
|
43
43
|
portForwarder,
|
|
44
44
|
resolveIP,
|
|
45
45
|
resolvePackagePath,
|
|
46
|
+
runShellCommand,
|
|
46
47
|
sha256,
|
|
47
48
|
sleep,
|
|
48
49
|
waitStopProcess,
|
|
@@ -147,6 +148,7 @@ export interface SessionParams {
|
|
|
147
148
|
useFakeMedia: boolean
|
|
148
149
|
enableGpu: string
|
|
149
150
|
enableBrowserLogging: string
|
|
151
|
+
enableRtpDump: string
|
|
150
152
|
startTimestamp: number
|
|
151
153
|
sessions: number
|
|
152
154
|
tabsPerSession: number
|
|
@@ -218,6 +220,7 @@ export class Session extends EventEmitter {
|
|
|
218
220
|
private readonly useFakeMedia: boolean
|
|
219
221
|
private readonly enableGpu: string
|
|
220
222
|
private readonly enableBrowserLogging: boolean
|
|
223
|
+
private readonly enableRtpDump: boolean
|
|
221
224
|
private readonly startTimestamp: number
|
|
222
225
|
private readonly sessions: number
|
|
223
226
|
private readonly tabsPerSession: number
|
|
@@ -365,6 +368,7 @@ export class Session extends EventEmitter {
|
|
|
365
368
|
useFakeMedia,
|
|
366
369
|
enableGpu,
|
|
367
370
|
enableBrowserLogging,
|
|
371
|
+
enableRtpDump,
|
|
368
372
|
startTimestamp,
|
|
369
373
|
sessions,
|
|
370
374
|
tabsPerSession,
|
|
@@ -433,6 +437,7 @@ export class Session extends EventEmitter {
|
|
|
433
437
|
this.useFakeMedia = useFakeMedia
|
|
434
438
|
this.enableGpu = enableGpu
|
|
435
439
|
this.enableBrowserLogging = enabledForSession(this.id, enableBrowserLogging)
|
|
440
|
+
this.enableRtpDump = enabledForSession(this.id, enableRtpDump)
|
|
436
441
|
this.startTimestamp = startTimestamp || Date.now()
|
|
437
442
|
this.sessions = sessions || 1
|
|
438
443
|
this.tabsPerSession = tabsPerSession || 1
|
|
@@ -595,12 +600,15 @@ export class Session extends EventEmitter {
|
|
|
595
600
|
|
|
596
601
|
let fieldTrials = this.chromiumFieldTrials || ''
|
|
597
602
|
|
|
598
|
-
if (this.
|
|
603
|
+
if (this.pageLogPath && this.enableBrowserLogging) {
|
|
599
604
|
const pageLogDir = path.dirname(this.pageLogPath)
|
|
600
605
|
const eventLogPath = path.resolve(pageLogDir, `webrtc-event-logging-${this.id}`)
|
|
601
606
|
fs.mkdirSync(eventLogPath, { recursive: true })
|
|
602
607
|
args.push('--enable-logging', '--vmodule=*/webrtc/*=5', '--v=0', `--webrtc-event-logging=${eventLogPath}`)
|
|
603
608
|
fieldTrials = 'WebRTC-RtcEventLogNewFormat/Disabled/' + fieldTrials
|
|
609
|
+
if (this.enableRtpDump) {
|
|
610
|
+
fieldTrials = 'WebRTC-Debugging-RtpDump/Enabled/' + fieldTrials
|
|
611
|
+
}
|
|
604
612
|
env.CHROME_LOG_FILE = path.resolve(pageLogDir, `chrome-${this.id}.log`)
|
|
605
613
|
}
|
|
606
614
|
|
|
@@ -1467,6 +1475,26 @@ Object.defineProperty(window.screen.orientation, 'type', { value: 'landscape-pri
|
|
|
1467
1475
|
page.once('close', () => throttleNotifier.off('change', onThrottleChange))
|
|
1468
1476
|
}
|
|
1469
1477
|
|
|
1478
|
+
if (this.pageLogPath && this.enableRtpDump) {
|
|
1479
|
+
page.once('close', async () => {
|
|
1480
|
+
const dirPath = path.dirname(this.pageLogPath)
|
|
1481
|
+
const logFilePath = path.join(dirPath, `chrome-${this.id}.log`)
|
|
1482
|
+
if (fs.existsSync(logFilePath)) {
|
|
1483
|
+
const pcapFilePath = path.join(dirPath, `chrome-${this.id}.pcap`)
|
|
1484
|
+
try {
|
|
1485
|
+
await runShellCommand(`\
|
|
1486
|
+
grep RTP_DUMP ${logFilePath} | text2pcap -D -u 1000,2000 -t %H:%M:%S.%f - ${pcapFilePath};
|
|
1487
|
+
grep -v RTP_DUMP ${logFilePath} > ${logFilePath}.tmp;
|
|
1488
|
+
mv ${logFilePath}.tmp ${logFilePath};
|
|
1489
|
+
`)
|
|
1490
|
+
log.info(`rtp dump saved to: ${pcapFilePath}`)
|
|
1491
|
+
} catch (err) {
|
|
1492
|
+
log.error(`error converting rtp dump to pcap: ${(err as Error).stack}`)
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1495
|
+
})
|
|
1496
|
+
}
|
|
1497
|
+
|
|
1470
1498
|
log.debug(`Page ${index + 1} "${url}" loaded in ${(Date.now() - pageLoadTime) / 1000}s`)
|
|
1471
1499
|
|
|
1472
1500
|
for (let i = 0; i < this.evaluateAfter.length; i++) {
|