mediasoup

/ home / Documentation / v3 / mediasoup / API

mediasoup v3 API

mediasoup

The top-level exported module.

const mediasoup = require("mediasoup");

// Or using destructuring assignment.
const {
  version,
  observer,
  createWorker,
  getSupportedRtpCapabilities,
  parseScalabilityMode
} = require("mediasoup");

Properties

mediasoup.version

The mediasoup version.

@type String, read only

console.log(mediasoup.version);
// => "3.0.0"

mediasoup.observer

An event emitter that allows the application (or third party libraries) monitor Worker instances created by the application. See the Observer Events section below.

@type EventEmitter, read only

Functions

mediasoup.createWorker(settings)

Creates a new worker with the given settings.

Argument Type Description Required Default
settings WorkerSettings Worker settings. No  

@async

@returns Worker

const worker = async mediasoup.createWorker(
  {
    logLevel            : "warn",
    dtlsCertificateFile : "/home/foo/dtls-cert.pem",
    dtlsPrivateKeyFile  : "/home/foo/dtls-key.pem"
  });

mediasoup.getSupportedRtpCapabilities()

Returns a cloned copy of the mediasoup supported RTP capabilities, specifically the content of the mediasoup/lib/supportedRtpCapabilities.js file.

@returns RtpCapabilities

const rtpCapabilities = mediasoup.getSupportedRtpCapabilities();

console.log(rtpCapabilities);
// => { codecs: [...], headerExtensions: [...] }

mediasoup.parseScalabilityMode(scalabilityMode)

Parses the given scalabilityMode string according to the rules in webrtc-svc.

Argument Type Description Required Default
scalabilityMode String Scalability mode. No  

@returns Object:

  • spatialLayers {@type Number} Number of spatial layers (by default 1).

  • temporalLayers {@type Number} Number of temporal layers (by default 1).

mediasoup.parseScalabilityMode("L2T3");
// => { spatialLayers: 2, temporalLayers: 3 }

mediasoup.parseScalabilityMode("S3T3");
// => { spatialLayers: 3, temporalLayers: 3 }

mediasoup.parseScalabilityMode("L4T7_KEY_SHIFT");
// => { spatialLayers: 4, temporalLayers: 7 }

mediasoup.parseScalabilityMode(undefined);
// => { spatialLayers: 1, temporalLayers: 1 }

Observer Events

See the Observer API section below.

mediasoup.observer.on(“newworker”, fn(worker))

Emitted when a new worker is created.

Argument Type Description
worker Worker New worker.
mediasoup.observer.on("newworker", (worker) =>
{
  console.log("new worker created [pid:%d]", worker.pid);
});

Worker

A worker represents a mediasoup C++ subprocess that runs in a single CPU core and handles Router instances.

Dictionaries

WorkerSettings

Field Type Description Required Default
logLevel String Logging level for logs generated by the media worker subprocesses (check the Debugging documentation). Valid values are “debug”, “warn”, “error” and “none”. No “error”
logTags Array<String> Log tags for debugging. Check the list of available tags in Debugging documentation. No [ ]
rtcMinPort Number Minimun RTC port for ICE, DTLS, RTP, etc. No 10000
rtcMaxPort Number Maximum RTC port for ICE, DTLS, RTP, etc. No 59999
dtlsCertificateFile String Path to the DTLS public certificate file in PEM format. If unset, a certificate is dynamically created. No  
dtlsPrivateKeyFile String Path to the DTLS certificate private key file in PEM format. If unset, a certificate is dynamically created. No  

RTC listening IPs are not set at worker level. Instead, they are set per individual transport.

WorkerUpdateableSettings

Field Type Description Required Default
logLevel String Logging level for logs generated by the media worker subprocesses (check the Debugging documentation). Valid values are “debug”, “warn”, “error” and “none”. No “error”
logTags Array<String> Log tags for debugging. Check the list of available tags in Debugging documentation. No  

Properties

worker.pid

The PID of the worker process.

@type Number, read only

console.log(worker.pid);
// => 86665

worker.closed

Whether the worker is closed.

@type Boolean, read only

console.log(worker.closed);
// => false

worker.observer

See the Observer Events section below.

@type EventEmitter, read only

Methods

worker.close()

Closes the worker. Triggers a “workerclose” event in all its routers.

worker.updateSettings(settings)

Updates the worker settings in runtime. Just a subset of the worker settings can be updated.

Argument Type Description Required Default
settings WorkerUpdateableSettings Worker updateable settings. No  

@async

await worker.updateSettings({ logLevel: "warn" });

worker.createRouter(options)

Creates a new router.

Argument Type Description Required Default
options RouterOptions Router options. Yes  

@async

@returns Router

const mediaCodecs =
[
  {
    kind        : "audio",
    mimeType    : "audio/opus",
    clockRate   : 48000,
    channels    : 2
  },
  {
    kind       : "video",
    mimeType   : "video/H264",
    clockRate  : 90000,
    parameters :
    {
      "packetization-mode"      : 1,
      "profile-level-id"        : "42e01f",
      "level-asymmetry-allowed" : 1
    }
  }
];

const router = await worker.createRouter({ mediaCodecs });

Events

worker.on(“died”, fn())

Emitted when the worker process unexpectedly dies.

