webrtcperf

by vpalmisano

Not rated
GitHub

About

WebRtcPerf is an open-source tool designed for testing WebRTC services with multiple concurrent client connections, measuring the most important RTC statistics and collecting them in an easy way.

Details

Author
vpalmisano
Categories
Developer Tools, Automation, Infrastructure, Other

Setup

Install webrtcperf in your MCP client (Claude Desktop, Cursor, Windsurf, and others).

Repository: https://github.com/vpalmisano/webrtcperf

Follow the installation instructions in the repository README, then restart your MCP client.

WebRtcPerf is an open-source tool designed for testing WebRTC services with multiple concurrent client connections, measuring the most important RTC statistics and collecting them in an easy way. This documentation will dive into its multiple features and configuration options, showing you how to leverage this tool to gain valuable insights into your real-time communication solutions.

The webrtcperf tool is a NodeJS application spawning multiplePuppeteerheadless browsers that will actually start the WebRTC connections, so it could ideally run on every platform where NodeJS and Chromium browser could run. Anyway, to gain advantage of some specific features, using a Linux OS is the suggested way to use the tool. If you plan to run multiple concurrent connections to an external host running the WebRTC service, you need to make sure that your machine has enough network bandwidth to send and receive the audio/video streams without affecting the quality and an amount of CPU and memory proportional to the number of clients that you want to start. Anyway, you can also use a limited machine at the purpose, in order to evaluate how the WebRTC server and the client react to the constrained environment. Consider also that the tool uses theTraffic Controller (TC)framework on Linux to apply network constraints and change them while running the tests.

npm install -g @vpalmisano/webrtcperf webrtcperf --help

Make sure to have FFMpeg installed on the same machine.

Alternatively, use the Docker pre-built image:

docker pull ghcr.io/vpalmisano/webrtcperf:devel docker run -it ghcr.io/vpalmisano/webrtcperf:devel --help

The tool can also be used from the source code:

git clone https://github.com/vpalmisano/webrtcperf.git cd webrtcperf yarn build yarn start --help

