webrtcperf

WebRtcPerf es una herramienta de código abierto diseñada para probar servicios WebRTC con múltiples conexiones de clientes concurrentes, midiendo las estadísticas RTC más importantes y recogiéndolas de manera sencilla.

Documentación

logo

WebRtcPerf

Página de GitHub | Documentación

Build Docker image

Add to Cursor Add to VS Code

WebRtcPerf es una herramienta de código abierto diseñada para probar servicios WebRTC con múltiples conexiones de clientes concurrentes, midiendo las estadísticas RTC más importantes y recopilándolas de forma sencilla. Esta documentación profundizará en sus múltiples funciones y opciones de configuración, mostrándote cómo aprovechar esta herramienta para obtener información valiosa sobre tus soluciones de comunicación en tiempo real.

Requisitos previos e instalación

La herramienta webrtcperf es una aplicación NodeJS que lanza múltiples navegadores headless de Puppeteer que realmente iniciarán las conexiones WebRTC, por lo que idealmente podría ejecutarse en cualquier plataforma donde NodeJS y el navegador Chromium puedan funcionar. De todos modos, para aprovechar algunas funciones específicas, se recomienda usar un sistema operativo Linux. Si planeas ejecutar múltiples conexiones concurrentes a un host externo que ejecuta el servicio WebRTC, debes asegurarte de que tu máquina tenga suficiente ancho de banda de red para enviar y recibir los flujos de audio/video sin afectar la calidad, y una cantidad de CPU y memoria proporcional al número de clientes que deseas iniciar. De todos modos, también puedes usar una máquina limitada con ese propósito, para evaluar cómo el servidor WebRTC y el cliente reaccionan al entorno restringido. Considera también que la herramienta utiliza el framework Traffic Controller (TC) en Linux para aplicar restricciones de red y cambiarlas mientras se ejecutan las pruebas.

El comando para instalar la herramienta:

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

Asegúrate de tener FFMpeg instalado en la misma máquina.

Alternativamente, usa la imagen Docker preconstruida:

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

La herramienta también se puede usar desde el código fuente:

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

Uso desde la línea de comandos