This should never happens (if it happens, it's a bug).

worker.on("died", () =>
{
  console.error("mediasoup worker died!");
});

Observer Events

See the Observer API section below.

worker.observer.on(“close”, fn())

Emitted when the worker is closed for whatever reason.

worker.observer.on(“newrouter”, fn(router))

Emitted when a new router is created.

Argument Type Description
router Router New router.
worker.observer.on("newrouter", (router) =>
{
  console.log("new router created [id:%s]", router.id);
});

Router

A router enables injection, selection and forwarding of media streams through Transport instances created on it.

Developers may think of a mediasoup router as if it were a “multi-party conference room”, although mediasoup is much more low level than that and doesn't constrain itself to specific high level use cases (for instance, a “multi-party conference room” could involve various mediasoup routers, even in different physicals hosts).

Dictionaries

RouterOptions

Field Type Description Required Default
mediaCodecs Array<RtpCodecCapability> Router media codecs. No [ ]
  • Feature codecs such as RTX MUST NOT be placed into the mediaCodecs list.
  • If preferredPayloadType is given in a RtpCodecCapability (although it's unnecessary) it's extremely recommended to use a value in the 96-127 range.

Properties

router.id

Router identifier.

@type String, read only

console.log(router.id);
// => "15177e19-5665-4eba-9a6a-c6cf3db16259"

router.closed

Whether the router is closed.

@type Boolean, read only

router.rtpCapabilities

An Object with the RTP capabilities of the router. These capabilities are tipically needed by mediasoup clients to compute their sending RTP parameters.

@type RtpCapabilities, read only

Check the RTP Parameters and Capabilities section for more details.

router.observer

See the Observer Events section below.

@type EventEmitter, read only

Methods

router.close()

Closes the router. Triggers a “routerclose” event in all its transports and also “routerclose” event in all its RTP observers.

router.createWebRtcTransport(options)

Creates a new WebRTC transport.

Argument Type Description Required Default
options WebRtcTransportOptions WebRTC transport options. Yes  

@async

@returns WebRtcTransport

const transport = await router.createWebRtcTransport(
  {
    listenIps : [ { ip: "192.168.0.111", announcedIp: "88.12.10.41" } ],
    enableUdp : true,
    enableTcp : true,
    preferUdp : true
  });

router.createPlainRtpTransport(options)

Creates a new plain RTP transport.

Argument Type Description Required Default
options PlainRtpTransportOptions Plain RTP transport options. Yes  

@async

@returns PlainRtpTransport

const transport = await router.createPlainRtpTransport(
  {
    listenIp : "a1:22:aA::08",
    rtcpMux  : true,
    comedia  : true
  });

router.createPipeTransport(options)

Creates a new pipe transport.

Argument Type Description Required Default
options PipeTransportOptions Pipe transport options. Yes  

@async

@returns PipeTransport

const transport = await router.createPipeTransport(
  {
    listenIp : "192.168.1.33"
  });

router.pipeToRouter({ producerId, dataProducerId, router, listenIp })

Pipes the given media or data producer into another router in the same host. It creates an underlying PipeTransport (if not previously created) that interconnects both routers.

This is specially useful to expand broadcasting capabilities (one to many) by interconnecting different routers that run in separate workers (so in different CPU cores).

Argument Type Description Required Default
producerId String Producer id No  
dataProducerId String Data producer id No  
router Router Destination router to pipe the given producer. Yes  
listenIp String IP to connect both routers in the same host. No “127.0.0.1”
enableSctp Boolean Create a SCTP association. No true
numSctpStreams TransportNumSctpStreams SCTP streams number. No  
  • Only one of producerId and dataProducerId must be provided.
  • SCTP agruments will only apply the first time the underlying transports are created.

@async

@returns Object:

  • pipeConsumer {@type Consumer} Consumer created in the current router.

  • pipeProducer {@type Producer} Producer created in the destination router.

// Have two workers.
const worker1 = await mediasoup.createWorker();
const worker2 = await mediasoup.createWorker();

// Create a router in each worker.
const router1 = await worker1.createRouter({ mediaCodecs });
const router2 = await worker2.createRouter({ mediaCodecs });

// Produce in router1.
const transport1 = await router1.createWebRtcTransport({ ... });
const producer1 = await transport1.produce({ ... });

// Pipe producer1 into router2.
await router1.pipeToRouter({ producerId: producer1.id, router: router2 });

// Consume producer1 from router2.
const transport2 = await router2.createWebRtcTransport({ ... });
const consumer2 = await transport2.consume({ producerId: producer1.id, ... });

router.createAudioLevelObserver(options)

Creates a new audio level observer.

Argument Type Description Required Default
options AudioLevelObserverOptions Options. Yes  

@async

@returns AudioLevelObserver

const audioLevelObserver = await router.createAudioLevelObserver(
  {
    maxEntries : 1,
    threshold  : -70,
    interval   : 2000
  });

router.canConsume({ producerId, rtpCapabilities })

Whether the given RTP capabilities are valid to consume the given producer.

Argument Type Description Required Default
producerId String Producer id. Yes  
rtpCapabilities RtpCapabilities RTP capabilities of the potential consumer. Yes  

@returns Boolean

if (router.canConsume({ producerId, rtpCapabilities }))
{
  // Consume the producer by calling transport.consume({ producerId, rtpCapabilities }).
}

Events

router.on(“workerclose”, fn())

Emitted when the worker this router belongs to is closed for whatever reason. The router itself is also closed. A “routerclose” event is triggered in all its transports and a “routerclose” event is triggered in all its RTP observers.

router.on("workerclose", () =>
{
  console.log("worker closed so router closed");
});

Observer Events

See the Observer API section below.

router.observer.on(“close”, fn())

Emitted when the router is closed for whatever reason.

router.observer.on(“newtransport”, fn(transport))

Emitted when a new transport is created.

Argument Type Description
transport Transport New transport.
router.observer.on("newtransport", (transport) =>
{
  console.log("new transport created [id:%s]", transport.id);
});

Transport

@abstract

A transport connects an endpoint with a mediasoup router and enables transmission of media in both directions by means of Producer and Consumer instances created on it.

mediasoup implements the following transport classes:

Dictionaries

TransportListenIp

Field Type Description Required Default
ip String Listening IPv4 or IPv6. Yes  
announcedIp String Announced IPv4 or IPv6 (useful when running mediasoup behind NAT with private IP). No  

TransportTuple

Field Type Description Required Default
localIP String Local IP address. Yes  
localPort Number Local port. Yes  
remoteIP String Remote IP address. Yes  
remotePort Number Remote port. Yes  
protocol String Protocol (“udp” / “tcp”). Yes  

TransportSctpParameters

Field Type Description Required Default
port Number Must always equal 5000. Yes  
OS Number Initially requested number of outgoing SCTP streams. Yes  
MIS Number Maximum number of incoming SCTP streams. Yes  
maxMessageSize Number Maximum allowed size for SCTP messages. Yes  

TransportNumSctpStreams

Field Type Description Required Default
OS Number Initially requested number of outgoing SCTP streams (from 1 to 65535). No 1024
MIS Number Maximum number of incoming SCTP streams (from 1 to 65535). No 1024

Both OS and MIS are part of the SCTP INIT+ACK handshake. OS refers to the initial number of outgoing SCTP streams that the server side transport creates (to be used by DataConsumers), while MIS refers to the maximum number of incoming SCTP streams that the server side transport can receive (to be used by DataProducers). So, if the server side transport will just be used to create data producers (but no data consumers), OS can be low (~1). However, if data consumers are desired on the server side transport, OS must have a proper value and such a proper value depends on whether the remote endpoint supports SCTP_ADD_STREAMS extension or not.

  • libwebrtc (Chrome, Safari, etc) does not enable SCTP_ADD_STREAMS so, if data consumers are required, OS should be 1024 (the maximum number of DataChannels that libwebrtc enables).
  • Firefox does enable SCTP_ADD_STREAMS so, if data consumers are required, OS can be lower (16 for instance). The mediasoup transport will allocate and announce more outgoing SCTM streams when needed.
  • mediasoup-client provides specific per browser/version OS and MIS values via the device.sctpCapabilities getter.

Enums

SctpState

Value Description
“new” SCTP procedures not yet initiated.
“connecting” SCTP connecting.
“connected” SCTP successfully connected.
“failed” SCTP connection failed.
“closed” SCTP state when the transport has been closed.

Properties

These are properties common to all transport classes. Each transport class may define new ones.

transport.id

Transport identifier.

@type String, read only

transport.closed

Whether the transport is closed.

@type Boolean, read only

transport.appData

Custom data Object provided by the application in the transport factory method. The app can modify its content at any time.

@type Object, read only

transport.appData.foo = "bar";

transport.observer

See the Observer Events section below.

@type EventEmitter, read only

Methods

These are methods common to all transport classes. Each transport class may define new ones.

transport.close()

Closes the transport. Triggers a “transportclose” event in all its producers and also “transportclose” event in all its consumers.

transport.getStats()

Returns current RTC statistics of the transport. Each transport class produces a different set of statistics.

@async

@abstract

@returns Array<Object>

Check the RTC Statistics section for more details.

transport.connect()

Provides the transport with the remote endpoint's transport parameters. Each transport class requires specific arguments in this method. Check the connect() method in each one of them.

@async

@abstract

transport.produce(options)

Instructs the transport to receive audio or video RTP (or SRTP depending on the transport class). This is the way to inject media into mediasoup.

Argument Type Description Required Default
options ProducerOptions Producer options. Yes  

@async

@returns Producer

Check the RTP Parameters and Capabilities section for more details.

const producer = await transport.produce(
  {
    kind          : "video",
    rtpParameters :
    {
      mid    : "1",
      codecs :
      [
        {
          mimeType    : "video/VP8",
          payloadType : 101,
          clockRate   : 90000,
          rtcpFeedback :
          [
            { type: "nack" },
            { type: "nack", parameter: "pli" },
            { type: "ccm", parameter: "fir" },
            { type: "goog-remb" }
          ]
        },
        {
          mimeType    : "video/rtx",
          payloadType : 102,
          clockRate   : 90000,
          parameters  : { apt: 101 }
        }
      ],
      headerExtensions :
      [
        {
          id  : 2, 
          uri : "urn:ietf:params:rtp-hdrext:sdes:mid"
        },
        { 
          id  : 3, 
          uri : "urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id"
        },
        { 
          id  : 5, 
          uri: "urn:3gpp:video-orientation" 
        },
        { 
          id  : 6, 
          uri : "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time"
        }
      ],
      encodings :
      [
        { rid: "r0", active: true, maxBitrate: 100000 },
        { rid: "r1", active: true, maxBitrate: 300000 }
        { rid: "r2", active: true, maxBitrate: 900000 }
      ],
      rtcp :
      {
        cname : "Zjhd656aqfoo"
      }
    }
  });

transport.consume(options)

Instructs the transport to send audio or video RTP (or SRTP depending on the transport class). This is the way to extract media from mediasoup.

Argument Type Description Required Default
options ConsumerOptions Consumer options. Yes  

@async

@returns Consumer

Check the RTP Parameters and Capabilities section for more details.

const consumer = await transport.consume(
  {
    producerId      : "a7a955cf-fe67-4327-bd98-bbd85d7e2ba3",
    rtpCapabilities :
    {
      codecs :
      [
        {
          mimeType             : "audio/opus",
          kind                 : "audio",
          clockRate            : 48000,
          preferredPayloadType : 100,
          channels             : 2
        },
        {
          mimeType             : "video/H264",
          kind                 : "video",
          clockRate            : 90000,
          preferredPayloadType : 101,
          rtcpFeedback         :
          [
            { type: "nack" },
            { type: "nack", parameter: "pli" },
            { type: "ccm", parameter: "fir" },
            { type: "goog-remb" }
          ],
          parameters :
          {
            "level-asymmetry-allowed" : 1,
            "packetization-mode"      : 1,
            "profile-level-id"        : "4d0032"
          }
        },
        {
          mimeType             : "video/rtx",
          kind                 : "video",
          clockRate            : 90000,
          preferredPayloadType : 102,
          rtcpFeedback         : [],
          parameters           :
          {
            apt : 101
          }
        }
      ],
      headerExtensions :
      [
        {
          kind             : "video",
          uri              : "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time", // eslint-disable-line max-len
          preferredId      : 4,
          preferredEncrypt : false
        },
        {
          kind             : "audio",
          uri              : "urn:ietf:params:rtp-hdrext:ssrc-audio-level",
          preferredId      : 8,
          preferredEncrypt : false
        },
        {
          kind             : "video",
          uri              : "urn:3gpp:video-orientation",
          preferredId      : 9,
          preferredEncrypt : false
        },
        {
          kind             : "video",
          uri              : "urn:ietf:params:rtp-hdrext:toffset",
          preferredId      : 10,
          preferredEncrypt : false
        }
      ]
    }
  });

transport.produceData(options)

Instructs the transport to receive data via SCTP. This is the way to inject data into mediasoup.

Argument Type Description Required Default
options DataProducerOptions Data producer options. No { }

@async

@returns DataProducer

const producer = await transport.produceData();

transport.consumeData(options)

Instructs the transport to send data via SCTP. This is the way to extract data from mediasoup.

Argument Type Description Required Default
options DataConsumerOptions Data Consumer options. Yes  

@async

@returns DataConsumer

const consumer = await transport.consumeData(
  {
    producerId      : "a7a955cf-fe67-4327-bd98-bbd85d7e2ba4"
  });

Events

These are events common to all transport classes. Each transport class may define new ones.

transport.on(“routerclose”, fn())

Emitted when the router this transport belongs to is closed for whatever reason. The transport itself is also closed. A “transportclose” event is triggered in all its producers and a “transportclose” event is triggered in all its consumers.

transport.on("routerclose", () =>
{
  console.log("router closed so transport closed");
});

Observer Events

See the Observer API section below.

These are observer events common to all transport classes. Each transport class may define new ones.

transport.observer.on(“close”, fn())

Emitted when the transport is closed for whatever reason.

transport.observer.on(“newproducer”, fn(producer))

Emitted when a new producer is created.

Argument Type Description
producer Producer New producer.
transport.observer.on("newproducer", (producer) =>
{
  console.log("new producer created [id:%s]", producer.id);
});

transport.observer.on(“newconsumer”, fn(consumer))

Emitted when a new consumer is created.

Argument Type Description
consumer Consumer New consumer.
transport.observer.on("newconsumer", (consumer) =>
{
  console.log("new consumer created [id:%s]", consumer.id);
});

transport.observer.on(“newdataproducer”, fn(dataProducer))

Emitted when a new data producer is created.

Argument Type Description
dataProducer DataProducer New producer.
transport.observer.on("newdataproducer", (dataProducer) =>
{
  console.log("new data producer created [id:%s]", dataProducer.id);
});

transport.observer.on(“newdataconsumer”, fn(dataConsumer))

Emitted when a new data consumer is created.

Argument Type Description
dataConsumer DataConsumer New consumer.
transport.observer.on("newdataconsumer", (dataConsumer) =>
{
  console.log("new data consumer created [id:%s]", dataConsumer.id);
});

WebRtcTransport

@inherits Transport

A WebRTC transport represents a network path negotiated by both, a WebRTC endpoint and mediasoup, via ICE and DTLS procedures. A WebRTC transport may be used to receive media, to send media or to both receive and send. There is no limitation in mediasoup. However, due to their design, mediasoup-client and libmediasoupclient require separate WebRTC transports for sending and receiving.

The WebRTC transport implementation of mediasoup is ICE Lite, meaning that it does not initiate ICE connections but expects ICE Binding Requests from endpoints.

Dictionaries

WebRtcTransportOptions

Field Type Description Required Default
listenIps Array<TransportListenIp>|TransportListenIp|String Listening IP address or addresses in order of preference (first one is the preferred one). Yes  
enableUdp Boolean Listen in UDP. No true
enableTcp Boolean Listen in TCP. No false
preferUdp Boolean Listen in UDP. No false
preferTcp Boolean Listen in TCP. No false
initialAvailableOutgoingBitrate Number Initial available outgoing bitrate (in bps). No 600000
minimumAvailableOutgoingBitrate Number Minimum available outgoing bitrate (in bps) to apply when the consumer endpoint reports less than this value. Use it with caution. No 300000
enableSctp Boolean Create a SCTP association. No false
numSctpStreams TransportNumSctpStreams SCTP streams number. No  
maxSctpMessageSize Number Maximum size of data that can be passed to DataProducer's send() method. No 262144
appData Object Custom application data. No { }
  • Both initialAvailableOutgoingBitrate and minimumAvailableOutgoingBitrate are just applied when the consumer endpoint supports REMB or Transport-CC.
  • If given, minimumAvailableOutgoingBitrate must be higher or equal than initialAvailableOutgoingBitrate.

IceParameters

Field Type Description Required Default
usernameFragment String ICE username fragment. No  
password String ICE password. No  
iceLite Boolean ICE Lite. No  

IceCandidate

Field Type Description Required Default
foundation String Unique identifier that allows ICE to correlate candidates that appear on multiple transports. Yes  
priority Number The assigned priority of the candidate. Yes  
ip String The IP address of the candidate. Yes  
protocol String The protocol of the candidate (“udp” / “tcp”). Yes  
port Number The port for the candidate. Yes  
type String The type of candidate (always “host”). Yes  
tcpType String The type of TCP candidate (always “passive”). No  

DtlsParameters

Field Type Description Required Default
role DtlsRole DTLS role. No “auto”
fingerprints DtlsFingerprints DTLS fingerprints. Yes  

DtlsFingerprints

Map of DTLS algorithms (as defined in the “Hash function Textual Names” registry initially specified in RFC 4572 Section 8) and their corresponding certificate fingerprint values (in lowercase hex string as expressed utilizing the syntax of “fingerprint” in RFC 4572 Section 5).

Field Type Description Required Default
sha-1 String SHA-1 certificate fingerprint. No  
sha-224 String SHA-224 certificate fingerprint. No  
sha-256 String SHA-256 certificate fingerprint. No  
sha-384 String SHA-384 certificate fingerprint. No  
sha-512 String SHA-512 certificate fingerprint. No  

Enums

IceState

Value Description
“new” No ICE Binding Requests have been received yet.
“connected” Valid ICE Binding Request have been received, but none with USE-CANDIDATE attribute. Outgoing media is allowed.
“completed” ICE Binding Request with USE_CANDIDATE attribute has been received. Media in both directions is now allowed.
“disconnected” ICE was “connected” or “completed” but it has suddenly failed (this can just happen if the selected tuple has “tcp” protocol).
“closed” ICE state when the transport has been closed.

DtlsRole

Value Description
“auto” The DTLS role is determined based on the resolved ICE role (the “controlled” role acts as DTLS client, the “controlling” role acts as DTLS server”). Since mediasoup is a ICE Lite implementation it always behaves as ICE “controlled”.
“client” DTLS client role.
“server” DTLS server role.

DtlsState

Value Description
“new” DTLS procedures not yet initiated.
“connecting” DTLS connecting.
“connected” DTLS successfully connected (SRTP keys already extracted).
“failed” DTLS connection failed.
“closed” DTLS state when the transport has been closed.

Properties

See also Transport Properties.

webRtcTransport.iceRole

Local ICE role. Due to the mediasoup ICE Lite design, this is always “controlled”.

@type String, read only

webRtcTransport.iceParameters

Local ICE parameters.

@type IceParameters, read only

webRtcTransport.iceCandidates

Local ICE candidates.

@type Array<IceCandidate>, read only

webRtcTransport.iceState

Current ICE state.

@type IceState, read only

webRtcTransport.iceSelectedTuple

The selected transport tuple if ICE is in “connected” or “completed” state. It is undefined if ICE is not established (no working candidate pair was found).

@type TransportTuple, read only

webRtcTransport.dtlsParameters

Local DTLS parameters.

@type DtlsParameters, read only

webRtcTransport.dtlsState

Current DTLS state.

@type DtlsState, read only

webRtcTransport.dtlsRemoteCert

The remote certificate in PEM format. It is set once the DTLS state becomes “connected”.

@type String, read only

The application may want to inspect the remote certificate for authorization purposes by using some certificates utility such as the Node pem module.

webRtcTransport.sctpParameters

Local SCTP parameters.

@type SctpParameters, read only

webRtcTransport.sctpState

Current SCTP state.

@type SctpState, read only

Methods

See also Transport Methods.

webRtcTransport.connect({ dtlsParameters })

Provides the WebRTC transport with the endpoint parameters.

Argument Type Description Required Default
dtlsParameters DtlsParameters Remote DTLS parameters. Yes  

@async

@overrides

await transport.connect(
  {
    dtlsParameters :
    {
      role         : "server",
      fingerprints :
      [
        {
          algorithm : "sha-256",
          value     : "E5:F5:CA:A7:2D:93:E6:16:AC:21:09:9F:23:51:62:8C:D0:66:E9:0C:22:54:2B:82:0C:DF:E0:C5:2C:7E:CD:53"
        }
      ]
    }
  });

webRtcTransport.setMaxIncomingBitrate(bitrate)

Set maximum incoming bitrate for media streams sent by the remote endpoint over this WebRTC transport.

Argument Type Description Required Default
bitrate Number Maximum sending bitrate in bps. Yes 0 (no limit)

@async

This method just works when REMB is used. It will be deprecated in the future.

await webRtcTransport.setMaxIncomingBitrate(3500000);

webRtcTransport.restartIce()

Restarts the ICE layer by generating new local ICE parameters that must be signaled to the remote endpoint.

@async

@returns IceParameters

const iceParameters = await webRtcTransport.restartIce();

// Send the new ICE parameters to the endpoint.

Events

See also Transport Events.

webRtcTransport.on(“icestatechange”, fn(iceState))

Emitted when the transport ICE state changes.

Argument Type Description
iceState IceState New ICE state.
webRtcTransport.on("icestatechange", (iceState) =>
{
  console.log("ICE state changed to %s", iceState);
});

webRtcTransport.on(“iceselectedtuplechange”, fn(iceSelectedTuple))

Emitted after ICE state becomes “completed” and when the ICE selected tuple changes.

Argument Type Description
iceSelectedTuple TransportTuple The new ICE selected tuple.

webRtcTransport.on(“dtlsstatechange”, fn(dtlsState))

Emitted when the transport DTLS state changes.

Argument Type Description
dtlsState DtlsState The new DTLS state.

webRtcTransport.on(“sctpstatechange”, fn(sctpState))

Emitted when the transport SCTP state changes.

Argument Type Description
sctpState SctpState The new SCTP state.

Observer Events

See also Transport Observer Events.

webRtcTransport.observer.on(“icestatechange”, fn(iceState))

Same as the icestatechange event.

webRtcTransport.observer.on(“iceselectedtuplechange”, fn(iceSelectedTuple))

Same as the iceselectedtuplechange event.

webRtcTransport.observer.on(“dtlsstatechange”, fn(dtlsState))

Same as the dtlsstatechange event.

webRtcTransport.observer.on(“sctpstatechange”, fn(sctpState))

Same as the sctpstatechange event.

PlainRtpTransport

@inherits Transport

A plain RTP transport represents a network path through which plain RTP and RTCP is transmitted.

Dictionaries

PlainRtpTransportOptions

Field Type Description Required Default
listenIp TransportListenIp|String Listening IP address. Yes  
rtcpMux Boolean Use RTCP-mux (RTP and RTCP in the same port). No true
comedia Boolean Whether remote IP:port should be auto-detected based on first RTP/RTCP packet received. If enabled, connect() method must not be called. This option is ignored if multiSource is set. No false
multiSource Boolean Whether RTP/RTCP from different remote IPs:ports is allowed. If set, the transport will just be valid for receiving media (consume() cannot be called on it) and connect() must not be called. No false
enableSctp Boolean Create a SCTP association. No false
numSctpStreams TransportNumSctpStreams SCTP streams number. No  
maxSctpMessageSize Number Maximum size of data that can be passed to DataProducer's send() method. No 262144
appData Object Custom application data. No { }
  • Note that comedia mode just makes sense when the remote endpoint is gonna produce RTP on this plain RTP transport. Otherwise, if the remote endpoint does not send any RTP packet to mediasoup, there is no way to detect its remote RTP IP and port, so the endpoint won't receive any packet from mediasoup.
    • In other words, do not use comedia mode if the remote endpoint is not going to produce RTP but just consume it. In those cases, do not set comedia flag and call connect() with the IP and port(s) of the remote endpoint.
  • When multiSource is set, the producer endpoint won't receive any RTCP packet from mediasoup. Try to avoid multiSource if possible. In case of video, if the producer does not send periodic video key frames, consumers will have problems to render the video (since RTCP PLI or FIR cannot be delivered to the producer if multiSource is set).

Properties

See also Transport Properties.

plainRtpTransport.tuple

The transport tuple. It's set after calling connect() method (it's undefined otherwise). If RTCP-mux is enabled, this tuple refers to both RTP and RTCP.

@type TransportTuple, read only

plainRtpTransport.rtcpTuple

The transport tuple for RTCP. It's set after calling connect() method just if RTCP-mux is not enabled.

@type TransportTuple, read only

plainRtpTransport.sctpParameters

Local SCTP parameters.

@type SctpParameters, read only

plainRtpTransport.sctpState

Current SCTP state.

@type SctpState, read only

Methods

See also Transport Methods.

plainRtpTransport.connect({ ip, port, rtcpPort })

Provides the plain RTP transport with the endpoint parameters.

Argument Type Description Required Default
ip String Remote IPv4 or IPv6. Yes  
port Number Remote port. Yes  
rtcpPort Number Remote RTCP port (required if RTCP-mux is not enabled). No  

@async

@overrides

Events

See also Transport Events.

plainRtpTransport.on(“sctpstatechange”, fn(sctpState))

Emitted when the transport SCTP state changes.

Argument Type Description
sctpState SctpState The new SCTP state.

Observer Events

See also Transport Observer Events.

plainRtpTransport.observer.on(“sctpstatechange”, fn(sctpState))

Same as the sctptatechange event.

PipeTransport

@inherits Transport

A pipe transport represents a network path through which plain RTP and RTCP is transmitted. Pipe transports are intented to intercommunicate two Router instances collocated on the same host or on separate hosts.

When calling consume() on a pipe transport, all RTP streams of the Producer are transmitted verbatim (in contrast to what happens in WebRtcTransport and PlainRtpTransport in which a single and continuos RTP stream is sent to the consuming endpoint).

Dictionaries

PipeTransportOptions

Field Type Description Required Default
listenIp TransportListenIp|String Listening IP address. Yes  
enableSctp Boolean Create a SCTP association. No false
numSctpStreams TransportNumSctpStreams SCTP streams number. No  
maxSctpMessageSize Number Maximum size of data that can be passed to DataProducer's send() method. No 1073741823
appData Object Custom application data. No { }

Properties

See also Transport Properties.

pipeTransport.tuple

The transport tuple. It's set after calling connect() method (it's undefined otherwise). This tuple refers to both RTP and RTCP.

@type TransportTuple, read only

pipeTransport.sctpParameters

Local SCTP parameters.

@type SctpParameters, read only

pipeTransport.sctpState

Current SCTP state.

@type SctpState, read only

Methods

See also Transport Methods.

pipeTransport.connect({ ip, port })

Provides the pipe RTP transport with the remote parameters.

Argument Type Description Required Default
ip String Remote IPv4 or IPv6. Yes  
port Number Remote port. Yes  

@async

@overrides

Events

See also Transport Events.

pipeTransport.on(“sctpstatechange”, fn(sctpState))

Emitted when the transport SCTP state changes.

Argument Type Description
sctpState SctpState The new SCTP state.

Observer Events

See also Transport Observer Events.

pipeTransport.observer.on(“sctpstatechange”, fn(sctpState))

Same as the sctpstatechange event.

Producer

A producer represents an audio or video source being injected into a mediasoup router. It's created on top of a transport that defines how the media packets are carried.

Dictionaries

ProducerOptions

Field Type Description Required Default
kind String Media kind (“audio” or “video”). Yes  
rtpParameters RtpSendParameters RTP parameters defining what the endpoint is sending. Yes  
paused Boolean Whether the producer must start in paused mode. No false
appData Object Custom application data. No { }

Check the RTP Parameters and Capabilities section for more details.

ProducerRtpStreamScore

Field Type Description Required Default
ssrc Number RTP stream SSRC. Yes  
rid String RTP stream RID value. No  
score Number RTP stream score (from 0 to 10) representing the transmission quality. Yes  

ProducerVideoOrientation

As documented in WebRTC Video Processing and Codec Requirements.

Field Type Description Required Default
camera Boolean Whether the source is a video camera. Yes  
flip Boolean Whether the video source is flipped. Yes  
rotation Number Rotation degrees (0, 90, 180 or 270). Yes  

Enums

ProducerType

Value Description
“simple” A single RTP stream is received with no spatial/temporal layers.
“simulcast” Two or more RTP streams are received, each of them with one or more temporal layers.
“svc” A single RTP stream is received with spatial/temporal layers.

Properties

producer.id

Producer identifier.

@type String, read only

producer.closed

Whether the producer is closed.

@type Boolean, read only

producer.kind

The media kind (“audio” or “video”).

@type String, read only

producer.rtpParameters

Producer RTP parameters.

@type RtpSendParameters, read only

Check the RTP Parameters and Capabilities section for more details.

producer.type

The RTC transmission type.

@type ProducerType, read only

producer.paused

Whether the producer is paused.

@type Boolean, read only

producer.score

The score of each RTP stream being received, representing their tranmission quality.

@type Array<ProducerRtpStreamScore>, read only

producer.appData

Custom data Object provided by the application in the producer factory method. The app can modify its content at any time.

@type Object, read only

producer.observer

See the Observer Events section below.

@type EventEmitter, read only

Methods

producer.close()

Closes the producer. Triggers a “producerclose” event in all its associated consumers.

producer.getStats()

Returns current RTC statistics of the producer.

@async

@returns Array<Object>

Check the RTC Statistics section for more details.

producer.pause()

Pauses the producer (no RTP is sent to its associated consumers). Triggers a “producerpause” event in all its associated consumers.

@async

producer.resume()

Resumes the producer (RTP is sent again to its associated consumers). Triggers a “producerresume” event in all its associated consumers.

@async

Events

producer.on(“transportclose”, fn())

Emitted when the transport this producer belongs to is closed for whatever reason. The producer itself is also closed. A “producerclose” event is triggered in all its associated consumers.

producer.on("transportclose", () =>
{
  console.log("transport closed so producer closed");
});

producer.on(“score”, fn(score))

Emitted when the producer score changes.

Argument Type Description
score Array<ProducerRtpStreamScore> RTP streams' scores.

producer.on(“videoorientationchange”, fn(videoOrientation))

Emitted when the video orientation changes. This is just possible if the “urn:3gpp:video-orientation” RTP extension has been negotiated in the producer RTP parameters.

Argument Type Description
videoOrientation ProducerVideoOrientation New video orientation.

Observer Events

See the Observer API section below.

producer.observer.on(“close”, fn())

Emitted when the producer is closed for whatever reason.

producer.observer.on(“pause”, fn())

Emitted when the producer is paused.

producer.observer.on(“resume”, fn())

Emitted when the producer is resumed.

producer.observer.on(“score”, fn(score))

Same as the score event.

producer.observer.on(“videoorientationchange”, fn(videoOrientation))

Same as the videoorientationchange event.

Consumer

A consumer represents an audio or video source being forwarded from a mediasoup router to an endpoint. It's created on top of a transport that defines how the media packets are carried.

Dictionaries

ConsumerOptions

Field Type Description Required Default
producerId String The id of the producer to consume. Yes  
rtpCapabilities RtpCapabilities RTP capabilities of the consuming endpoint. Yes  
paused Boolean Whether the consumer must start in paused mode. See note below. No false
preferredLayers ConsumerLayers Preferred spatial and temporal layer for simulcast or SVC media sources. If unset, the highest ones are selected. No  
appData Object Custom application data. No { }

Check the RTP Parameters and Capabilities section for more details.

When creating a video consumer, it's recommended to set paused to true, then transmit the consumer parameters to the consuming endpoint and, once the consuming endpoint has created its local side consumer, unpause the server side consumer using the resume() method.

This is an optimization to make it possible for the consuming endpoint to render the video as far as possible. If the server side consumer was created with paused: false, mediasoup will immediately request a key frame to the producer and that key frame may reach the consuming endpoint even before it's ready to consume it, generating “black” video until the device requests a keyframe by itself.

ConsumerLayers

Field Type Description Required Default
spatialLayer Number The spatial layer index (from 0 to N). Yes  
temporalLayer Number The temporal layer index (from 0 to N). No  

ConsumerRtpStreamScore

Field Type Description Required Default
score Number Score of the RTP stream in the consumer (from 0 to 10) representing its transmission quality. Yes  
producerScore Number Score of the currently selected RTP stream in the associated producer (from 0 to 10) representing its transmission quality. Yes  

Enums

ConsumerType

Value Description
“simple” A single RTP stream is sent with no spatial/temporal layers.
“simulcast” Two or more RTP streams are sent, each of them with one or more temporal layers.
“svc” A single RTP stream is sent with spatial/temporal layers.
“pipe” Special type for consumers created on a PipeTransport.

Properties

consumer.id

Consumer identifier.

@type String, read only

consumer.producerId

The associated producer identifier.

@type String, read only

consumer.closed

Whether the consumer is closed.

consumer.kind

The media kind (“audio” or “video”).

@type String, read only

consumer.rtpParameters

Consumer RTP parameters.

@type RtpReceiveParameters, read only

Check the RTP Parameters and Capabilities section for more details.

consumer.type

The RTC transmission type.

@type ConsumerType, read only

consumer.paused

Whether the consumer is paused. It does not take into account whether the associated producer is paused.

@type Boolean, read only

consumer.producerPaused

Whether the associated producer is paused.

@type Boolean, read only

consumer.score

The score of the RTP stream being sent, representing its tranmission quality.

@type ConsumerRtpStreamScore, read only

consumer.currentLayers

Current spatial and temporal layers (for simulcast and SVC consumers). It's null if no layers are being sent to the consuming endpoint.

@type ConsumerLayers|Null, read only

consumer.appData

Custom data Object provided by the application in the consumer factory method. The app can modify its content at any time.

@type Object, read only

consumer.observer

See the Observer Events section below.

@type EventEmitter, read only

Methods

consumer.close()

Closes the consumer.

consumer.getStats()

Returns current RTC statistics of the consumer.

@async

@returns Array<Object>

Check the RTC Statistics section for more details.

consumer.pause()

Pauses the consumer (no RTP is sent to the consuming endpoint).

@async

consumer.resume()

Resumes the consumer (RTP is sent again to the consuming endpoint).

@async

consumer.setPreferredLayers(preferredLayers)

Sets the preferred (highest) spatial and temporal layers to be sent to the consuming endpoint. Just valid for simulcast and SVC consumers.

Argument Type Description Required Default
preferredLayers ConsumerLayers Preferred spatial and temporal layers. The temporal layer is optional (if unset, the highest one is chosen). Yes  

@async

await consumer.setPreferredLayers({ spatialLayer: 3 });

consumer.requestKeyFrame()

Request a key frame to the associated producer. Just valid for video consumers.

@async

Events

consumer.on(“transportclose”, fn())

Emitted when the transport this consumer belongs to is closed for whatever reason. The consumer itself is also closed.

consumer.on("transportclose", () =>
{
  console.log("transport closed so consumer closed");
});

consumer.on(“producerclose”, fn())

Emitted when the associated producer is closed for whatever reason. The consumer itself is also closed.

consumer.on("producerclose", () =>
{
  console.log("associated producer closed so consumer closed");
});

consumer.on(“producerpause”, fn())

Emitted when the associated producer is paused.

consumer.on(“producerresume”, fn())

Emitted when the associated producer is resumed.

consumer.on(“score”, fn(score))

Emitted when the consumer score changes.

Argument Type Description
score ConsumerRtpStreamScore RTP stream score.

consumer.on(“layerschange”, fn(layers))

Emitted when the spatial/temporal layers being sent to the endpoint change. Just for simulcast or SVC consumers.

Argument Type Description
layers ConsumerLayers|Null Current spatial and temporal layers (or null if there are no current layers).

This event is emitted under various circumstances in SVC or simulcast consumers (assuming the consumer endpoints supports BWE via REMB or Transport-CC):

  • When the consumer (or its associated producer) is paused.
  • When all the RTP streams of the associated producer become inactive (no RTP received for a while).
  • When the available bitrate of the BWE makes the consumer upgrade or downgrade the spatial and/or temporal layers.
  • When there is no available bitrate for this consumer (even for the lowest layers) so the event fires with null as argument.

The Node.js application can detect the latter (consumer deactivated due to not enough bandwidth) by checking if both consumer.paused and consumer.producerPaused are falsy after the consumer has emitted this event with null as argument.

Observer Events

See the Observer API section below.

consumer.observer.on(“close”, fn())

Emitted when the consumer is closed for whatever reason.

consumer.observer.on(“pause”, fn())

Emitted when the consumer or its associated producer is paused and, as result, the consumer becomes paused.

consumer.observer.on(“resume”, fn())

Emitted when the consumer or its associated producer is resumed and, as result, the consumer is no longer paused.

consumer.observer.on(“score”, fn(score))

Same as the score event.

consumer.observer.on(“layerschange”, fn(layers))

Same as the layerschange event.

DataProducer

A data producer represents a SCTP data source being injected into a mediasoup router. It's created on top of a transport that defines how the data messages are carried.

Dictionaries

DataProducerOptions

Field Type Description Required Default
sctpStreamParameters SctpStreamParameters SCTP parameters defining how the endpoint is sending the data. Yes  
label String A label which can be used to distinguish this DataChannel from others. No  
protocol String Name of the sub-protocol used by this DataChannel. No  
appData Object Custom application data. No { }

Properties

dataProducer.id

Data producer identifier.

@type String, read only

dataProducer.closed

Whether the data producer is closed.

@type Boolean, read only

dataProducer.sctpStreamParameters

The SCTP stream parameters.

@type SctpStreamParameters, read only

dataProducer.label

The data producer label.

@type String , read only

dataProducer.protocol

The data producer sub-protocol.

@type String , read only

dataProducer.appData

Custom data Object provided by the application in the producer factory method. The app can modify its content at any time.

@type Object, read only

dataProducer.observer

See the Observer Events section below.

@type EventEmitter, read only

Methods

dataProducer.close()

Closes the producer. Triggers a “dataproducerclose” event in all its associated consumers.

dataProducer.getStats()

Returns current SCTP statistics of the producer.

@async

@returns Object

Check the SCTP Statistics section for more details.

Events

dataProducer.on(“transportclose”, fn())

Emitted when the transport this data producer belongs to is closed for whatever reason. The producer itself is also closed. A “dataproducerclose” event is triggered in all its associated consumers.

dataProducer.on("transportclose", () =>
{
  console.log("transport closed so dataProducer closed");
});

Observer Events

See the Observer API section below.

dataProducer.observer.on(“close”, fn())

Emitted when the producer is closed for whatever reason.

DataConsumer

A data consumer represents a SCTP data source being forwarded from a mediasoup router to an endpoint. It's created on top of a transport that defines how the data messages are carried.

Dictionaries

DataConsumerOptions

Field Type Description Required Default
producerId String The id of the data producer to consume. Yes  
appData Object Custom application data. No { }

Properties

dataConsumer.id

Data consumer identifier.

@type String, read only

dataConsumer.dataProducerId

The associated data producer identifier.

@type String, read only

dataConsumer.closed

Whether the data consumer is closed.

@type Boolean, read only

dataConsumer.sctpStreamParameters

The SCTP stream parameters.

@type SctpStreamParameters, read only

dataConsumer.label