The command line arguments can be explicitly provided using the lower snake case format (e.g.--run-duration=or setting the corresponding environment variable in upper snake case format (RUN_DURATION=). The command line params have precedence over the corresponding environment variables. Alternatively, it is possible to load the configuration variables saved in lower camel case into a local JSON/JSON5, YAML or TOML file; the file can also be stored remotely and loaded using its public HTTP URL.
Example running a simple scenario with
Mediasoup demo:

webrtcperf https://raw.githubusercontent.com/vpalmisano/webrtcperf/refs/heads/devel/examples/scenarios/mediasoup.json

Stop the tool pressingq(normal browser close) orx(it will close the process immediately).

Let’s start running some simple test scenarios with only 2 participants. The command line arguments required to join a Google Meet public room are:

webrtcperf \ --sessions=1 \ --run-duration=600 \ --url=https://meet.google.com/<ID> \ --debugging-port=9000 \ --script-path=https://raw.githubusercontent.com/vpalmisano/webrtcperf/refs/heads/devel/examples/google-meet.js

In particular, the mandatory arguments are:

- --sessions: the total number of chromium browser sessions that we want to start.
- --run-duration: the test run duration in seconds.
- --url: the remote URL that we want to visit.

Other arguments required to join a Google Meet room:

- --debugging-port: set to a value different from zero in order to disable the webdriver feature (https://issues.chromium.org/issues/40746300).
- --script-path: it injects a javascript code into the running page. It accepts a comma separated list of local file paths or http urls. In this case, the code automatically fills in the user name and it joins the room.

By default, the tool will periodically output some metrics fetched from the running RTC PeerConnection objects. The metrics are aggregated across all the running sessions, showing the sum (when it makes sense), mean, standard deviation, 5th and 95th percentiles, min and max values.

-- Wed, 04 Jun 2025 11:04:30 GMT ------------------------------------------------------------------- name count sum mean stddev 5p 95p min max System CPU 1 10.20 0.00 10.20 10.20 10.20 10.20 % System GPU 1 22.00 0.00 22.00 22.00 22.00 22.00 % System Memory 1 33.64 0.00 33.64 33.64 33.64 33.64 % CPU/page 1 92.29 92.29 0.00 92.29 92.29 92.29 92.29 % Memory/page 1 2021.88 2021.88 0.00 2021.88 2021.88 2021.88 2021.88 MB Pages 1 1 1 0 1 1 1 1 Errors 1 0 0 0 0 0 0 0 Warnings 1 0 0 0 0 0 0 0 Peer Connections 1 1 1 0 1 1 1 1 -- Inbound audio ----------------------------------------------------------------------------------- -- Inbound video ----------------------------------------------------------------------------------- -- Outbound audio ---------------------------------------------------------------------------------- rate 1 73.81 73.81 0.00 73.81 73.81 73.81 73.81 Kbps lost 1 0.00 0.00 0.00 0.00 0.00 0.00 % roundTripTime 1 0.033 0.000 0.033 0.033 0.033 0.033 s -- Outbound video ---------------------------------------------------------------------------------- sent 1 2.62 2.62 0.00 2.62 2.62 2.62 2.62 MB rate 1 1209.16 1209.16 0.00 1209.16 1209.16 1209.16 1209.16 Kbps lost 1 0.00 0.00 0.00 0.00 0.00 0.00 % roundTripTime 1 0.000 0.000 0.000 0.000 0.000 0.000 s qualityLimitResolutionChanges 1 0 0 0 0 0 0 0 qualityLimitationCpu 1 0 0 0 0 0 0 0 % qualityLimitationBandwidth 1 0 0 0 0 0 0 0 % width 1 1280 0 1280 1280 1280 1280 px height 1 720 0 720 720 720 720 px fps 1 25 0 25 25 25 25 fps firCountReceived 1 0 0 0 0 0 0 pliCountReceived 1 0 0 0 0 0 0

- System CPU/GPU/Memory: the % of the system used CPU, GPU and RSS memory (ranging from 0 to 100%).
- CPU/page: the amount of CPU % used by each chromium process, including all the children processes (ranging from 0 to N00% depending on the number of available CPU cores).
- Memory/page: the RSS memory used by each chromium process, including all the children processes.
- Pages: the number of opened pages (it should match the--sessionsprovided value).
- Errors, Warnings: the cumulative number of errors and warn logs collected by each page.
- Peer Connections: the number of connected RTC Peer Connection objects running in each page.
- rate: the ingress/egress bitrate.
- lost: the % of lost packets.
- roundTripTime: the Round Trip Time value.
- qualityLimitResolutionChanges: the count of quality limitation events.
- qualityLimitationCpu, qualityLimitationBandwidth: the % of time the sender has run with a quality limitation.
- width, height, fps: the current sent resolution and frame rate.
- firCountReceived, pliCountReceived: they count the number FIR/PLI (keyframe) requested to that sender.

Let’s see what happens when we start increasing the number of sessions, introducing more participants in the same room (--sessions=2):

-- Wed, 04 Jun 2025 11:34:00 GMT ------------------------------------------------------------------- name count sum mean stddev 5p 95p min max System CPU 2 18.92 0.00 18.92 18.92 18.92 18.92 % System GPU 2 0.00 0.00 0.00 0.00 0.00 0.00 % System Memory 2 33.98 0.00 33.98 33.98 33.98 33.98 % CPU/page 2 370.03 185.01 1.91 183.10 186.93 183.10 186.93 % Memory/page 2 3914.67 1957.34 10.50 1946.84 1967.83 1946.84 1967.83 MB Pages 2 2 1 0 1 1 1 1 Errors 2 0 0 0 0 0 0 0 Warnings 2 0 0 0 0 0 0 0 Peer Connections 2 2 1 0 1 1 1 1 -- Inbound audio ----------------------------------------------------------------------------------- rate 2 89.64 44.82 0.02 44.80 44.83 44.80 44.83 Kbps lost 2 0.00 0.00 0.00 0.00 0.00 0.00 % jitter 2 0.00 0.00 0.00 0.00 0.00 0.00 s avgJitterBufferDelay 2 65.87 13.25 52.62 79.12 52.62 79.12 ms -- Inbound video ----------------------------------------------------------------------------------- received 2 12.93 6.47 0.01 6.46 6.48 6.46 6.48 MB rate 2 2985.18 1492.59 15.29 1477.30 1507.88 1477.30 1507.88 Kbps lost 2 0.00 0.00 0.00 0.00 0.00 0.00 % jitter 2 0.01 0.00 0.01 0.01 0.01 0.01 s avgJitterBufferDelay 2 52.64 4.28 48.36 56.92 48.36 56.92 ms width 2 1280 0 1280 1280 1280 1280 px height 2 720 0 720 720 720 720 px fps 2 25 0 24 25 24 25 fps -- Outbound audio ---------------------------------------------------------------------------------- rate 2 154.32 77.16 0.01 77.15 77.17 77.15 77.17 Kbps lost 2 0.00 0.00 0.00 0.00 0.00 0.00 % roundTripTime 2 0.032 0.001 0.031 0.033 0.031 0.033 s -- Outbound video ---------------------------------------------------------------------------------- sent 2 13.72 6.86 0.03 6.83 6.90 6.83 6.90 MB rate 2 2986.60 1493.30 15.40 1477.91 1508.70 1477.91 1508.70 Kbps lost 2 0.00 0.00 0.00 0.00 0.00 0.00 % roundTripTime 2 0.032 0.001 0.031 0.033 0.031 0.033 s qualityLimitResolutionChanges 2 0 0 0 0 0 0 0 qualityLimitationCpu 2 0 0 0 0 0 0 0 % qualityLimitationBandwidth 2 0 0 0 0 0 0 0 % width 2 1280 0 1280 1280 1280 1280 px height 2 720 0 720 720 720 720 px fps 2 25 0 25 25 25 25 fps firCountReceived 2 0 0 0 0 0 0 pliCountReceived 2 0 0 0 0 0 0

As we can see from the command output, now we havecount=2for all the metrics and we start noticing some differences between the sum, average, min, max and percentile values.

Collecting and analyzing the metrics using the command console output could be a difficult task, especially when we increase the number of sessions. At this purpose, webrtcperf allows sending the metrics values to an external Prometheus/Grafana service, through a Pushgateway service. An example docker compose configuration to run all the required services is available athttps://github.com/vpalmisano/webrtcperf/tree/devel/prometheus-stack.
Assuming that the Pushgateway service is running onlocalhost:9091, the additional param to include to the command line is:--prometheus-pushgateway=http://localhost:9091
If the Pushgateway server is protected by username and password credentials, just add the--prometheus-pushgateway-auth=username:passwordparam.
Additionally, we can change the Prometheusjob=defaulttag using the--prometheus-pushgateway-job-name=custom-tagparam; this way, we can easily differentiate the metrics coming from different or concurrent test runs.

Visiting the Grafana service started with the previous docker compose it is possible to access the example dashboard, showing a number of metrics collected by webrtcperf:

In the previous examples we used the--urloption to set a page target URL that is used by all the running sessions. The tool has other two options in order to customize the destination url:

-

--url-query: It allows you to specify an additional URL query string that will be attached to the provided--url. The string can include some template variables that will be replaced at run time:

- $pthe process pid
- $sthe session index
- $Sthe total sessions
- $tthe tab index
- $Tthe total tabs per session
- $ithe tab absolute index

Example:--url-query=”participantName=Test-$i”will attach?participantName=Test-0,?participantName=Test-1to the corresponding session url.

--custom-url-handler: This option accepts a javascript module path containing a single exported function that will be invoked for each started session. Use this option without setting the--urloption.
The function will be invoked with a single object with the following properties:

tabsPerSession: the total number of tabs per session;

id: the session global index (0-indexed);

index: the tab global index (0-indexed);

tabIndex: the tab index in the current session (0-indexed);

export default function ({ id, sessions, tabIndex, tabsPerSession, index, env, pid }) { return https://example.com/${id}/${sessions}/${tabIndex}/${tabsPerSession}/${index}/${pid} }

The tool leverages several options offered by chromium to specify an audio/video input file that will be used as getUserMedia source. Using fake audio and video allows us to run consistent and repeatable tests, without introducing the implicit randomness that will be caused by running tests with a local webcam/microphone inputs.
The tool allows to configure the following options:

- --video-path: A file path used as source for the audio and video streams. FFMpeg will be used to convert this file into a format that is accepted by the chromium options, thus any input format accepted by ffmpeg is a valid value (e.g.https://…). Additionally, usinggenerate:nullwill generate a black video and silent audio track; withgenerate:testit will generate an ffmpegtestsrcvideo pattern and a single frequency audio with beep pattern. The option is set by default to this test videohttps://github.com/vpalmisano/webrtcperf/releases/download/videos-1.0/kt.mp4. More test videos are available under this release tag:https://github.com/vpalmisano/webrtcperf/releases/tag/videos-1.0.
- --video-width,--video-height,--video-framerate: the resolution and the video frame rate that will be used to upscale or downscale the input video.
- --video-seek: the seek time in seconds from the start in the provided video.
- --video-duration: the total duration used to trim the input video.
- --video-cache-raw: when true (default value) the generated files will be cached into the~/.webrtcperf/cachedirectory.
- --video-format: the video format used for video track conversion; it could be “y4m” (raw yuv video, the default value) or “mjpeg”.
- --use-fake-media:

- when true (default), the supplied file specified with videoPath will be converted into raw audio and video files that will be passed to the chromium executable using theuse-fake-ui-for-media-stream,use-file-for-fake-video-captureanduse-file-for-fake-audio-captureparams. The getUserMedia calls will output tracks generated from the provided raw files.
- When false, the browser will run without any fake media option but the webrtcperf default page script will override the getUserMedia call loading an hidden video element inside the page and using it as source for the generated tracks. The advantage of using this approach is that the audio and video tracks will run in sync, so it can be used to detect audio/video desynchronization; the disadvantage is the higher page memory and CPU usage caused by decoding the fake media.

The chromium default behaviour to fake the display media track allows to get a generated video animation that is usually very different from what we have in a regular video conference when users share a static presentation with slide transitions. In fact, the chromium generated animation produces a constant bitrate stream, while a real presentation generates a low bitrate at average with big spikes caused by the slide transitions. Emulating this behavior is essential to assess the video quality of the screen sharing in a video conference service.
In webrtcperf, the getDisplayMedia calls will output a video track that is obtained from sharing the current browser window (when--use-fake-media=true) or a new browser tab (--use-fake-media=false). In both cases, the tool will use a page script automation that generates a fake screenshare sequence that can be customized adding afakeScreenshareoption in the--script-paramscommand line option. ThefakeScreenshareoption accepts the following params:

- animationDuration: the slide animation duration expressed in milliseconds (default: 1000).
- delay: the slide change delay in milliseconds (default: 5000).
- embed: an optional URL specifying a document or an external Google Drive presentation that will be loaded inside an iframe element.
- width,height: the screen share resolution (default: 1920x1080)
- pointerAnimation: if different from zero, it will draw a random animation emulating the mouse movement.
- slides: the total slides to generate (default: 4).
- urls: an optional array of strings that could include (even in mixed order):

-

an image or video URL that will be used as slide content;

a document that will be embedded into an iframe element and it will be used as slide content.

When both slides and embed are not provided, the tool will load the images fromhttps://picsum.photos.

Internet available bandwidth, network latency and packet loss are factors that usually could impact the perceived quality of a video conference service. Replicating the network conditions that affect real users is usually a good way to assess if the WebRTC service is able to adapt to the available bandwidth (increasing or decreasing the video resolution and the framerate) and deal with the packet loss and delay.
The webrtcperf tool includes a network throttling functionality offered by the
https://github.com/vpalmisano/throttlerproject, that is essentially a NodeJS wrapper of the Linux Traffic Controller framework (https://tldp.org/HOWTO/Traffic-Control-HOWTO/intro.html) and NetEm. The--throttle-configparam accepts a JSON/JSON5 encoded string containing an array of throttler configuration; each configuration item is an object containing the following properties:

- sessions(string): The webrtcperf sessions IDs that will use this throttle configuration. It could be a single index ("0"), a range ("0-2") or a comma-separated list ("0,3,4").
- up,down(string, JSON): A single or an array of throttle rules that will be applied to the uplink and to the downlink.
- protocol("udp" | "tcp"): If specified, only TCP or UDP packets will be throttled.
- device(string): The network interface to throttle. If not specified, the default interface will be used.
- filter(string): An additional IPTables packet filter rule.
- match(string): An additional
TC match expressionused to filter packets.
- skipSourcePorts,skipDestinationPorts(string): A comma-separated list of source and destination ports that will not be throttled. Example usage: in some cases it is better to avoid throttling the 80,443 ports, otherwise the web application will fail to load.
- capture(string): If set, the packets matching the provided session and protocol will be captured at that file location in PCAP format.

Each throttle rule could include the following properties that controls the corresponding value in theNetEmtool:

- rate: The available bandwidth (Kbps).
- delay: The one-way delay (ms).
- delayJitter: The one-way delay jitter (ms).
- delayJitterCorrelation: The one-way delay jitter correlation.
- delayDistribution: The delay distribution ('uniform' | 'normal' | 'pareto' | 'paretonormal').
- reorder: The packet reordering percentage.
- reorderCorrelation: The packet reordering correlation.
- reorderGap: The packet reordering gap.
- loss: The packet loss percentage.
- lossBurst: The packet loss burst.
- queue: The packet queue size.
- at: If set, the rule will be applied after the specified number of seconds.

Examples
Run a two participants video conference on Google Meet, throttling the the first participant uplink at 500Kbps, 100ms delay and 2% packet loss:

webrtcperf \ --sessions=2 \ --run-duration=300 \ --url=https://meet.google.com/<ID> \ --debugging-port=9000 \ --script-path=https://raw.githubusercontent.com/vpalmisano/webrtcperf/refs/heads/devel/examples/google-meet.js \ --prometheus-pushgateway=http://localhost:9091 \ --throttle-config='[{sessions:"0",protocol:"udp",up:[{rate:500,delay:100,loss:2,queue:50}]}]'

The “Participant-000000” video stream has a visible lower quality compared with “Participant-000001”:

Comparing the same test run without and with network throttler option, we can see how the sent bitrate decreased from an average of ~600Kbps down to ~300Kbps; packet loss increased up to 1-2% and the round trip time increase from ~40ms up to ~150ms:

Let’s run another test with a different throttle configuration. In this case we specify multiple rules for the upstream limitation, using a differentatvalue for each one, in particular what we want to test is:

- start applying a bitrate limitation of 1Mbps;
- after 60 seconds, change the bitrate limitation to 500Kbps;
- after 60 seconds, set the bitrate again to 1Mbps.

webrtcperf \ --sessions=2 \ --run-duration=300 \ --url=https://meet.google.com/<ID> \ --debugging-port=9000 \ --script-path=https://raw.githubusercontent.com/vpalmisano/webrtcperf/refs/heads/devel/examples/google-meet.js \ --prometheus-pushgateway=http://localhost:9091 \ --throttle-config='[{ sessions:"0", protocol:"udp", up: [ { rate:1000, delay:100, queue:50 }, { rate:500, delay:100, queue:50, at:60 }, { rate:1000, delay:100, queue:50, at:120 }, ] }]'

Looking at the measured metrics, we see the effect of the bandwidth limitation change:

- the video bitrate decreased from 600Kbps to 300Kbps from t=60 to t=120;
- we got some packet loss after the bandwidth decrease;
- the bandwidth quality limitation indicator increased to ~80% in the same time interval.

Using a fake media file with continuous speech when we run tests with multiple participants is not close to what happens in a real video conference room, when participants usually talk at turn without overlapping. The webrtcperf page automation permits to automatically activate/deactivate the audio tracks captured with getUserMedia changing thetrack.enabledproperty; the mechanism can be controlled with the following command line options:

- --random-audio-period: It specifies the maximum period in seconds after which a new random active session is selected, enabling the getUserMedia audio tracks in that session and disabling all of the others.
- --random-audio-probability: it defines the probability % that the selected audio will be activated (default: 100%). Setting this value to value lower than 100, will have the effect of deactivating the audio for all the sessions.
- --random-audio-range: It defines the session indexes that should be included into the random selection mechanism (default: include all the sessions).

Additionally to thetrack.enabledproperty, the tool will invoke thepublisherSetMuted(true | false)function, if that function has been implemented in a custom page script (loaded with--script-path); this way it is possible to trigger the muted state clicking on the corresponding mute/unmute button inside the page, depending on the particular service we are testing.

Using the custom Chromium build to save CPU

Running tests with many participants increases the amount of CPU required to render the page, encode the audio/video streams and decode them at the receiver side. The webrtcperf docker image includes amodified Chromium versionthat allows the tool to specify a maximum number of RTC video streams to decode in parallel for each browser session. The value can be controlled using the following command line options:

- --max-video-decoders: The maximum number of RTC video streams that will be decoded by each browser session (default: 0, decode all the videos).
- --max-video-decoders-range: It applies the max video decoders option to the sessions included into this list (default: “true” that will include all the sessions).

It is worth noticing that disabling the video stream decoding would cause some RTC metrics (e.g. the received width, height, framerate) to always report a zero value. The suggested way to use this feature is keeping the video decoder enabled for a percentage of sessions, depending on the amount of cpu that we want to save.
The modified Chromium version can be build from sources using the following commands:

git clone https://github.com/vpalmisano/webrtcperf.git cd webrtcperf/chromium ./build.sh setup # Use a valid tag version ./build.sh update "tags/139.0.7230.1" ./build.sh build # install the package (on Ubuntu/Debian) sudo dpkg -i ./chromium-browser-unstable_139.0.7230.1-1_amd64.deb

Once that the custom Chromium package has been installed, specify the executable path with the--chromium-pathoption (or setting theCHROMIUM_PATHenv variable):

export CHROMIUM_PATH=/usr/bin/chromium-browser-unstable webrtcperf https://raw.githubusercontent.com/vpalmisano/webrtcperf/refs/heads/devel/examples/scenarios/mediasoup.json

The tool offers several logging options to save the opened pages logs and, optionally, the full chromium process output.

- --show-page-log: If true (default) the pages console logs will be shown on console.
- --page-log-filter: If set, only the logs with the matching text or regular expression will be printed on the console.
- --page-log-path: If set, the page console logs will be saved on the selected file path.
- --enable-browser-logging: It enables the Chromium browser logging for the specified session indexes. It requires the--page-log-pathoption to be set. When enabled, the tool will enable the chromium verbose logging (with--vmodule=/webrtc/=5) that will be written into the page log path directory. It also activates the Chromium--webrtc-event-loggingoption, that will save the event logging file in the same directory (you can use
https://github.com/fippo/dump-webrtc-event-logto parse this file).

In the previous examples we used the--script-pathoption providing a javascript page that runs some page automation (like automatically filling in the participant name and clicking on the join button). By default, the webrtcperf tool will load thewebrtcperf-jsscript bundle, that provides a number of utilities to automate the testing tasks and run advanced measurements into the page context. The custom script provided with--script-pathoption can access the webrtcperf-js utilities under thewebrtcperfglobal object. Some of the features offered by webrtcperf-js needs to be configured at the page load time; at this purpose, webrtcperf offers the--script-paramsoption that can be used to provide a JSON/JSON5 object with the values that will be set into thewebrtcperf.paramsobject.

Measuring the end-to-end (mouth-to-ear) delay

Setting thetimestampWatermarkAudioandtimestampWatermarkVideoscript params will enable a webrtcperf-js feature that automatically applies a video watermark overlay and an audio modulated signal containing the sender UNIX timestamp. At the receiver side, the video overlay will be recognized using theTesseract.js library, while the audio signal will be decoded with theggwave library. Subtracting the decoded value from the UNIX timestamp at receiver side we will obtain the total end to end delay that occurs from the audio/video frame capture time to the display time (please note that the sender and receiver machine clocks need to be synchronized, otherwise we will introduce an error in the delay estimation).
Example usage:

webrtcperf \ --sessions=2 \ --run-duration=300 \ --url=https://meet.google.com/<ID> \ --debugging-port=9000 \ --prometheus-pushgateway=http://localhost:9091 \ --script-path=https://raw.githubusercontent.com/vpalmisano/webrtcperf/refs/heads/devel/examples/google-meet.js \ --script-params='{timestampWatermarkAudio:true,timestampWatermarkVideo:true}'

Measuring the network end-to-end delay using the abs-capture-time extension

The webrtcperf-js library comes with another mechanism that can be used to estimate the network end-to-end delay. Setting theabsCaptureTimescript param, the library will modify the SDP offer inserting the theabs-capture-timeheader extension (https://datatracker.ietf.org/doc/draft-ietf-avtcore-abs-capture-time/) for audio and video media sections. If the SFU supports this extension header, the receiver side will receive thecaptureTimestampvalue into the corresponding contributing source. Consider also that some video conferencing applications (e.g. Google Meet) already uses this header, so you don’t need to add any script param to get the measurement.
The code used to calculate the delay is the following:

const contributingSource = receiver.getSynchronizationSources()[0] const captureTimestamp = contributingSource?.captureTimestamp const senderCaptureTimeOffset = contributingSource?.senderCaptureTimeOffset if (contributingSource && captureTimestamp && senderCaptureTimeOffset !== undefined) { endToEndDelay = (contributingSource.timestamp - (captureTimestamp + senderCaptureTimeOffset - 2208988800000)) / 1000 }

As we can see, the delay is calculated as the time difference from the current timestamp and the capture timestamp, using the time offset to compensate the clock difference between the sender and the receiver machines; both the capture and the offset are NTP time based (midnight UTC on January 1, 1900), so we need to rebase them to the UNIX start time (midnight UTC on January 1, 1970).
The End-to-End delay calculated with the abs-capture-time extension in a Google Meet test (audioEndToEndDelayandvideoEndToEndDelaymetrics):

The advantage of using this option is that it does not require any audio or video watermarking, and it will save some CPU at the receiver side required to run the image recognition. Anyway, this method takes into account only the RTP one-way delay on the network path; if you want to get a more accurate delay you should add the encoding (videoEncodeLatency) and the decoding (videoDecodeLatency) metrics values to thevideoEndToEndDelayvalue.

Setting theactionsscript params value allows us to run several page tasks at different times, starting from the webrtcperf launch time. Each action object could include the following properties:

- name(string): the javascript method to call (it must be a globally exported method).
- params(array): the method arguments.
- index(string): the webrtcperf session indexes where the action must run.
- at(number): the number of seconds from the test start when the action should run. If the page load took more time than “at” seconds, the action run is skipped.
- relaxedAt(number): use this in place of the “at” property if you want to run the action even if the scheduled time is greater than the elapsed time.
- every(number): if set, the action will run at regular intervals.
- times(number): the number of times the action should run.

Example: assuming you have defined amuteParticipantcustom function to mute/unmute the microphone, use this script actions to mute “Participant-000000” after 60 seconds and unmute it after 180 seconds form the test launch time:

webrtcperf \ --sessions=2 \ --run-duration=300 \ --url=https://meet.google.com/<ID> \ --debugging-port=9000 \ --prometheus-pushgateway=http://localhost:9091 \ --script-path=https://raw.githubusercontent.com/vpalmisano/webrtcperf/refs/heads/devel/examples/google-meet.js \ --script-params='{ actions: [ { name: "muteParticipant", params: [true], index: "0", at: 60 }, { name: "muteParticipant", params: [false], index: "0", at: 180 }, ] }'
No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.