Los argumentos de la línea de comandos se pueden proporcionar explícitamente usando el formato lower snake case (p. ej. --run-duration= o configurando la variable de entorno correspondiente en formato upper snake case (RUN_DURATION=). Los parámetros de la línea de comandos tienen prioridad sobre las variables de entorno correspondientes. Alternativamente, es posible cargar las variables de configuración guardadas en lower camel case en un archivo local JSON/JSON5, YAML o TOML; el archivo también se puede almacenar de forma remota y cargarse usando su URL HTTP pública.
Ejemplo de ejecución de un escenario simple con demo de Mediasoup:

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

image1

Detén la herramienta presionando q (cierre normal del navegador) o x (cerrará el proceso inmediatamente).

Usar la herramienta para ejecutar pruebas simples

Comencemos ejecutando algunos escenarios de prueba simples con solo 2 participantes. Los argumentos de la línea de comandos necesarios para unirse a una sala pública de Google Meet son:

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

En particular, los argumentos obligatorios son:

  • --sessions: el número total de sesiones de navegador chromium que queremos iniciar.
  • --run-duration: la duración de la ejecución de la prueba en segundos.
  • --url: la URL remota que queremos visitar.

Otros argumentos necesarios para unirse a una sala de Google Meet:

  • --debugging-port: se establece en un valor diferente de cero para deshabilitar la función webdriver (https://issues.chromium.org/issues/40746300).
  • --script-path: inyecta un código javascript en la página en ejecución. Acepta una lista separada por comas de rutas de archivos locales o URLs http. En este caso, el código completa automáticamente el nombre de usuario y se une a la sala.

Por defecto, la herramienta generará periódicamente algunas métricas obtenidas de los objetos RTC PeerConnection en ejecución. Las métricas se agregan en todas las sesiones en ejecución, mostrando la suma (cuando tiene sentido), la media, la desviación estándar, los percentiles 5 y 95, los valores mínimos y máximos.

-- 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

Las métricas anteriores representan:

  • CPU/GPU/Memoria del sistema: el % de CPU, GPU y memoria RSS del sistema utilizados (que van de 0 a 100%).
  • CPU/página: la cantidad de % de CPU utilizada por cada proceso de chromium, incluidos todos los procesos hijos (que van de 0 a N00% según el número de núcleos de CPU disponibles).
  • Memoria/página: la memoria RSS utilizada por cada proceso de chromium, incluidos todos los procesos hijos.
  • Páginas: el número de páginas abiertas (debe coincidir con el valor --sessions proporcionado).
  • Errores, Advertencias: el número acumulado de errores y registros de advertencia recopilados por cada página.
  • Conexiones de pares: el número de objetos RTC Peer Connection conectados que se ejecutan en cada página.
  • rate: la tasa de bits de entrada/salida.
  • lost: el % de paquetes perdidos.
  • roundTripTime: el valor del tiempo de ida y vuelta.
  • qualityLimitResolutionChanges: el recuento de eventos de limitación de calidad.
  • qualityLimitationCpu, qualityLimitationBandwidth: el % de tiempo que el emisor ha funcionado con una limitación de calidad.
  • width, height, fps: la resolución y la velocidad de fotogramas de envío actuales.
  • firCountReceived, pliCountReceived: cuentan el número de FIR/PLI (fotogramas clave) solicitados a ese emisor.

Veamos qué sucede cuando comenzamos a aumentar el número de sesiones, introduciendo más participantes en la misma sala (--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

Como podemos ver en la salida del comando, ahora tenemos count=2 para todas las métricas y comenzamos a notar algunas diferencias entre los valores de suma, promedio, mínimo, máximo y percentiles.

Envío de estadísticas a Prometheus

Recopilar y analizar las métricas usando la salida de la consola de comandos podría ser una tarea difícil, especialmente cuando aumentamos el número de sesiones. Con este propósito, webrtcperf permite enviar los valores de las métricas a un servicio externo Prometheus/Grafana, a través de un servicio Pushgateway. Una configuración de ejemplo de docker compose para ejecutar todos los servicios necesarios está disponible en https://github.com/vpalmisano/webrtcperf/tree/devel/prometheus-stack.
Suponiendo que el servicio Pushgateway se está ejecutando en localhost:9091, el parámetro adicional que se debe incluir en la línea de comandos es: --prometheus-pushgateway=http://localhost:9091
Si el servidor Pushgateway está protegido con credenciales de nombre de usuario y contraseña, simplemente agrega el parámetro --prometheus-pushgateway-auth=username:password.
Además, podemos cambiar la etiqueta job=default de Prometheus usando el parámetro --prometheus-pushgateway-job-name=custom-tag; de esta manera, podemos diferenciar fácilmente las métricas provenientes de diferentes ejecuciones de prueba o concurrentes.

Al visitar el servicio Grafana iniciado con el docker compose anterior, es posible acceder al panel de ejemplo, que muestra una serie de métricas recopiladas por webrtcperf:
image2

Uso avanzado

Opciones de URL

En los ejemplos anteriores usamos la opción --url para establecer una URL de destino de página que usan todas las sesiones en ejecución. La herramienta tiene otras dos opciones para personalizar la URL de destino:

  • --url-query: permite especificar una cadena de consulta de URL adicional que se adjuntará al --url proporcionado. La cadena puede incluir algunas variables de plantilla que se reemplazarán en tiempo de ejecución:

    • $p el pid del proceso
    • $s el índice de la sesión
    • $S el total de sesiones
    • $t el índice de la pestaña
    • $T el total de pestañas por sesión
    • $i el índice absoluto de la pestaña

    Ejemplo: --url-query=”participantName=Test-$i” adjuntará ?participantName=Test-0, ?participantName=Test-1 a la URL de la sesión correspondiente.

  • --custom-url-handler: esta opción acepta una ruta de módulo javascript que contiene una única función exportada que se invocará para cada sesión iniciada. Usa esta opción sin configurar la opción --url.
    La función se invocará con un único objeto con las siguientes propiedades:

    • sessions: el número total de sesiones;

    • tabsPerSession: el número total de pestañas por sesión;

    • id: el índice global de la sesión (basado en 0);

    • index: el índice global de la pestaña (basado en 0);

    • tabIndex: el índice de la pestaña en la sesión actual (basado en 0);

    • pid: el pid del proceso;

    • env: el objeto de variables de entorno;

    • params: el objeto de parámetros del script.

      Script de ejemplo:

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

Las opciones de entrada de getUserMedia

La herramienta aprovecha varias opciones que ofrece chromium para especificar un archivo de entrada de audio/video que se usará como fuente de getUserMedia. El uso de audio y video falsos nos permite ejecutar pruebas consistentes y repetibles, sin introducir la aleatoriedad implícita que causaría ejecutar pruebas con entradas locales de cámara web/micrófono.
La herramienta permite configurar las siguientes opciones:

  • --video-path: una ruta de archivo utilizada como fuente para los flujos de audio y video. Se usará FFMpeg para convertir este archivo a un formato aceptado por las opciones de chromium, por lo que cualquier formato de entrada aceptado por ffmpeg es un valor válido (p. ej. https://…). Además, usar generate:null generará un video negro y una pista de audio silenciosa; con generate:test generará un patrón de video testsrc de ffmpeg y un audio de frecuencia única con patrón de pitido. La opción está configurada por defecto a este video de prueba https://github.com/vpalmisano/webrtcperf/releases/download/videos-1.0/kt.mp4. Hay más videos de prueba disponibles bajo esta etiqueta de versión: https://github.com/vpalmisano/webrtcperf/releases/tag/videos-1.0.
  • --video-width, --video-height, --video-framerate: la resolución y la velocidad de fotogramas de video que se usarán para ampliar o reducir el video de entrada.
  • --video-seek: el tiempo de búsqueda en segundos desde el inicio en el video proporcionado.
  • --video-duration: la duración total utilizada para recortar el video de entrada.
  • --video-cache-raw: cuando es true (valor predeterminado), los archivos generados se almacenarán en caché en el directorio ~/.webrtcperf/cache.
  • --video-format: el formato de video utilizado para la conversión de la pista de video; puede ser "y4m" (video yuv sin procesar, el valor predeterminado) o "mjpeg".
  • --use-fake-media:
    • cuando es true (predeterminado), el archivo proporcionado especificado con videoPath se convertirá en archivos de audio y video sin procesar que se pasarán al ejecutable de chromium usando los parámetros use-fake-ui-for-media-stream, use-file-for-fake-video-capture y use-file-for-fake-audio-capture. Las llamadas a getUserMedia generarán pistas a partir de los archivos sin procesar proporcionados.
    • Cuando es false, el navegador se ejecutará sin ninguna opción de medios falsos, pero el script de página predeterminado de webrtcperf anulará la llamada a getUserMedia cargando un elemento de video oculto dentro de la página y usándolo como fuente para las pistas generadas. La ventaja de usar este enfoque es que las pistas de audio y video se ejecutarán sincronizadas, por lo que se puede usar para detectar desincronización de audio/video; la desventaja es el mayor uso de memoria y CPU de la página causado por la decodificación de los medios falsos.

Las opciones de entrada de getDisplayMedia

El comportamiento predeterminado de chromium para simular la pista de medios de pantalla permite obtener una animación de video generada que generalmente es muy diferente de lo que tenemos en una videoconferencia regular cuando los usuarios comparten una presentación estática con transiciones de diapositivas. De hecho, la animación generada por chromium produce un flujo de tasa de bits constante, mientras que una presentación real genera una tasa de bits baja en promedio con grandes picos causados por las transiciones de diapositivas. Emular este comportamiento es esencial para evaluar la calidad de video de la pantalla compartida en un servicio de videoconferencia.
En webrtcperf, las llamadas a getDisplayMedia generarán una pista de video que se obtiene al compartir la ventana actual del navegador (cuando --use-fake-media=true) o una nueva pestaña del navegador (--use-fake-media=false). En ambos casos, la herramienta usará una automatización de script de página que genera una secuencia falsa de pantalla compartida que se puede personalizar agregando una opción fakeScreenshare en la opción de línea de comandos --script-params. La opción fakeScreenshare acepta los siguientes parámetros:

  • animationDuration: la duración de la animación de la diapositiva expresada en milisegundos (predeterminado: 1000).
  • delay: el retraso de cambio de diapositiva en milisegundos (predeterminado: 5000).
  • embed: una URL opcional que especifica un documento o una presentación externa de Google Drive que se cargará dentro de un elemento iframe.
  • width, height: la resolución de compartir pantalla (predeterminado: 1920x1080)
  • pointerAnimation: si es diferente de cero, dibujará una animación aleatoria que emula el movimiento del ratón.
  • slides: el total de diapositivas a generar (predeterminado: 4).
  • urls: un array opcional de cadenas que podría incluir (incluso en orden mixto):
    • una URL de imagen o video que se utilizará como contenido de la diapositiva;

    • un documento que se incrustará en un elemento iframe y se utilizará como contenido de la diapositiva.

      Cuando no se proporcionan ni slides ni embed, la herramienta cargará las imágenes desde https://picsum.photos.

Limitación de red (Network throttling)

El ancho de banda disponible de Internet, la latencia de red y la pérdida de paquetes son factores que normalmente pueden afectar la calidad percibida de un servicio de videoconferencia. Replicar las condiciones de red que afectan a los usuarios reales suele ser una buena forma de evaluar si el servicio WebRTC es capaz de adaptarse al ancho de banda disponible (aumentando o disminuyendo la resolución de video y la velocidad de fotogramas) y manejar la pérdida de paquetes y el retraso.
La herramienta webrtcperf incluye una funcionalidad de limitación de red ofrecida por el proyecto https://github.com/vpalmisano/throttler, que es esencialmente un envoltorio NodeJS del framework Linux Traffic Controller (https://tldp.org/HOWTO/Traffic-Control-HOWTO/intro.html) y NetEm. El parámetro --throttle-config acepta una cadena codificada en JSON/JSON5 que contiene un array de configuración del throttler; cada elemento de configuración es un objeto que contiene las siguientes propiedades:

  • sessions (string): Los IDs de sesiones de webrtcperf que usarán esta configuración de limitación. Podría ser un índice único ("0"), un rango ("0-2") o una lista separada por comas ("0,3,4").
  • up, down (string, JSON): Una sola o un array de reglas de limitación que se aplicarán al enlace ascendente y al enlace descendente.
  • protocol ("udp" | "tcp"): Si se especifica, solo se limitarán los paquetes TCP o UDP.
  • device (string): La interfaz de red a limitar. Si no se especifica, se utilizará la interfaz predeterminada.
  • filter (string): Una regla adicional de filtro de paquetes IPTables.
  • match (string): Una expresión de coincidencia TC adicional utilizada para filtrar paquetes.
  • skipSourcePorts, skipDestinationPorts (string): Una lista separada por comas de puertos de origen y destino que no se limitarán. Ejemplo de uso: en algunos casos es mejor evitar limitar los puertos 80,443, de lo contrario la aplicación web no podrá cargarse.
  • capture (string): Si se establece, los paquetes que coincidan con la sesión y el protocolo proporcionados se capturarán en esa ubicación de archivo en formato PCAP.

Cada regla de limitación podría incluir las siguientes propiedades que controlan el valor correspondiente en la herramienta NetEm:

  • rate: El ancho de banda disponible (Kbps).
  • delay: El retraso de un solo sentido (ms).
  • delayJitter: La fluctuación del retraso de un solo sentido (ms).
  • delayJitterCorrelation: La correlación de la fluctuación del retraso de un solo sentido.
  • delayDistribution: La distribución del retraso ('uniform' | 'normal' | 'pareto' | 'paretonormal').
  • reorder: El porcentaje de reordenación de paquetes.
  • reorderCorrelation: La correlación de reordenación de paquetes.
  • reorderGap: La brecha de reordenación de paquetes.
  • loss: El porcentaje de pérdida de paquetes.
  • lossBurst: La ráfaga de pérdida de paquetes.
  • queue: El tamaño de la cola de paquetes.
  • at: Si se establece, la regla se aplicará después del número de segundos especificado.

Ejemplos
Ejecute una videoconferencia de dos participantes en Google Meet, limitando el enlace ascendente del primer participante a 500Kbps, 100ms de retraso y 2% de pérdida de paquetes:

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}]}]'

La transmisión de video "Participant-000000" tiene una calidad visiblemente menor en comparación con "Participant-000001":
image3

Comparando la misma ejecución de prueba sin y con la opción de limitación de red, podemos ver cómo la tasa de bits enviada disminuyó de un promedio de ~600Kbps a ~300Kbps; la pérdida de paquetes aumentó hasta 1-2% y el tiempo de ida y vuelta aumentó de ~40ms a ~150ms:
image4

Ejecutemos otra prueba con una configuración de limitación diferente. En este caso especificamos múltiples reglas para la limitación del enlace ascendente, usando un valor at diferente para cada una; en particular, lo que queremos probar es:

  • comenzar aplicando una limitación de tasa de bits de 1Mbps;
  • después de 60 segundos, cambiar la limitación de tasa de bits a 500Kbps;
  • después de 60 segundos, establecer la tasa de bits nuevamente a 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 },
      ] 
    }]'

Observando las métricas medidas, vemos el efecto del cambio de limitación de ancho de banda:

  • la tasa de bits de video disminuyó de 600Kbps a 300Kbps de t=60 a t=120;
  • obtuvimos algo de pérdida de paquetes después de la disminución del ancho de banda;
  • el indicador de limitación de calidad de ancho de banda aumentó a ~80% en el mismo intervalo de tiempo.

image5

Emulación de orador aleatorio

Usar un archivo multimedia falso con habla continua cuando ejecutamos pruebas con múltiples participantes no se acerca a lo que sucede en una sala de videoconferencia real, donde los participantes suelen hablar por turnos sin superponerse. La automatización de página de webrtcperf permite activar/desactivar automáticamente las pistas de audio capturadas con getUserMedia cambiando la propiedad track.enabled; el mecanismo se puede controlar con las siguientes opciones de línea de comandos:

  • --random-audio-period: Especifica el período máximo en segundos después del cual se selecciona una nueva sesión activa aleatoria, habilitando las pistas de audio getUserMedia en esa sesión y deshabilitando todas las demás.
  • --random-audio-probability: define el % de probabilidad de que el audio seleccionado se active (predeterminado: 100%). Establecer este valor a un valor menor que 100 tendrá el efecto de desactivar el audio para todas las sesiones.
  • --random-audio-range: Define los índices de sesión que deben incluirse en el mecanismo de selección aleatoria (predeterminado: incluir todas las sesiones).

Además de la propiedad track.enabled, la herramienta invocará la función publisherSetMuted(true | false), si esa función se ha implementado en un script de página personalizado (cargado con --script-path); de esta manera es posible activar el estado silenciado haciendo clic en el botón correspondiente de silenciar/activar sonido dentro de la página, dependiendo del servicio particular que estemos probando.

Usar la compilación personalizada de Chromium para ahorrar CPU

Ejecutar pruebas con muchos participantes aumenta la cantidad de CPU necesaria para renderizar la página, codificar las transmisiones de audio/video y decodificarlas en el lado del receptor. La imagen docker de webrtcperf incluye una versión modificada de Chromium que permite a la herramienta especificar un número máximo de transmisiones de video RTC para decodificar en paralelo para cada sesión de navegador. El valor se puede controlar usando las siguientes opciones de línea de comandos:

  • --max-video-decoders: El número máximo de transmisiones de video RTC que serán decodificadas por cada sesión de navegador (predeterminado: 0, decodificar todos los videos).
  • --max-video-decoders-range: Aplica la opción de máximo de decodificadores de video a las sesiones incluidas en esta lista (predeterminado: "true" que incluirá todas las sesiones).

Vale la pena notar que deshabilitar la decodificación de transmisiones de video haría que algunas métricas RTC (por ejemplo, el ancho, alto y velocidad de fotogramas recibidos) siempre reporten un valor de cero. La forma sugerida de usar esta característica es mantener el decodificador de video habilitado para un porcentaje de sesiones, dependiendo de la cantidad de CPU que queramos ahorrar.
La versión modificada de Chromium se puede compilar desde el código fuente usando los siguientes comandos:

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

Una vez que el paquete de Chromium personalizado se ha instalado, especifique la ruta del ejecutable con la opción --chromium-path (o estableciendo la variable de entorno CHROMIUM_PATH):

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

Opciones de registro adicionales

La herramienta ofrece varias opciones de registro para guardar los registros de las páginas abiertas y, opcionalmente, la salida completa del proceso de Chromium.

  • --show-page-log: Si es true (predeterminado), los registros de consola de las páginas se mostrarán en la consola.
  • --page-log-filter: Si se establece, solo los registros con el texto o expresión regular coincidente se imprimirán en la consola.
  • --page-log-path: Si se establece, los registros de consola de la página se guardarán en la ruta de archivo seleccionada.
  • --enable-browser-logging: Habilita el registro del navegador Chromium para los índices de sesión especificados. Requiere que la opción --page-log-path esté establecida. Cuando está habilitado, la herramienta activará el registro verboso de Chromium (con --vmodule=*/webrtc/*=5) que se escribirá en el directorio de ruta de registro de la página. También activa la opción --webrtc-event-logging de Chromium, que guardará el archivo de registro de eventos en el mismo directorio (puede usar https://github.com/fippo/dump-webrtc-event-log para analizar este archivo).

La automatización de scripts

En los ejemplos anteriores usamos la opción --script-path proporcionando una página javascript que ejecuta algo de automatización de página (como completar automáticamente el nombre del participante y hacer clic en el botón de unirse). Por defecto, la herramienta webrtcperf cargará el paquete de scripts webrtcperf-js, que proporciona una serie de utilidades para automatizar las tareas de prueba y ejecutar mediciones avanzadas en el contexto de la página. El script personalizado proporcionado con la opción --script-path puede acceder a las utilidades de webrtcperf-js bajo el objeto global webrtcperf. Algunas de las características ofrecidas por webrtcperf-js necesitan configurarse en el momento de la carga de la página; con este propósito, webrtcperf ofrece la opción --script-params que se puede usar para proporcionar un objeto JSON/JSON5 con los valores que se establecerán en el objeto webrtcperf.params.

Medición del retraso de extremo a extremo (boca-oído)

Establecer los parámetros de script timestampWatermarkAudio y timestampWatermarkVideo habilitará una característica de webrtcperf-js que aplica automáticamente una superposición de marca de agua de video y una señal de audio modulada que contiene la marca de tiempo UNIX del remitente. En el lado del receptor, la superposición de video se reconocerá usando la biblioteca Tesseract.js, mientras que la señal de audio se decodificará con la biblioteca ggwave. Restando el valor decodificado de la marca de tiempo UNIX en el lado del receptor obtendremos el retraso total de extremo a extremo que ocurre desde el tiempo de captura del cuadro de audio/video hasta el tiempo de visualización (tenga en cuenta que los relojes de las máquinas del remitente y del receptor deben estar sincronizados, de lo contrario introduciremos un error en la estimación del retraso).
Ejemplo de uso:

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}'

Medición del retraso de extremo a extremo de la red usando la extensión abs-capture-time

La biblioteca webrtcperf-js viene con otro mecanismo que se puede usar para estimar el retraso de extremo a extremo de la red. Al establecer el parámetro de script absCaptureTime, la biblioteca modificará la oferta SDP insertando la extensión de encabezado abs-capture-time (https://datatracker.ietf.org/doc/draft-ietf-avtcore-abs-capture-time/) para las secciones de medios de audio y video. Si el SFU admite esta extensión de encabezado, el lado del receptor recibirá el valor captureTimestamp en la fuente contribuyente correspondiente. Considere también que algunas aplicaciones de videoconferencia (por ejemplo, Google Meet) ya usan este encabezado, por lo que no necesita agregar ningún parámetro de script para obtener la medición.
El código utilizado para calcular el retraso es el siguiente:

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
}

Como podemos ver, el retraso se calcula como la diferencia de tiempo entre la marca de tiempo actual y la marca de tiempo de captura, usando el desplazamiento de tiempo para compensar la diferencia de reloj entre las máquinas del remitente y del receptor; tanto la captura como el desplazamiento se basan en tiempo NTP (medianoche UTC del 1 de enero de 1900), por lo que necesitamos reajustarlos al tiempo de inicio UNIX (medianoche UTC del 1 de enero de 1970).
El retraso de extremo a extremo calculado con la extensión abs-capture-time en una prueba de Google Meet (métricas audioEndToEndDelay y videoEndToEndDelay):
image6 La ventaja de usar esta opción es que no requiere ninguna marca de agua de audio o vídeo, y ahorrará algo de CPU en el lado del receptor necesaria para ejecutar el reconocimiento de imágenes. De todos modos, este método solo tiene en cuenta el retardo unidireccional RTP en la ruta de red; si desea obtener un retardo más preciso, debe agregar los valores de las métricas de codificación (videoEncodeLatency) y decodificación (videoDecodeLatency) al valor de videoEndToEndDelay.

Ejecutar automatizaciones de página

Establecer el valor de los parámetros de script actions nos permite ejecutar varias tareas de página en diferentes momentos, a partir del momento de lanzamiento de webrtcperf. Cada objeto de acción podría incluir las siguientes propiedades:

  • name (cadena): el método de JavaScript a llamar (debe ser un método exportado globalmente).
  • params (array): los argumentos del método.
  • index (cadena): los índices de sesión de webrtcperf donde debe ejecutarse la acción.
  • at (número): el número de segundos desde el inicio de la prueba cuando debe ejecutarse la acción. Si la carga de la página tardó más tiempo que los segundos de "at", la ejecución de la acción se omite.
  • relaxedAt (número): use esto en lugar de la propiedad "at" si desea ejecutar la acción incluso si el tiempo programado es mayor que el tiempo transcurrido.
  • every (número): si se establece, la acción se ejecutará a intervalos regulares.
  • times (número): el número de veces que debe ejecutarse la acción.

Ejemplo: suponiendo que haya definido una función personalizada muteParticipant para silenciar/activar el micrófono, use estas acciones de script para silenciar a "Participant-000000" después de 60 segundos y activar su micrófono después de 180 segundos desde el momento de lanzamiento de la prueba:

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 },
      ]
    }'

El bitrate de audio enviado por Participant-000000 muestra un período vacío durante el período de silencio:
image7

Los bitrates de audio recibidos por Participant-000001 reflejan el período de audio en pausa:
image8

Modificadores de respuesta de página

Usando la opción --response-modifiers es posible realizar un reemplazo de cadenas en una o más solicitudes HTTP realizadas por la página (incluyendo XHR, recursos, etc.). Acepta un objeto JSON con el patrón de URL de la solicitud y una lista de uno o más reemplazos deseados.
Ejemplos:

  • Realizar un reemplazo de cadenas en cada solicitud *.js realizada a la URL seleccionada:
    { "https://url.com/*.js": [{ search: "searchString": replace: "anotherString" }] }
  • Reemplazar completamente la salida de la solicitud con un archivo local:
    { "https://url.com/file.js": [{ file: "path/to/newFile.js" }] }

Otra opción útil para depurar las solicitudes de la página es --download-reponses. Acepta un array de patrones de URL que queremos guardar como archivos locales. Por ejemplo, guardar la descarga de fragmentos mpegts HLS mientras se ve una transmisión en vivo requerirá algo como esto:
[{ urlPattern: "https://url.com/*.ts", output: "save/directory" }]

Cabeceras personalizadas, CSS, cookies

  • --extra-headers: Especifique esta opción para agregar cabeceras HTTP personalizadas a cada solicitud. Ejemplo:
    { "https://url.com/*": { "Authorization": "Bearer secret" } }
    Adjuntará una cabecera "Authorization" para cada solicitud realizada al patrón de URL especificado.
  • --extra-css: Una cadena que contiene las reglas CSS que se inyectarán dentro del contenido de la página.
  • --cookies: Un array de objetos JSON CookieParam (https://pptr.dev/api/puppeteer.cookieparam) que se establecerán en la página web en ejecución.

Opciones de depuración

La herramienta acepta las siguientes opciones que nos permiten acceder a las páginas abiertas de Chromium con el inspector de devtools (chrome://inspect/#devices). De esta manera podemos acceder al contexto de la página mientras se ejecuta la prueba para depurar la aplicación web.
Las opciones que permiten configurar el depurador son:

  • --debugging-port: Si no es cero, habilitará el depurador de Chromium escuchando en el puerto seleccionado.
  • --debugging-address: El navegador Chromium solo permite escuchar en la dirección 127.0.0.1, por lo que no es posible alcanzar una sesión que se ejecuta dentro de un contenedor docker o en una máquina remota. Cuando esta opción está configurada, webrtcperf iniciará un reenviador de puertos que le permitirá conectarse al protocolo devtool incluso si la página se ejecuta de forma remota.

Otras opciones diversas que simplifican la depuración de la página son:

  • --emulate-cpu-throttling: Cuando es diferente de cero, usará la función de limitación de CPU de devtools para limitar la ejecución de JavaScript de la página, emulando un dispositivo lento.
  • --hardware-concurrency: Sobrescribe la propiedad navigator.hardwareConcurrency. Algunos proveedores de conferencias web usan esta opción para inferir las capacidades de la máquina y reducir la resolución de video y la tasa de fotogramas según el número de núcleos de CPU detectado.
  • --device-scale-factor: El factor de escala de dispositivo del navegador a usar (predeterminado: 1).
  • --user-agent: Una cadena de user agent personalizada para usar.
  • --chromium-field-trials: Una cadena válida de anulación de field trials de Chromium.
  • --local-storage y --session-storage: Un objeto JSON que se establecerá en localStorage y sessionStorage de la página en la carga de la página.
  • --override-permissions: Una lista separada por comas de permisos para otorgar a la página. Los valores posibles se enumeran aquí: https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Permissions-Policy#directives.
  • --debug: Permite aumentar la verbosidad de los mensajes de registro de la herramienta. Consulte https://github.com/commenthol/debug-level#readme para la sintaxis.

Reglas de alerta

Después de ejecutar las pruebas, normalmente necesitamos revisar las métricas recopiladas en la interfaz de Grafana o directamente desde los registros de salida e inspeccionarlas observando los valores de pérdida de paquetes, bajo ancho de banda o resoluciones, etc.
Webrtcperf incluye una funcionalidad que intenta automatizar la inspección de métricas y la detección de fallos ejecutando un paso de verificación de valores cada vez que se recopilan las métricas. Las verificaciones de valores se pueden especificar proporcionando una cadena JSON válida a la opción --alert-rules que contenga un único objeto con las métricas que queremos verificar con la definición de regla de alerta correspondiente.

Ejemplo 1: queremos verificar si la suma de las conexiones peer activas es igual a 100 después de 1 minuto desde el inicio de la prueba.

--alert-rules='{
  pages: {
    tags: ["connectivity"],
    sum: { "$eq": 100, "$after": 60 },
  },
}'

Ejemplo 2: queremos verificar si, después de 2 minutos, el número de videos recibidos es igual a 25 y si el percentil 5 de los bitrates recibidos está incluido en el rango de 2-3 Mbps.

--alert-rules='{
  videoRecvBitrates: {
    tags: ["quality"],
    length: { "$eq": 25, "$after": 120 },
    p5: { "$gt": 2000000, "$lt": 3000000, "$after": 120 },
  },
}'

La lista completa de las métricas recopiladas por webrtcperf está disponible aquí. Las reglas de métricas podrían incluir estos especificadores:

  • length: el número de métricas realmente recopiladas (por ejemplo, el número de flujos de video);
  • sum: la suma de los valores de las métricas;
  • min, max, mean, p5, p95: valores mínimo, máximo, percentil 5 y percentil 95.

Las verificaciones de valores podrían incluir:

  • $eq: el valor de la métrica debe ser igual al valor especificado;
  • $gt, $gte: el valor de la métrica debe ser mayor / mayor o igual al valor;
  • $lt, $lte: menor / menor o igual;
  • $after: la herramienta comenzará a evaluar la regla después del valor proporcionado en segundos;
  • $before: la herramienta dejará de evaluar la regla después del valor proporcionado en segundos.

La regla opcional "tag" se puede usar para agrupar la regla de prueba en una categoría personalizada. Si se especifica --alert-rules-output, al final de la prueba la herramienta escribirá un archivo JSON con los resultados de la prueba agrupados por etiqueta de categoría, informando el porcentaje de tiempo en que las métricas verificadas en cada categoría no coincidieron con las reglas correspondientes. Puede usar esta salida para activar una alerta automatizada en un sistema de monitoreo cada vez que los resultados de la prueba sean diferentes de los valores esperados. Además, para cada verificación de regla de alerta, la herramienta agregará una métrica de Prometheus _alert que se puede usar para visualizar el umbral de alerta en Grafana e informar si la verificación de métrica está fallando o no.

Ejemplo 3: ejecutar una prueba con 2 participantes que visitan una página de demostración de Mediasoup; el primer participante se ejecutará con red de bajada limitada (1Mbps, 100ms de retardo) y queremos verificar si el bitrate de video recibido cae en el intervalo 400Kbps - 1Mbps:

Configuración del escenario mediasoup_r1000-d100.yaml:

sessions: 2
runDuration: 300
url: 'https://v3demo.mediasoup.org/?roomId=webrtcperf-test-12345&displayName=Participant-$i'
debuggingPort: 9000
prometheusPushgateway: 'http://localhost:9091'
showPageLog: false
showStats: false
statsInterval: 5
throttleConfig: |
    [{
        sessions: "0",
        protocol: "udp",
        down: [
            { rate: 1000, delay: 100, queue: 50 },
        ]
    }]
alertRules: |
    {
        peerConnections: {
            tags: ["connectivity"],
            sum: { "$eq": 4, "$after": 30 },
        },
        videoRecvBitrates: {
            tags: ["quality"],
            length: { "$eq": 2, "$after": 30 },
            p5: { "$gt": 400000, "$lt": 1000000, "$after": 30 },
        },
    }
alertRulesOutput: 'results.json'

Comando de prueba:

webrtcperf mediasoup_r1000-d100.yaml

Podemos ver la métrica de Grafana y el estado correspondiente de la regla de alerta; en este caso el percentil 5 no coincide con los valores esperados, por lo que tenemos algunos fallos de verificación de alerta.
image9

El contenido de results.json y el final de la prueba informan un porcentaje de fallo de prueba del 48%, con los detalles sobre cuántas veces y la duración total en que la verificación falló:

{
  "tags": {
    "connectivity": 0,
    "quality": 48
  },
  "reports": {
    "videoRecvBitrates p5 > 400000 and < 1000000 after 30s": {
      "totalFails": 18,
      "totalFailsTime": 50,
      "valueAverage": 419731.18521030556,
      "totalFailsTimePerc": 19,
      "failAmount": 48,
      "count": 54
    }
  }
}

Si cambiamos la regla de alerta videoRecvBitrates usando "$gt": 100000, las verificaciones de la prueba son exitosas en su lugar:
image10

Evaluación de calidad VMAF

Evaluar la calidad del video en la mayoría de los casos requiere una inspección visual de los flujos de salida buscando artefactos, efectos de desbloqueo, etc. Ejecutar esta comparación de forma automatizada es preferible y permite que la infraestructura de prueba informe inmediatamente una alerta cuando la calidad detectada no coincide con el valor esperado mientras se ejecuta el mismo escenario de prueba en las mismas condiciones.
VMAF (Video Multimethod Assessment Fusion) es un algoritmo de evaluación perceptual de calidad de video desarrollado por Netflix (https://github.com/Netflix/vmaf). Es una métrica de referencia completa, lo que significa que requiere tanto un video de referencia (original) como uno distorsionado (codificado) para la evaluación. VMAF tiene como objetivo predecir la calidad del video combinando varias métricas en un único valor de puntuación (que va de 0 a 100). VMAF ha sido diseñado para evaluar la calidad de codificación de video asumiendo que la versión distorsionada del video contiene exactamente los mismos fotogramas de video que el video de entrada. Esto no es cierto en el contexto de WebRTC, donde el video recibido podría verse afectado por el retardo (retardo de red implícito, búfer de jitter, operaciones de codificación/decodificación) y la pérdida de paquetes. La falta de una relación perfecta entre los fotogramas de video enviados y recibidos hace imposible usar la herramienta VMAF tal como está, después de simplemente grabar los flujos de video en el lado del emisor (referencia) y en el lado del receptor (distorsionado). La herramienta webrtcperf integra un mecanismo de marca de agua de video que usamos anteriormente para medir el retardo de video de extremo a extremo (timestampWatermarkVideo). Al tener tanto los archivos de video de referencia como los distorsionados con una marca de tiempo superpuesta en cada fotograma, la herramienta puede procesar los archivos de video, alinearlos y filtrar los fotogramas que tienen la misma marca de tiempo superpuesta. Después del paso de alineación, la herramienta evalúa la puntuación de video usando el filtro libvmaf de ffmpeg. Lo que obtenemos aquí es una indicación perceptual de la degradación del video causada por el codificador que podría reducir el bitrate para coincidir con el ancho de banda disponible. Vale la pena notar que la herramienta no evaluará la calidad del video para los fotogramas descartados (perdidos), por lo que la puntuación VMAF obtenida debe combinarse con las otras métricas de WebRTC (como la pérdida de paquetes y la tasa de fotogramas de video recibida) para tener una evaluación de calidad completa.
La forma sugerida de usar esta funcionalidad es ejecutar la imagen docker de webrtcperf que ya incluye una versión parcheada de ffmpeg con el filtro libvmaf.

Ejemplo de prueba que ejecuta la evaluación de calidad VMAF (inicie la pila de prometheus antes de ejecutar la prueba):

docker run -it --rm \
  -v /dev/shm:/dev/shm \
  -v $PWD/data:/data \
  -p 9000 \
  --net=prometheus-stack_default \
  ghcr.io/vpalmisano/webrtcperf:devel \
  --sessions=2 \
  --run-duration=180 \
  --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://pushgateway:9091 \
  --script-params="{timestampWatermarkVideo:true,saveSendVideoTrack:'0',saveRecvVideoTrack:'1'}" \
  --server-port=5000 \
  --server-use-https \
  --server-data=/data \
  --vmaf-path=/data \
  --vmaf-preview

La herramienta ejecutará una conferencia de Google Meet con 2 participantes, guardando el video enviado por "Participant-000000" (saveSendVideoTrack:’0’) y el video recibido por "Participant-000001" (saveRecvVideoTrack:'1'). Necesitamos activar la herramienta en modo servidor (--server-port) para guardar los fotogramas de video capturados dentro de la automatización de la página web. Agregar la opción --vmaf-path hará que la herramienta ejecute la evaluación VMAF al final de la prueba y --vmaf-preview generará una comparación lado a lado entre el video de referencia y el video degradado.
Las salidas de VMAF son:

  • Un nombre de carpeta para cada comparación realizada por la herramienta para la prueba actual en el formato <Sender Participant>_recv-by_<Receiver Participant>; para esta prueba simple será Participant-000000_recv-by_Participant-000001. En cada carpeta encontraremos los siguientes archivos:
    • psnr.log (el registro PSNR);
    • vmaf-log.json (la salida VMAF completa);
    • vmaf-log.png (un gráfico realizado con las puntuaciones fotograma a fotograma);
    • comparison.mp4 con la comparación lado a lado.
  • Un archivo vmaf.json que contiene algunas puntuaciones VMAF agregadas para cada comparación.

vmaf-log.png:
image11

vmaf.json:

[
  {
    "sender": "Participant-000000",
    "receiver": "Participant-000001",
    "min": 61.083063,
    "max": 87.46276,
    "mean": 76.260023,
    "harmonic_mean": 76.118533
  }
]

Otras opciones para controlar la evaluación VMAF son:

  • --vmaf-keep-source-files: Verdadero por defecto, conserva los archivos de video crudos grabados en la carpeta de destino después de la evaluación.
  • --vmaf-keep-intermediate-files: Falso por defecto, cuando es verdadero, todos los archivos de video intermedios utilizados por la herramienta VMAF se conservarán en la carpeta de destino, permitiendo depurarlos.
  • --vmaf-skip-duplicated: Falso por defecto, cuando es verdadero, la herramienta omitirá los fotogramas con la misma marca de tiempo reconocida. Use esta opción si el codificador utilizado por el servicio que está probando aplica una duplicación de fotogramas para igualar la velocidad de fotogramas configurada (por ejemplo, esto podría ocurrir al probar videos HLS).
  • --vmaf-crop: una cadena JSON con una configuración de recorte para aplicar a videos de referencia y/o degradados. La configuración de recorte debe expresarse usando la sintaxis del filtro de recorte de ffmpeg (https://ffmpeg.org/ffmpeg-filters.html#crop).
    Ejemplo:
    {
      "Participant-000001_recv-by_Participant-000000": {
        ref: { w: "iw-10", h: "ih-5" },
        deg: { w: "200", h: "200" }
      }
    }
    

Ejecutar pruebas distribuidas

Ejecutar pruebas con múltiples participantes generalmente requiere una cantidad de CPU y memoria que podría no coincidir con las capacidades de la máquina anfitriona. Además, ejecutar pruebas con video de alta resolución y/o recibir transmisiones de muchos participantes remotos en la misma sala de conferencias requerirá una cantidad de ancho de banda que podría no estar disponible en un solo host. Por estas razones, al ejecutar pruebas con muchos participantes concurrentes, la forma preferida de usar webrtcperf es activar la opción de modo servidor en una instancia (la llamaremos "colector") y ejecutar todas las demás instancias de prueba de webrtcperf requeridas en diferentes hosts ("trabajador"); las instancias trabajadoras recopilarán las métricas extraídas de las sesiones locales en ejecución y las enviarán al colector, que las agregará y las enviará al servicio Prometheus Pushgateway.

image12

Comando de ejemplo para iniciar webrtcperf en modo "colector" en el host 192.168.0.1:

webrtcperf \
  --run-duration=200 \
  --prometheus-pushgateway=http://127.0.0.1:9091 \
  --server-port=5000 \
  --server-use-https \
  --server-secret=<SECRET>

Comando de ejemplo para iniciar dos instancias "trabajador" en diferentes hosts, ejecutando 50 participantes cada una:

# Worker 1 
webrtcperf \
  --sessions=50 \
  --run-duration=180 \
  --url=<URL> \
  --push-stats-url=https://192.168.0.1:5000 \
  --server-secret=<SECRET> \
  --push-stats-id=1 \
  --start-session-id=0 \
  --start-timestamp=1749212181000

# Worker 2
webrtcperf \
  --sessions=50 \
  --run-duration=180 \
  --url=<URL> \
  --push-stats-url=https://192.168.0.1:5000 \
  --server-secret=<SECRET> \
  --push-stats-id=2 \
  --start-session-id=50 \
  --start-timestamp=1749212181000

Tenga en cuenta que necesita agregar las siguientes opciones para cada trabajador:

  • La dirección/puerto del colector con --push-stats-url.
  • Un identificador único con --push-stats-id que será utilizado por el colector para agregar las métricas provenientes de ese trabajador.
  • Debe establecer --start-session-id a 50 en el segundo host, para que los participantes se indexen comenzando desde Participant-000050 hasta Participant-000099.
  • Use el mismo --start-timestamp para ambos hosts y establézcalo en la misma marca de tiempo UNIX expresada en milisegundos. De esta manera, toda la automatización de acciones que se ejecuta en cada host estará sincronizada en el tiempo (ejemplo: desmutear a Participant-000001 y Participant-000051 en el tiempo 60 se ejecutará al mismo tiempo de reloj en ambas instancias). Los relojes de las máquinas trabajadoras deben estar sincronizados.
  • Use el mismo valor de --server-secret tanto para el colector como para los trabajadores.

Para la configuración del colector, use una opción --run-duration más larga solo para evitar perder las últimas actualizaciones de métricas de los hosts trabajadores.

Características experimentales

Ejecutar pruebas con el prompt de IA

La opción --prompt le permite ejecutar una prueba con un prompt de IA que se utilizará para generar la configuración del escenario de prueba. El prompt debe ser una descripción precisa del escenario de prueba que se desea ejecutar, incluyendo el número de participantes, la URL del servicio, la configuración de limitación de red, etc. El prompt se enviará al servicio Google Gemini AI y la respuesta se analizará para generar una configuración de prueba válida.

Ejemplo de uso:

export GEMINI_API_KEY=<key>
webrtcperf --prompt "run a 2min test with 2 sessions on 'https://v3demo.mediasoup.org/?roomId=webrtcperf-test-12345' limiting the 2nd session upstream at 1Mbps with 1% packet loss for 30s, 2Mbps for 30s and 1Mbps for all the remaining time"

Agregue la opción --dry-run para imprimir la configuración de prueba generada sin ejecutarla:

webrtcperf --prompt --dry-run "run a 2min test with 2 sessions on 'https://v3demo.mediasoup.org/?roomId=webrtcperf-test-12345' limiting the 2nd session upstream at 1Mbps with 1% packet loss for 30s, 2Mbps for 30s and 1Mbps for all the remaining time"
{
  throttleConfig: '[{ sessions: "1", up: [{ rate: 1000, loss: 1, at: 0 }, { rate: 2000, at: 30 }, { rate: 1000, at: 60 }] }]',
  runDuration: 120,
  sessions: 2,
  url: 'https://v3demo.mediasoup.org/?roomId=webrtcperf-test-12345',
}

Instalación de MCP

Para usar webrtcperf como servidor MCP, agregue la siguiente configuración:

{
  "mcpServers": {
    "webrtcperf": {
      "command": "npx",
      "args": ["-y", "@vpalmisano/webrtcperf@latest", "--mcp"]
    }
  }
}

Autores

Licencia

AGPL