Socket
Socket
Sign inDemoInstall

mediasoup

Package Overview
Dependencies
Maintainers
2
Versions
348
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mediasoup - npm Package Compare versions

Comparing version 3.13.2 to 3.13.3

1

node/lib/Consumer.d.ts

@@ -132,2 +132,3 @@ /// <reference types="node" />

rtp: [Buffer];
listenererror: [string, Error];
'@close': [];

@@ -134,0 +135,0 @@ '@producerclose': [];

12

node/lib/Consumer.js

@@ -218,7 +218,7 @@ "use strict";

logger.debug('pause()');
const wasPaused = this.#paused || this.#producerPaused;
await this.#channel.request(FbsRequest.Method.CONSUMER_PAUSE, undefined, undefined, this.#internal.consumerId);
const wasPaused = this.#paused;
this.#paused = true;
// Emit observer event.
if (!wasPaused) {
if (!wasPaused && !this.#producerPaused) {
this.#observer.safeEmit('pause');

@@ -232,4 +232,4 @@ }

logger.debug('resume()');
const wasPaused = this.#paused || this.#producerPaused;
await this.#channel.request(FbsRequest.Method.CONSUMER_RESUME, undefined, undefined, this.#internal.consumerId);
const wasPaused = this.#paused;
this.#paused = false;

@@ -350,7 +350,6 @@ // Emit observer event.

}
const wasPaused = this.#paused || this.#producerPaused;
this.#producerPaused = true;
this.safeEmit('producerpause');
// Emit observer event.
if (!wasPaused) {
if (!this.#paused) {
this.#observer.safeEmit('pause');

@@ -365,7 +364,6 @@ }

}
const wasPaused = this.#paused || this.#producerPaused;
this.#producerPaused = false;
this.safeEmit('producerresume');
// Emit observer event.
if (wasPaused && !this.#paused) {
if (!this.#paused) {
this.#observer.safeEmit('resume');

@@ -372,0 +370,0 @@ }

@@ -71,2 +71,3 @@ /// <reference types="node" />

bufferedamountlow: [number];
listenererror: [string, Error];
'@close': [];

@@ -73,0 +74,0 @@ '@dataproducerclose': [];

@@ -188,7 +188,7 @@ "use strict";

logger.debug('pause()');
await this.#channel.request(FbsRequest.Method.DATACONSUMER_PAUSE, undefined, undefined, this.#internal.dataConsumerId);
const wasPaused = this.#paused;
await this.#channel.request(FbsRequest.Method.DATACONSUMER_PAUSE, undefined, undefined, this.#internal.dataConsumerId);
this.#paused = true;
// Emit observer event.
if (!wasPaused) {
if (!wasPaused && !this.#dataProducerPaused) {
this.#observer.safeEmit('pause');

@@ -202,7 +202,7 @@ }

logger.debug('resume()');
await this.#channel.request(FbsRequest.Method.DATACONSUMER_RESUME, undefined, undefined, this.#internal.dataConsumerId);
const wasPaused = this.#paused;
await this.#channel.request(FbsRequest.Method.DATACONSUMER_RESUME, undefined, undefined, this.#internal.dataConsumerId);
this.#paused = false;
// Emit observer event.
if (wasPaused) {
if (wasPaused && !this.#dataProducerPaused) {
this.#observer.safeEmit('resume');

@@ -310,7 +310,6 @@ }

}
const wasPaused = this.#paused || this.#dataProducerPaused;
this.#dataProducerPaused = true;
this.safeEmit('dataproducerpause');
// Emit observer event.
if (!wasPaused) {
if (!this.#paused) {
this.#observer.safeEmit('pause');

@@ -325,7 +324,6 @@ }

}
const wasPaused = this.#paused || this.#dataProducerPaused;
this.#dataProducerPaused = false;
this.safeEmit('dataproducerresume');
// Emit observer event.
if (wasPaused && !this.#paused) {
if (!this.#paused) {
this.#observer.safeEmit('resume');

@@ -332,0 +330,0 @@ }

@@ -49,2 +49,3 @@ /// <reference types="node" />

transportclose: [];
listenererror: [string, Error];
'@close': [];

@@ -51,0 +52,0 @@ };

@@ -162,4 +162,4 @@ "use strict";

logger.debug('pause()');
await this.#channel.request(FbsRequest.Method.DATAPRODUCER_PAUSE, undefined, undefined, this.#internal.dataProducerId);
const wasPaused = this.#paused;
await this.#channel.request(FbsRequest.Method.DATAPRODUCER_PAUSE, undefined, undefined, this.#internal.dataProducerId);
this.#paused = true;

@@ -176,4 +176,4 @@ // Emit observer event.

logger.debug('resume()');
await this.#channel.request(FbsRequest.Method.DATAPRODUCER_RESUME, undefined, undefined, this.#internal.dataProducerId);
const wasPaused = this.#paused;
await this.#channel.request(FbsRequest.Method.DATAPRODUCER_RESUME, undefined, undefined, this.#internal.dataProducerId);
this.#paused = false;

@@ -180,0 +180,0 @@ // Emit observer event.

@@ -19,3 +19,2 @@ "use strict";

safeEmit(eventName, ...args) {
const numListeners = super.listenerCount(eventName);
try {

@@ -26,3 +25,9 @@ return super.emit(eventName, ...args);

logger.error('safeEmit() | event listener threw an error [eventName:%s]:%o', eventName, error);
return Boolean(numListeners);
try {
super.emit('listenererror', eventName, error);
}
catch (error2) {
// Ignore it.
}
return Boolean(super.listenerCount(eventName));
}

@@ -29,0 +34,0 @@ }

@@ -104,2 +104,3 @@ /// <reference types="node" />

trace: [ProducerTraceEventData];
listenererror: [string, Error];
'@close': [];

@@ -106,0 +107,0 @@ };

@@ -185,4 +185,4 @@ "use strict";

logger.debug('pause()');
await this.#channel.request(FbsRequest.Method.PRODUCER_PAUSE, undefined, undefined, this.#internal.producerId);
const wasPaused = this.#paused;
await this.#channel.request(FbsRequest.Method.PRODUCER_PAUSE, undefined, undefined, this.#internal.producerId);
this.#paused = true;

@@ -199,4 +199,4 @@ // Emit observer event.

logger.debug('resume()');
await this.#channel.request(FbsRequest.Method.PRODUCER_RESUME, undefined, undefined, this.#internal.producerId);
const wasPaused = this.#paused;
await this.#channel.request(FbsRequest.Method.PRODUCER_RESUME, undefined, undefined, this.#internal.producerId);
this.#paused = false;

@@ -203,0 +203,0 @@ // Emit observer event.

@@ -141,2 +141,3 @@ import { EnhancedEventEmitter } from './EnhancedEventEmitter';

workerclose: [];
listenererror: [string, Error];
'@close': [];

@@ -143,0 +144,0 @@ };