The data producer label.

@type String , read only

dataConsumer.protocol

The data producer sub-protocol.

@type String , read only

dataConsumer.appData

Custom data Object provided by the application in the data consumer factory method. The app can modify its content at any time.

@type Object, read only

dataConsumer.observer

See the Observer Events section below.

@type EventEmitter, read only

Methods

dataConsumer.close()

Closes the data consumer.

dataConsumer.getStats()

Returns current SCTP statistics of the data consumer.

@async

@returns Object

Check the SCTP Statistics section for more details.

Events

dataConsumer.on(“transportclose”, fn())

Emitted when the transport this data consumer belongs to is closed for whatever reason. The data consumer itself is also closed.

dataConsumer.on("transportclose", () =>
{
  console.log("transport closed so dataConsumer closed");
});

dataConsumer.on(“dataproducerclose”, fn())

Emitted when the associated data producer is closed for whatever reason. The data consumer itself is also closed.

dataConsumer.on("dataproducerclose", () =>
{
  console.log("associated data producer closed so dataConsumer closed");
});

Observer Events

See the Observer API section below.

dataConsumer.observer.on(“close”, fn())

Emitted when the data consumer is closed for whatever reason.

RtpObserver

@abstract

An RTP observer inspects the media received by a set of selected producers.

mediasoup implements the following RTP observer classes:

Properties

These are properties common to all RTP observer classes. Each RTP observer class may define new ones.

rtpObserver.id

RTP observer identifier.

@type String, read only

rtpObserver.closed

Whether the RTP observer is closed.

@type Boolean, read only

rtpObserver.paused

Whether the RTP observer is paused.

@type Boolean, read only

Methods

These are methods common to all RTP observer classes. Each RTP observer class may define new ones.

rtpObserver.close()

Closes the RTP observer.

rtpObserver.pause()

Pauses the RTP observer. No RTP is inspected until resume() is called.

@async

rtpObserver.resume()

Resumes the RTP observer. RTP is inspected again.

@async

rtpObserver.addProducer(producer)

Provides the RTP observer with a new producer to monitor.

Argument Type Description Required Default
producer Producer Producer. Yes  

@async

rtpObserver.removeProducer(producer)

Removes the given producer from the RTP observer.

Argument Type Description Required Default
producer Producer Producer. Yes  

@async

Events

These are events common to all RTP observer classes. Each RTP observer class may define new ones.

rtpObserver.on(“routerclose”)

Emitted when the router this RTP observer belongs to is closed for whatever reason. The RTP observer itself is also closed.

rtpObserver.on("routerclose", () =>
{
  console.log("router closed so RTP observer closed");
});

AudioLevelObserver

@inherits RtpObserver

An audio level observer monitors the volume of the selected audio producers. It just handles audio producers (if addProducer() is called with a video producer it will fail).

Dictionaries

AudioLevelObserverOptions

Field Type Description Required Default
maxEntries Number Maximum number of entries in the “volumes” event. No 1
threshold Number Minimum average volume (in dBvo from -127 to 0) for entries in the “volumes” event. No -80
interval Number Interval in ms for checking audio volumes. No 1000

AudioLevelObserverVolume

Field Type Description Required Default
producer Producer The audio producer instance. Yes  
volume Number The average volume (in dBvo from -127 to 0) of the audio producer in the last interval. Yes  

Properties

See also RtpObserver Properties.

Methods

See also RtpObserver Methods.

Events

See also RtpObserver Events.

audioLevelObserver.on(“volumes”, fn(volumes))

Emitted at most every interval ms (see AudioLevelObserverOptions).

Argument Type Description
volumes Array<AudioLevelObserverVolume> Audio volumes entries ordered by volume (louder ones go first).

Observer API

Most entities in mediasoup expose a observer property (a Node.js EventEmitter) that can be used by third party libraries to monitor everything related to mediasoup.

The observer API should not be directly used by the application itself, but by separate modules or libraries that the application integrate into its code. Such a module or library may, for example, monitor all the creation and closure of workers, routers, transports, etc. It could also monitor events generated by producers and consumers (“pause”, “resume”, “score”, “layerschange”, etc).

Usage example:

const mediasoup = require('mediasoup');

mediasoup.observer.on('newworker', (worker) =>
{
  console.log('new worker created [worke.pid:%d]', worker.pid);

  worker.observer.on('close', () => 
  {
    console.log('worker closed [worker.pid:%d]', worker.pid);
  });

  worker.observer.on('newrouter', (router) =>
  {
    console.log(
      'new router created [worker.pid:%d, router.id:%s]',
      worker.pid, router.id);

    router.observer.on('close', () => 
    {
      console.log('router closed [router.id:%s]', router.id);
    });

    router.observer.on('newtransport', (transport) =>
    {
      console.log(
        'new transport created [worker.pid:%d, router.id:%s, transport.id:%s]',
        worker.pid, router.id, transport.id);

      transport.observer.on('close', () => 
      {
        console.log('transport closed [transport.id:%s]', transport.id);
      });

      transport.observer.on('newproducer', (producer) =>
      {
        console.log(
          'new producer created [worker.pid:%d, router.id:%s, transport.id:%s, producer.id:%s]',
          worker.pid, router.id, transport.id, producer.id);

        producer.observer.on('close', () => 
        {
          console.log('producer closed [producer.id:%s]', producer.id);
        });
      });

      transport.observer.on('newconsumer', (consumer) =>
      {
        console.log(
          'new consumer created [worker.pid:%d, router.id:%s, transport.id:%s, consumer.id:%s]',
          worker.pid, router.id, transport.id, consumer.id);

        consumer.observer.on('close', () => 
        {
          console.log('consumer closed [consumer.id:%s]', consumer.id);
        });
      });

      transport.observer.on('newdataproducer', (dataProducer) =>
      {
        console.log(
          'new data producer created [worker.pid:%d, router.id:%s, transport.id:%s, dataProducer.id:%s]',
          worker.pid, router.id, transport.id, dataProducer.id);

        dataProducer.observer.on('close', () => 
        {
          console.log('data producer closed [dataProducer.id:%s]', dataProducer.id);
        });
      });

      transport.observer.on('newdataconsumer', (dataConsumer) =>
      {
        console.log(
          'new data consumer created [worker.pid:%d, router.id:%s, transport.id:%s, dataConsumer.id:%s]',
          worker.pid, router.id, transport.id, dataConsumer.id);

        dataConsumer.observer.on('close', () => 
        {
          console.log('data consumer closed [dataConsumer.id:%s]', dataConsumer.id);
        });
      });
    });
  });
});