@@ -8,2 +8,3 @@ import { EnhancedEventEmitter } from './EnhancedEventEmitter';

routerclose: [];
listenererror: [string, Error];
'@close': [];

@@ -10,0 +11,0 @@ };

@@ -673,2 +673,6 @@ "use strict";

test('consumer.pause() and resume() succeed', async () => {
const onObserverPause = jest.fn();
const onObserverResume = jest.fn();
audioConsumer.observer.on('pause', onObserverPause);
audioConsumer.observer.on('resume', onObserverResume);
await audioConsumer.pause();

@@ -684,3 +688,30 @@ expect(audioConsumer.paused).toBe(true);

.toMatchObject({ paused: false });
// Even if we don't await for pause()/resume() completion, the observer must
// fire 'pause' and 'resume' events if state was the opposite.
audioConsumer.pause();
audioConsumer.resume();
audioConsumer.pause();
audioConsumer.pause();
audioConsumer.pause();
await audioConsumer.resume();
expect(onObserverPause).toHaveBeenCalledTimes(3);
expect(onObserverResume).toHaveBeenCalledTimes(3);
}, 2000);
test('producer.pause() and resume() emit events', async () => {
const promises = [];
const events = [];
audioConsumer.observer.once('resume', () => {
events.push('resume');
});
audioConsumer.observer.once('pause', () => {
events.push('pause');
});
promises.push(audioProducer.pause());
promises.push(audioProducer.resume());
await Promise.all(promises);
// Must also wait a bit for the corresponding events in the consumer.
await new Promise((resolve) => setTimeout(resolve, 100));
expect(events).toEqual(['pause', 'resume']);
expect(audioConsumer.paused).toBe(false);
}, 2000);
test('consumer.setPreferredLayers() succeed', async () => {

@@ -687,0 +718,0 @@ await audioConsumer.setPreferredLayers({ spatialLayer: 1, temporalLayer: 1 });

@@ -163,2 +163,6 @@ "use strict";

test('dataConsumer.pause() and resume() succeed', async () => {
const onObserverPause = jest.fn();
const onObserverResume = jest.fn();
dataConsumer1.observer.on('pause', onObserverPause);
dataConsumer1.observer.on('resume', onObserverResume);
let data;

@@ -173,3 +177,30 @@ await dataConsumer1.pause();

expect(data.paused).toBe(false);
// Even if we don't await for pause()/resume() completion, the observer must
// fire 'pause' and 'resume' events if state was the opposite.
dataConsumer1.pause();
dataConsumer1.resume();
dataConsumer1.pause();
dataConsumer1.pause();
dataConsumer1.pause();
await dataConsumer1.resume();
expect(onObserverPause).toHaveBeenCalledTimes(3);
expect(onObserverResume).toHaveBeenCalledTimes(3);
}, 2000);
test('dataProducer.pause() and resume() emit events', async () => {
const promises = [];
const events = [];
dataConsumer1.observer.once('resume', () => {
events.push('resume');
});
dataConsumer1.observer.once('pause', () => {
events.push('pause');
});
promises.push(dataProducer.pause());
promises.push(dataProducer.resume());
await Promise.all(promises);
// Must also wait a bit for the corresponding events in the data consumer.
await new Promise((resolve) => setTimeout(resolve, 100));
expect(events).toEqual(['pause', 'resume']);
expect(dataConsumer1.paused).toBe(false);
}, 2000);
test('dataConsumer.close() succeeds', async () => {

@@ -176,0 +207,0 @@ const onObserverClose = jest.fn();

@@ -185,2 +185,6 @@ "use strict";

test('dataProducer.pause() and resume() succeed', async () => {
const onObserverPause = jest.fn();
const onObserverResume = jest.fn();
dataProducer1.observer.on('pause', onObserverPause);
dataProducer1.observer.on('resume', onObserverResume);
let data;

@@ -195,3 +199,28 @@ await dataProducer1.pause();

expect(data.paused).toBe(false);
// Even if we don't await for pause()/resume() completion, the observer must
// fire 'pause' and 'resume' events if state was the opposite.
dataProducer1.pause();
dataProducer1.resume();
dataProducer1.pause();
dataProducer1.pause();
dataProducer1.pause();
await dataProducer1.resume();
expect(onObserverPause).toHaveBeenCalledTimes(3);
expect(onObserverResume).toHaveBeenCalledTimes(3);
}, 2000);
test('producer.pause() and resume() emit events', async () => {
const promises = [];
const events = [];
dataProducer1.observer.once('resume', () => {
events.push('resume');
});
dataProducer1.observer.once('pause', () => {
events.push('pause');
});
promises.push(dataProducer1.pause());
promises.push(dataProducer1.resume());
await Promise.all(promises);
expect(events).toEqual(['pause', 'resume']);
expect(dataProducer1.paused).toBe(false);
}, 2000);
test('dataProducer.close() succeeds', async () => {

@@ -198,0 +227,0 @@ const onObserverClose = jest.fn();

@@ -101,10 +101,15 @@ "use strict";

let recvMessageBytes = 0;
let lastSentMessageId = 0;
let lastRecvMessageId = 0;
let numSentMessages = 0;
let numReceivedMessages = 0;
// eslint-disable-next-line no-async-promise-executor
await new Promise(async (resolve) => {
// Send messages over the sctpSendStream created above.
await new Promise(async (resolve, reject) => {
dataProducer.on('listenererror', (eventName, error) => {
reject(new Error(`dataProducer 'listenererror' [eventName:${eventName}]: ${error}`));
});
dataConsumer.on('listenererror', (eventName, error) => {
reject(new Error(`dataConsumer 'listenererror' [eventName:${eventName}]: ${error}`));
});
sendNextMessage();
async function sendNextMessage() {
const id = ++lastSentMessageId;
const id = ++numSentMessages;
let ppid;

@@ -143,2 +148,3 @@ let message;

dataConsumer.on('message', (message, ppid) => {
++numReceivedMessages;
// message is always a Buffer.

@@ -150,13 +156,14 @@ recvMessageBytes += message.byteLength;

}
if (id < numMessages / 2) {
expect(ppid).toBe(51); // PPID of WebRTC DataChannel string.
// PPID of WebRTC DataChannel string.
else if (id < numMessages / 2 && ppid !== 51) {
reject(new Error(`ppid in message with id ${id} should be 51 but it is ${ppid}`));
}
else {
expect(ppid).toBe(53); // PPID of WebRTC DataChannel binary.
// PPID of WebRTC DataChannel binary.
else if (id > numMessages / 2 && ppid !== 53) {
reject(new Error(`ppid in message with id ${id} should be 53 but it is ${ppid}`));
}
++lastRecvMessageId;
});
});
expect(lastSentMessageId).toBe(numMessages);
expect(lastRecvMessageId).toBe(expectedReceivedNumMessages);
expect(numSentMessages).toBe(numMessages);
expect(numReceivedMessages).toBe(expectedReceivedNumMessages);
expect(recvMessageBytes).toBe(effectivelySentMessageBytes);

@@ -163,0 +170,0 @@ await expect(dataProducer.getStats())

@@ -89,6 +89,10 @@ "use strict";

});
afterAll(() => {
afterAll(async () => {
udpSocket.close();
sctpSocket.end();
worker.close();
// NOTE: For some reason we have to wait a bit for the SCTP stuff to release
// internal things, otherwise Jest reports open handles. We don't care much
// honestly.
await new Promise((resolve) => setTimeout(resolve, 2000));
});

@@ -100,10 +104,11 @@ test('ordered DataProducer delivers all SCTP messages to the DataConsumer', async () => {

let recvMessageBytes = 0;
let lastSentMessageId = 0;
let lastRecvMessageId = 0;
let numSentMessages = 0;
let numReceivedMessages = 0;
// It must be zero because it's the first DataConsumer on the transport.
expect(dataConsumer.sctpStreamParameters?.streamId).toBe(0);
await new Promise((resolve) => {
// Send SCTP messages over the sctpSendStream created above.
const interval = setInterval(() => {
const id = ++lastSentMessageId;
// eslint-disable-next-line no-async-promise-executor
await new Promise(async (resolve, reject) => {
sendNextMessage();
async function sendNextMessage() {
const id = ++numSentMessages;
const data = Buffer.from(String(id));

@@ -122,6 +127,6 @@ // Set ppid of type WebRTC DataChannel string.

sentMessageBytes += data.byteLength;
if (id === numMessages) {
clearInterval(interval);
if (id < numMessages) {
sendNextMessage();
}
}, 10);
}
sctpSocket.on('stream', onStream);

@@ -133,20 +138,26 @@ // Handle the generated SCTP incoming stream and SCTP messages receives on it.

// DataConsumer).
expect(streamId).toBe(0);
if (streamId !== 0) {
reject(new Error(`streamId should be 0 but it is ${streamId}`));
return;
}
// @ts-ignore
stream.on('data', (data) => {
++numReceivedMessages;
recvMessageBytes += data.byteLength;
const id = Number(data.toString('utf8'));
if (id === numMessages) {
clearInterval(interval);
// @ts-ignore
const ppid = data.ppid;
if (id !== numReceivedMessages) {
reject(new Error(`id ${id} in message should match numReceivedMessages ${numReceivedMessages}`));
}
else if (id === numMessages) {
resolve();
}
if (id < numMessages / 2) {
// @ts-ignore
expect(data.ppid).toBe(sctp.PPID.WEBRTC_STRING);
else if (id < numMessages / 2 && ppid !== sctp.PPID.WEBRTC_STRING) {
reject(new Error(`ppid in message with id ${id} should be ${sctp.PPID.WEBRTC_STRING} but it is ${ppid}`));
}
else {
// @ts-ignore
expect(data.ppid).toBe(sctp.PPID.WEBRTC_BINARY);
else if (id > numMessages / 2 && ppid !== sctp.PPID.WEBRTC_BINARY) {
reject(new Error(`ppid in message with id ${id} should be ${sctp.PPID.WEBRTC_BINARY} but it is ${ppid}`));
return;
}
expect(id).toBe(++lastRecvMessageId);
});

@@ -156,4 +167,4 @@ });

expect(onStream).toHaveBeenCalledTimes(1);
expect(lastSentMessageId).toBe(numMessages);
expect(lastRecvMessageId).toBe(numMessages);
expect(numSentMessages).toBe(numMessages);
expect(numReceivedMessages).toBe(numMessages);
expect(recvMessageBytes).toBe(sentMessageBytes);

@@ -160,0 +171,0 @@ await expect(dataProducer.getStats())

@@ -194,9 +194,9 @@ "use strict";

}, 2000);
test.only('transport1.produce() without header extensions and rtcp succeeds', async () => {
test('transport1.produce() without header extensions and rtcp succeeds', async () => {
const onObserverNewProducer = jest.fn();
transport1.observer.once('newproducer', onObserverNewProducer);
audioProducer = await transport1.produce({
const audioProducer2 = await transport1.produce({
kind: 'audio',
rtpParameters: {
mid: 'AUDIO',
mid: 'AUDIO2',
codecs: [

@@ -220,26 +220,14 @@ {

expect(onObserverNewProducer).toHaveBeenCalledTimes(1);
expect(onObserverNewProducer).toHaveBeenCalledWith(audioProducer);
expect(typeof audioProducer.id).toBe('string');
expect(audioProducer.closed).toBe(false);
expect(audioProducer.kind).toBe('audio');
expect(typeof audioProducer.rtpParameters).toBe('object');
expect(audioProducer.type).toBe('simple');
expect(onObserverNewProducer).toHaveBeenCalledWith(audioProducer2);
expect(typeof audioProducer2.id).toBe('string');
expect(audioProducer2.closed).toBe(false);
expect(audioProducer2.kind).toBe('audio');
expect(typeof audioProducer2.rtpParameters).toBe('object');
expect(audioProducer2.type).toBe('simple');
// Private API.
expect(typeof audioProducer.consumableRtpParameters).toBe('object');
expect(audioProducer.paused).toBe(false);
expect(audioProducer.score).toEqual([]);
expect(audioProducer.appData).toEqual({ foo: 1, bar: '2' });
await expect(router.dump())
.resolves
.toMatchObject({
mapProducerIdConsumerIds: [{ key: audioProducer.id, values: [] }],
mapConsumerIdProducerId: []
});
await expect(transport1.dump())
.resolves
.toMatchObject({
id: transport1.id,
producerIds: [audioProducer.id],
consumerIds: []
});
expect(typeof audioProducer2.consumableRtpParameters).toBe('object');
expect(audioProducer2.paused).toBe(false);
expect(audioProducer2.score).toEqual([]);
expect(audioProducer2.appData).toEqual({ foo: 1, bar: '2' });
audioProducer2.close();
}, 2000);

@@ -568,2 +556,6 @@ test('transport1.produce() with wrong arguments rejects with TypeError', async () => {

test('producer.pause() and resume() succeed', async () => {
const onObserverPause = jest.fn();
const onObserverResume = jest.fn();
audioProducer.observer.on('pause', onObserverPause);
audioProducer.observer.on('resume', onObserverResume);
await audioProducer.pause();

@@ -579,3 +571,28 @@ expect(audioProducer.paused).toBe(true);

.toMatchObject({ paused: false });
// Even if we don't await for pause()/resume() completion, the observer must
// fire 'pause' and 'resume' events if state was the opposite.
audioProducer.pause();
audioProducer.resume();
audioProducer.pause();
audioProducer.pause();
audioProducer.pause();
await audioProducer.resume();
expect(onObserverPause).toHaveBeenCalledTimes(3);
expect(onObserverResume).toHaveBeenCalledTimes(3);
}, 2000);
test('producer.pause() and resume() emit events', async () => {
const promises = [];
const events = [];
audioProducer.observer.once('resume', () => {
events.push('resume');
});
audioProducer.observer.once('pause', () => {
events.push('pause');
});
promises.push(audioProducer.pause());
promises.push(audioProducer.resume());
await Promise.all(promises);
expect(events).toEqual(['pause', 'resume']);
expect(audioProducer.paused).toBe(false);
}, 2000);
test('producer.enableTraceEvent() succeed', async () => {

@@ -633,3 +650,6 @@ let dump;

expect(onScore).toHaveBeenCalledTimes(3);
expect(videoProducer.score).toEqual([{ ssrc: 11, score: 10 }, { ssrc: 22, score: 9 }]);
expect(videoProducer.score).toEqual([
{ ssrc: 11, rid: undefined, score: 10, encodingIdx: 0 },
{ ssrc: 22, rid: undefined, score: 9, encodingIdx: 1 }
]);
}, 2000);

@@ -636,0 +656,0 @@ test('producer.close() succeeds', async () => {

@@ -100,2 +100,3 @@ import { EnhancedEventEmitter } from './EnhancedEventEmitter';

trace: [TransportTraceEventData];
listenererror: [string, Error];
'@close': [];

@@ -102,0 +103,0 @@ '@newproducer': [Producer];

@@ -23,2 +23,3 @@ import { EnhancedEventEmitter } from './EnhancedEventEmitter';

workerclose: [];
listenererror: [string, Error];
'@close': [];

@@ -25,0 +26,0 @@ };

@@ -136,2 +136,3 @@ import { EnhancedEventEmitter } from './EnhancedEventEmitter';

died: [Error];
listenererror: [string, Error];
'@success': [];

@@ -138,0 +139,0 @@ '@failure': [Error];

{
"name": "mediasoup",
"version": "3.13.2",
"version": "3.13.3",
"description": "Cutting Edge WebRTC Video Conferencing",

@@ -109,6 +109,6 @@ "contributors": [

"@types/jest": "^29.5.8",
"@types/node": "^20.9.1",
"@types/node": "^20.9.2",
"@typescript-eslint/eslint-plugin": "^6.11.0",
"@typescript-eslint/parser": "^6.11.0",
"eslint": "^8.53.0",
"eslint": "^8.54.0",
"eslint-plugin-jest": "^27.6.0",

@@ -115,0 +115,0 @@ "jest": "^29.7.0",

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc