New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

mediasoup-client

Package Overview
Dependencies
Maintainers
1
Versions
245
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mediasoup-client - npm Package Compare versions

Comparing version 0.3.1 to 0.4.0

2

.eslintrc.js

@@ -120,3 +120,3 @@ module.exports =

'no-multi-str': 2,
'no-multiple-empty-lines': 2,
'no-multiple-empty-lines': [ 2, { max: 1, maxEOF: 0, maxBOF: 0 } ],
'no-native-reassign': 2,

@@ -123,0 +123,0 @@ 'no-negated-in-lhs': 2,

import Logger from './Logger';
import EnhancedEventEmitter from './EnhancedEventEmitter';
import { InvalidStateError } from './errors';

@@ -16,9 +17,7 @@ const logger = new Logger('Consumer');

*
* @emits {[appData]: Any} @pause
* @emits {[appData]: Any} @resume
* @emits {originator: String} @close
* @emits @close
*/
constructor(id, kind, rtpParameters, peer, appData)
{
super();
super(logger);

@@ -53,5 +52,5 @@ // Id.

// Whether this Consumer is being handled by a Transport.
// @type {Boolean}
this._handled = false;
// Associated Transport.
// @type {Transport}
this._transport = null;

@@ -72,12 +71,2 @@ // Remote track.

/**
* Class name.
*
* @return {String}
*/
get klass()
{
return 'Consumer';
}
/**
* Consumer id.

@@ -153,9 +142,9 @@ *

/**
* Whether this is being handled by a Transport.
* Associated Transport.
*
* @return {Boolean}
* @return {Transport}
*/
get handled()
get transport()
{
return Boolean(this._handled);
return this._transport;
}

@@ -210,3 +199,3 @@

{
return (!this._closed && this.handled === true && !this.paused);
return (!this._closed && this._transport === true && !this.paused);
}

@@ -229,3 +218,3 @@

this.emit('@close', 'local');
this.emit('@close');
this.safeEmit('close', 'local');

@@ -253,6 +242,8 @@

this.emit('@close', 'remote');
this.safeEmit('close', 'remote', appData);
if (this._transport)
this._transport.removeConsumer(this, appData);
this._destroy();
this.safeEmit('close', 'remote', appData);
}

@@ -262,3 +253,3 @@

{
this._handled = false;
this._transport = null;

@@ -272,2 +263,52 @@ try { this._track.stop(); }

/**
* Receives RTP.
*
* @param {transport} Transport instance.
*
* @return {Promise} Resolves with a remote MediaStreamTrack.
*/
receive(transport)
{
logger.debug('receive() [transport:%o]', transport);
if (this._closed)
return Promise.reject(new InvalidStateError('Consumer closed'));
else if (!this._supported)
return Promise.reject(new Error('unsupported codecs'));
else if (this._transport)
return Promise.reject(new Error('already handled by a Transport'));
else if (typeof transport !== 'object')
return Promise.reject(new TypeError('invalid Transport'));
this._transport = transport;
return transport.addConsumer(this)
.then((track) =>
{
transport.once('@close', () =>
{
if (this._closed || this._transport !== transport)
return;
this._transport = null;
try { this._track.stop(); }
catch (error) {}
this._track = null;
this.safeEmit('unhandled');
});
this.safeEmit('handled');
return track;
})
.catch((error) =>
{
this._transport = null;
throw error;
});
}
/**
* Pauses receiving media.

@@ -294,2 +335,5 @@ *

if (this._transport)
this._transport.pauseConsumer(this, appData);
this._locallyPaused = true;

@@ -300,5 +344,2 @@

if (this._handled)
this.emit('@pause', appData);
this.safeEmit('pause', 'local', appData);

@@ -355,2 +396,5 @@

if (this._transport)
this._transport.resumeConsumer(this, appData);
this._locallyPaused = false;

@@ -361,5 +405,2 @@

if (this._handled)
this.emit('@resume', appData);
this.safeEmit('resume', 'local', appData);

@@ -407,33 +448,12 @@

/**
* Set this Consumer as handled or unhandled by a Transport.
* Set remote MediaStreamTrack.
*
* @private
*
* @param {Boolean|String} flag - If 'tmp' it's considered temporal.
* @param {track} MediaStreamTrack
* @param {MediaStreamTrack} track
*/
setHandled(flag, track)
setTrack(track)
{
if (this._closed)
return;
const previous = this._handled;
this._handled = flag;
this._track = track || null;
if (track && this.paused)
this._track.enabled = false;
if (flag === false || flag === 'tmp')
{
try { this._track.stop(); }
catch (error) {}
this._track = null;
}
if (previous === true && flag === false)
this.safeEmit('unhandled');
this._track = track;
}
}
import { EventEmitter } from 'events';
import Logger from './Logger';
const logger = new Logger('EnhancedEventEmitter');
export default class EnhancedEventEmitter extends EventEmitter
{
constructor()
constructor(logger)
{
super();
this.setMaxListeners(Infinity);
this._logger = logger || new Logger('EnhancedEventEmitter');
}

@@ -22,3 +22,4 @@

{
logger.error('event listener threw an error [event:%s]: %o',
this._logger.error(
'safeEmit() | event listener threw an error [event:%s]:%o',
event, error);

@@ -28,3 +29,3 @@ }

safeEmitAsPromise(...args)
safeEmitAsPromise(event, ...args)
{

@@ -40,8 +41,12 @@ return new Promise((resolve, reject) =>

{
this._logger.error(
'safeEmitAsPromise() | errback called [event:%s]:%o',
event, error);
reject(error);
};
this.safeEmit(...args, callback, errback);
this.safeEmit(event, ...args, callback, errback);
});
}
}

@@ -15,3 +15,3 @@ import sdpTransform from 'sdp-transform';

{
super();
super(logger);

@@ -18,0 +18,0 @@ // RTCPeerConnection instance.

@@ -28,2 +28,4 @@ /* global RTCIceGatherer, RTCIceTransport, RTCDtlsTransport, RTCRtpReceiver, RTCRtpSender */

{
super(logger);
logger.debug(

@@ -33,4 +35,2 @@ 'constructor() [direction:%s, extendedRtpCapabilities:%o]',

super();
// Generic sending RTP parameters for audio and video.

@@ -37,0 +37,0 @@ // @type {Object}

@@ -15,3 +15,3 @@ import sdpTransform from 'sdp-transform';

{
super();
super(logger);

@@ -178,4 +178,6 @@ // RTCPeerConnection instance.

// at least a fake-active sending track.
if (this._stream.getTracks().length === 0)
return;
// NOTE: This does not fix the problem.
// ISSUE: https://github.com/versatica/mediasoup-client/issues/2
// if (this._stream.getTracks().length === 0)
// return;

@@ -188,4 +190,6 @@ return Promise.resolve()

{
if (this._pc.signalingState === 'stable')
return;
// TODO: This may be removed.
// ISSUE: https://github.com/versatica/mediasoup-client/issues/2
// if (this._pc.signalingState === 'stable')
// return;

@@ -192,0 +196,0 @@ const localSdpObj = sdpTransform.parse(this._pc.localDescription.sdp);

@@ -34,2 +34,9 @@ /* global RTCRtpReceiver */

codec.parameters.apt = Number(codec.parameters.apt);
// Delete emty parameter String in rtcpFeedback.
for (const feedback of codec.rtcpFeedback || [])
{
if (!feedback.parameter)
delete feedback.parameter;
}
}

@@ -36,0 +43,0 @@

@@ -15,3 +15,3 @@ import sdpTransform from 'sdp-transform';

{
super();
super(logger);

@@ -18,0 +18,0 @@ // RTCPeerConnection instance.

@@ -95,5 +95,8 @@ import sdpTransform from 'sdp-transform';

type : fb.type,
parameter : fb.subtype || ''
parameter : fb.subtype
};
if (!feedback.parameter)
delete feedback.parameter;
codec.rtcpFeedback.push(feedback);

@@ -100,0 +103,0 @@ }

@@ -68,3 +68,2 @@ import sdpTransform from 'sdp-transform';

const localDtlsParameters = this._transportLocalParameters.dtlsParameters;
const remoteIceParameters = this._transportRemoteParameters.iceParameters;

@@ -107,6 +106,9 @@ const remoteIceCandidates = this._transportRemoteParameters.iceCandidates;

// NOTE: We take the latest fingerprint.
const numFingerprints = remoteDtlsParameters.fingerprints.length;
sdpObj.fingerprint =
{
type : remoteDtlsParameters.fingerprints[0].algorithm,
hash : remoteDtlsParameters.fingerprints[0].value
type : remoteDtlsParameters.fingerprints[numFingerprints - 1].algorithm,
hash : remoteDtlsParameters.fingerprints[numFingerprints - 1].value
};

@@ -156,3 +158,3 @@

switch (localDtlsParameters.role)
switch (remoteDtlsParameters.role)
{

@@ -225,3 +227,3 @@ case 'client':

type : fb.type,
subtype : fb.parameter
subtype : fb.parameter || ''
});

@@ -318,6 +320,9 @@ }

// NOTE: We take the latest fingerprint.
const numFingerprints = remoteDtlsParameters.fingerprints.length;
sdpObj.fingerprint =
{
type : remoteDtlsParameters.fingerprints[0].algorithm,
hash : remoteDtlsParameters.fingerprints[0].value
type : remoteDtlsParameters.fingerprints[numFingerprints - 1].algorithm,
hash : remoteDtlsParameters.fingerprints[numFingerprints - 1].value
};

@@ -419,3 +424,3 @@

type : fb.type,
subtype : fb.parameter
subtype : fb.parameter || ''
});

@@ -422,0 +427,0 @@ }

@@ -68,3 +68,2 @@ import sdpTransform from 'sdp-transform';

const localDtlsParameters = this._transportLocalParameters.dtlsParameters;
const remoteIceParameters = this._transportRemoteParameters.iceParameters;

@@ -113,6 +112,9 @@ const remoteIceCandidates = this._transportRemoteParameters.iceCandidates;

// NOTE: We take the latest fingerprint.
const numFingerprints = remoteDtlsParameters.fingerprints.length;
sdpObj.fingerprint =
{
type : remoteDtlsParameters.fingerprints[0].algorithm,
hash : remoteDtlsParameters.fingerprints[0].value
type : remoteDtlsParameters.fingerprints[numFingerprints - 1].algorithm,
hash : remoteDtlsParameters.fingerprints[numFingerprints - 1].value
};

@@ -163,3 +165,3 @@

switch (localDtlsParameters.role)
switch (remoteDtlsParameters.role)
{

@@ -232,3 +234,3 @@ case 'client':

type : fb.type,
subtype : fb.parameter
subtype : fb.parameter || ''
});

@@ -335,6 +337,9 @@ }

// NOTE: We take the latest fingerprint.
const numFingerprints = remoteDtlsParameters.fingerprints.length;
sdpObj.fingerprint =
{
type : remoteDtlsParameters.fingerprints[0].algorithm,
hash : remoteDtlsParameters.fingerprints[0].value
type : remoteDtlsParameters.fingerprints[numFingerprints - 1].algorithm,
hash : remoteDtlsParameters.fingerprints[numFingerprints - 1].value
};

@@ -439,3 +444,3 @@

type : fb.type,
subtype : fb.parameter
subtype : fb.parameter || ''
});

@@ -442,0 +447,0 @@ }

@@ -14,7 +14,7 @@ import Logger from './Logger';

*
* @emits {originator: String} @close
* @emits @close
*/
constructor(name, appData)
{
super();
super(logger);

@@ -93,3 +93,3 @@ // Name.

this.emit('@close', 'local');
this.emit('@close');
this.safeEmit('close', 'local');

@@ -121,3 +121,3 @@

this.emit('@close', 'remote');
this.emit('@close');
this.safeEmit('close', 'remote', appData);

@@ -124,0 +124,0 @@

@@ -18,4 +18,2 @@ import Logger from './Logger';

*
* @emits {[appData]: Any} @pause
* @emits {[appData]: Any} @resume
* @emits {originator: String, [appData]: Any} @close

@@ -26,3 +24,3 @@ *

{
super();
super(logger);

@@ -49,5 +47,5 @@ // Id.

// Whether this Producer is being handled by a Transport.
// @type {Boolean}
this._handled = false;
// Associated Transport.
// @type {Transport}
this._transport = null;

@@ -68,12 +66,2 @@ // RTP parameters.

/**
* Class name.
*
* @return {String}
*/
get klass()
{
return 'Producer';
}
/**
* Producer id.

@@ -139,9 +127,9 @@ *

/**
* Whether this is being handled by a Transport.
* Associated Transport.
*
* @return {Boolean}
* @return {Transport}
*/
get handled()
get transport()
{
return Boolean(this._handled);
return this._transport;
}

@@ -196,3 +184,3 @@

{
return (!this._closed && this.handled === true && !this.paused);
return (!this._closed && this._transport === true && !this.paused);
}

@@ -214,6 +202,12 @@

if (this._transport)
{
this._transport.removeProducer(
this, appData, { locallyClosed: true });
}
this._destroy();
this.emit('@close', 'local', appData);
this.safeEmit('close', 'local', appData);
this._destroy();
}

@@ -238,6 +232,12 @@

if (this._transport)
{
this._transport.removeProducer(
this, appData, { locallyClosed: false });
}
this._destroy();
this.emit('@close', 'remote', appData);
this.safeEmit('close', 'remote', appData);
this._destroy();
}

@@ -247,4 +247,3 @@

{
this._closed = true;
this._handled = false;
this._transport = false;
this._rtpParameters = null;

@@ -257,2 +256,46 @@

/**
* Sends RTP.
*
* @param {transport} Transport instance.
*
* @return {Promise}
*/
send(transport)
{
logger.debug('send() [transport:%o]', transport);
if (this._closed)
return Promise.reject(new InvalidStateError('Producer closed'));
else if (this._transport)
return Promise.reject(new Error('already handled by a Transport'));
else if (typeof transport !== 'object')
return Promise.reject(new TypeError('invalid Transport'));
this._transport = transport;
return transport.addProducer(this)
.then(() =>
{
transport.once('@close', () =>
{
if (this._closed || this._transport !== transport)
return;
this._transport = null;
this._rtpParameters = null;
this.safeEmit('unhandled');
});
this.safeEmit('handled');
})
.catch((error) =>
{
this._transport = null;
throw error;
});
}
/**
* Pauses sending media.

@@ -279,8 +322,8 @@ *

if (this._transport)
this._transport.pauseProducer(this, appData);
this._locallyPaused = true;
this._track.enabled = false;
if (this._handled)
this.emit('@pause', appData);
this.safeEmit('pause', 'local', appData);

@@ -335,2 +378,5 @@

if (this._transport)
this._transport.resumeProducer(this, appData);
this._locallyPaused = false;

@@ -341,5 +387,2 @@

if (this._handled)
this.emit('@resume', appData);
this.safeEmit('resume', 'local', appData);

@@ -397,4 +440,4 @@

// the new track.
if (this._handled)
return this.safeEmitAsPromise('@replacetrack', track);
if (this._transport)
return this._transport.replaceProducerTrack(this, track);
})

@@ -407,5 +450,11 @@ .then(() =>

// If this Producer was locally paused/resumed and the state of the new
// track does not match, fix it.
if (this.paused && track.enabled)
track.enabled = false;
else if (!this.paused && !track.enabled)
track.enabled = true;
// Set the new track.
this._track = track;
this._locallyPaused = !track.enabled;

@@ -418,37 +467,12 @@ // Return the new track.

/**
* Set this Producer as handled or unhandled by a Transport.
* Set/update RTP parameters.
*
* @private
*
* @param {Boolean|String} flag - If 'tmp' it's considered temporal.
* @param {RTCRtpParameters} rtpParameters
*/
setHandled(flag, rtpParameters)
setRtpParameters(rtpParameters)
{
if (this._closed)
return;
const previous = this._handled;
this._handled = flag;
this._rtpParameters = rtpParameters;
if (flag === false || flag === 'tmp')
this._rtpParameters = null;
if (previous === true && flag === false)
this.safeEmit('unhandled');
}
/**
* Update RTP parameters.
*
* @private
*
* @param {RTCRtpParameters} rtpParameters
*/
updateRtpParameters(rtpParameters)
{
this._rtpParameters = rtpParameters;
}
}

@@ -48,6 +48,6 @@ import Logger from './Logger';

{
super(logger);
logger.debug('constructor() [options:%o]', options);
super();
if (!Device.isSupported())

@@ -518,189 +518,189 @@ throw new Error('current browser/device not supported');

{
try
{
if (this.closed)
throw new InvalidStateError('Room closed');
else if (typeof notification !== 'object')
throw new TypeError('wrong notification Object');
else if (notification.notification !== true)
throw new TypeError('not a notification');
else if (typeof notification.method !== 'string')
throw new TypeError('wrong/missing notification method');
if (this.closed)
return Promise.reject(new InvalidStateError('Room closed'));
else if (typeof notification !== 'object')
return Promise.reject(new TypeError('wrong notification Object'));
else if (notification.notification !== true)
return Promise.reject(new TypeError('not a notification'));
else if (typeof notification.method !== 'string')
return Promise.reject(new TypeError('wrong/missing notification method'));
const method = notification.method;
const { method } = notification;
logger.debug(
'receiveNotification() [method:%s, notification:%o]',
method, notification);
logger.debug(
'receiveNotification() [method:%s, notification:%o]',
method, notification);
switch (method)
return Promise.resolve()
.then(() =>
{
case 'closed':
switch (method)
{
const { appData } = notification;
case 'closed':
{
const { appData } = notification;
this.remoteClose(appData);
this.remoteClose(appData);
break;
}
break;
}
case 'transportClosed':
{
const { id, appData } = notification;
const transport = this._transports.get(id);
case 'transportClosed':
{
const { id, appData } = notification;
const transport = this._transports.get(id);
if (!transport)
throw new Error(`Transport does not exist [id:"${id}"]`);
if (!transport)
throw new Error(`Transport does not exist [id:"${id}"]`);
transport.remoteClose(appData);
transport.remoteClose(appData);
break;
}
break;
}
case 'newPeer':
{
const { name } = notification;
case 'newPeer':
{
const { name } = notification;
if (this._peers.has(name))
throw new Error(`Peer already exists [name:"${name}"]`);
if (this._peers.has(name))
throw new Error(`Peer already exists [name:"${name}"]`);
const peerData = notification;
const peerData = notification;
this._handlePeerData(peerData);
this._handlePeerData(peerData);
break;
}
break;
}
case 'peerClosed':
{
const peerName = notification.name;
const { appData } = notification;
const peer = this._peers.get(peerName);
case 'peerClosed':
{
const peerName = notification.name;
const { appData } = notification;
const peer = this._peers.get(peerName);
if (!peer)
throw new Error(`no Peer found [name:"${peerName}"]`);
if (!peer)
throw new Error(`no Peer found [name:"${peerName}"]`);
peer.remoteClose(appData);
peer.remoteClose(appData);
break;
}
break;
}
case 'producerClosed':
{
const { id, appData } = notification;
const producer = this._producers.get(id);
case 'producerClosed':
{
const { id, appData } = notification;
const producer = this._producers.get(id);
if (!producer)
throw new Error(`Producer not found [id:${id}]`);
if (!producer)
throw new Error(`Producer not found [id:${id}]`);
producer.remoteClose(appData);
producer.remoteClose(appData);
break;
}
break;
}
case 'producerPaused':
{
const { id, appData } = notification;
const producer = this._producers.get(id);
case 'producerPaused':
{
const { id, appData } = notification;
const producer = this._producers.get(id);
if (!producer)
throw new Error(`Producer not found [id:${id}]`);
if (!producer)
throw new Error(`Producer not found [id:${id}]`);
producer.remotePause(appData);
producer.remotePause(appData);
break;
}
break;
}
case 'producerResumed':
{
const { id, appData } = notification;
const producer = this._producers.get(id);
case 'producerResumed':
{
const { id, appData } = notification;
const producer = this._producers.get(id);
if (!producer)
throw new Error(`Producer not found [id:${id}]`);
if (!producer)
throw new Error(`Producer not found [id:${id}]`);
producer.remoteResume(appData);
producer.remoteResume(appData);
break;
}
break;
}
case 'newConsumer':
{
const { peerName } = notification;
const peer = this._peers.get(peerName);
case 'newConsumer':
{
const { peerName } = notification;
const peer = this._peers.get(peerName);
if (!peer)
throw new Error(`no Peer found [name:"${peerName}"]`);
if (!peer)
throw new Error(`no Peer found [name:"${peerName}"]`);
const consumerData = notification;
const consumerData = notification;
this._handleConsumerData(consumerData, peer);
this._handleConsumerData(consumerData, peer);
break;
}
break;
}
case 'consumerClosed':
{
const { id, peerName, appData } = notification;
const peer = this._peers.get(peerName);
case 'consumerClosed':
{
const { id, peerName, appData } = notification;
const peer = this._peers.get(peerName);
if (!peer)
throw new Error(`no Peer found [name:"${peerName}"]`);
if (!peer)
throw new Error(`no Peer found [name:"${peerName}"]`);
const consumer = peer.getConsumerById(id);
const consumer = peer.getConsumerById(id);
if (!consumer)
throw new Error(`Consumer not found [id:${id}]`);
if (!consumer)
throw new Error(`Consumer not found [id:${id}]`);
consumer.remoteClose(appData);
consumer.remoteClose(appData);
break;
}
break;
}
case 'consumerPaused':
{
const { id, peerName, appData } = notification;
const peer = this._peers.get(peerName);
case 'consumerPaused':
{
const { id, peerName, appData } = notification;
const peer = this._peers.get(peerName);
if (!peer)
throw new Error(`no Peer found [name:"${peerName}"]`);
if (!peer)
throw new Error(`no Peer found [name:"${peerName}"]`);
const consumer = peer.getConsumerById(id);
const consumer = peer.getConsumerById(id);
if (!consumer)
throw new Error(`Consumer not found [id:${id}]`);
if (!consumer)
throw new Error(`Consumer not found [id:${id}]`);
consumer.remotePause(appData);
consumer.remotePause(appData);
break;
}
break;
}
case 'consumerResumed':
{
const { id, peerName, appData } = notification;
const peer = this._peers.get(peerName);
case 'consumerResumed':
{
const { id, peerName, appData } = notification;
const peer = this._peers.get(peerName);
if (!peer)
throw new Error(`no Peer found [name:"${peerName}"]`);
if (!peer)
throw new Error(`no Peer found [name:"${peerName}"]`);
const consumer = peer.getConsumerById(id);
const consumer = peer.getConsumerById(id);
if (!consumer)
throw new Error(`Consumer not found [id:${id}]`);
if (!consumer)
throw new Error(`Consumer not found [id:${id}]`);
consumer.remoteResume(appData);
consumer.remoteResume(appData);
break;
break;
}
default:
throw new Error(`unknown notification method "${method}"`);
}
default:
throw new Error(`unknown notification method "${method}"`);
}
}
catch (error)
{
logger.error(
'receiveNotification() failed [notification:%o]: %s',
notification, error.toString());
}
})
.catch((error) =>
{
logger.error(
'receiveNotification() failed [notification:%o]: %s', notification, error);
});
}

@@ -762,3 +762,3 @@

const errback = (message) =>
const errback = (error) =>
{

@@ -781,9 +781,9 @@ if (done)

// Make sure message is a String.
message = String(message);
// Make sure message is an Error.
if (!(error instanceof Error))
error = new Error(String(error));
logger.error(
'request failed [method:%s]: %s', method, message);
logger.error('request failed [method:%s]:%o', method, error);
reject(new Error(message));
reject(error);
};

@@ -790,0 +790,0 @@

import Logger from './Logger';
import EnhancedEventEmitter from './EnhancedEventEmitter';
import { InvalidStateError } from './errors';
import * as utils from './utils';

@@ -19,11 +20,11 @@ import Device from './Device';

* @emits {method: String, [data]: Object} @notify
* @emits {originator: String} @close
* @emits @close
*/
constructor(direction, extendedRtpCapabilities, settings, appData)
{
super(logger);
logger.debug('constructor() [direction:%s, extendedRtpCapabilities:%o]',
direction, extendedRtpCapabilities);
super();
// Id.

@@ -49,10 +50,2 @@ // @type {Number}

// Map of Producers indexed by id.
// @type {map<Number, Producer>}
this._producers = new Map();
// Map of Consumers indexed by id.
// @type {map<Number, Consumer>}
this._consumers = new Map();
// Commands handler.

@@ -71,2 +64,3 @@ // @type {CommandQueue}

this._commandQueue.on('exec', this._execCommand.bind(this));
this._handleHandler();

@@ -142,3 +136,3 @@ }

this.emit('@close', 'local');
this.emit('@close');
this.safeEmit('close', 'local', appData);

@@ -153,2 +147,4 @@

*
* @private
*
* @param {Any} [appData] - App custom data.

@@ -165,3 +161,3 @@ */

this.emit('@close', 'remote');
this.emit('@close');
this.safeEmit('close', 'remote', appData);

@@ -179,68 +175,4 @@

this._handler.close();
// Unhandle all the Producers.
for (const producer of this._producers.values())
{
producer.setHandled(false);
}
// Unhandle all the Consumers.
for (const consumer of this._consumers.values())
{
consumer.setHandled(false);
}
}
/**
* Send the given Producer over this Transport.
*
* @param {Producer} producer
*
* @return {Promise}
*
* @example
* transport.send(videoProducer)
* .then(() => {
* // Done
* });
*/
send(producer)
{
logger.debug('send() [producer:%o]', producer);
if (this._direction !== 'send')
return Promise.reject(new Error('cannot send on a receiving Transport'));
else if (!producer || producer.klass !== 'Producer')
return Promise.reject(new TypeError('wrong Producer'));
// Enqueue command.
return this._commandQueue.push('addProducer', { producer });
}
/**
* Receive the given Consumer over this Transport.
*
* @param {Consumer} consumer
*
* @return {Promise}
*
* @example
* transport.receive(aliceVideoConsumer)
* .then(() => {
* // Done
* });
*/
receive(consumer)
{
logger.debug('receive() [consumer:%o]', consumer);
if (this._direction !== 'recv')
return Promise.reject(new Error('cannot receive on a sending Transport'));
else if (!consumer || consumer.klass !== 'Consumer')
return Promise.reject(new TypeError('wrong Consumer'));
// Enqueue command.
return this._commandQueue.push('addConsumer', { consumer });
}
_handleHandler()

@@ -255,2 +187,4 @@ {

logger.debug('Transport connection state changed to %s', state);
this._connectionState = state;

@@ -300,3 +234,3 @@

// Update Producer RTP parameters.
producer.updateRtpParameters(rtpParameters);
producer.setRtpParameters(rtpParameters);

@@ -308,2 +242,150 @@ // Notify the server.

/**
* Send the given Producer over this Transport.
*
* @private
*
* @param {Producer} producer
*
* @return {Promise}
*/
addProducer(producer)
{
logger.debug('addProducer() [producer:%o]', producer);
if (this._closed)
return Promise.reject(new InvalidStateError('Transport closed'));
if (this._direction !== 'send')
return Promise.reject(new Error('not a sending Transport'));
// Enqueue command.
return this._commandQueue.push('addProducer', { producer });
}
/**
* @private
*/
removeProducer(producer, appData, { locallyClosed })
{
logger.debug('removeProducer() [producer:%o]', producer);
// Enqueue command.
this._commandQueue.push('removeProducer', { producer })
.catch(() => {});
if (locallyClosed)
this.safeEmit('@notify', 'closeProducer', { id: producer.id, appData });
}
/**
* @private
*/
pauseProducer(producer, appData)
{
logger.debug('pauseProducer() [producer:%o]', producer);
const data =
{
id : producer.id,
appData : appData
};
this.safeEmit('@notify', 'pauseProducer', data);
}
/**
* @private
*/
resumeProducer(producer, appData)
{
logger.debug('resumeProducer() [producer:%o]', producer);
const data =
{
id : producer.id,
appData : appData
};
this.safeEmit('@notify', 'resumeProducer', data);
}
/**
* @private
*
* @return {Promise}
*/
replaceProducerTrack(producer, track)
{
logger.debug('replaceProducerTrack() [producer:%o]', producer);
return this._commandQueue.push(
'replaceProducerTrack', { producer, track });
}
/**
* Receive the given Consumer over this Transport.
*
* @private
*
* @param {Consumer} consumer
*
* @return {Promise} Resolves to a remote MediaStreamTrack.
*/
addConsumer(consumer)
{
logger.debug('addConsumer() [consumer:%o]', consumer);
if (this._closed)
return Promise.reject(new InvalidStateError('Transport closed'));
if (this._direction !== 'recv')
return Promise.reject(new Error('not a receiving Transport'));
// Enqueue command.
return this._commandQueue.push('addConsumer', { consumer });
}
/**
* @private
*/
removeConsumer(consumer)
{
logger.debug('removeConsumer() [consumer:%o]', consumer);
// Enqueue command.
this._commandQueue.push('removeConsumer', { consumer })
.catch(() => {});
}
/**
* @private
*/
pauseConsumer(consumer, appData)
{
logger.debug('pauseConsumer() [consumer:%o]', consumer);
const data =
{
id : consumer.id,
appData : appData
};
this.safeEmit('@notify', 'pauseConsumer', data);
}
/**
* @private
*/
resumeConsumer(consumer, appData)
{
logger.debug('resumeConsumer() [consumer:%o]', consumer);
const data =
{
id : consumer.id,
appData : appData
};
this.safeEmit('@notify', 'resumeConsumer', data);
}
_execCommand(command, promiseHolder)

@@ -377,11 +459,4 @@ {

if (producer.closed)
return Promise.reject(new Error('Producer closed'));
else if (producer.handled)
return Promise.reject(new Error('Producer already handled by a Transport'));
let producerRtpParameters;
producer.setHandled('tmp');
// Call the handler.

@@ -411,11 +486,3 @@ return Promise.resolve()

{
producer.setHandled(true, producerRtpParameters);
this._producers.set(producer.id, producer);
this._handleProducer(producer);
})
.catch((error) =>
{
producer.setHandled(false);
throw error;
producer.setRtpParameters(producerRtpParameters);
});

@@ -444,18 +511,4 @@ }

if (consumer.closed)
return Promise.reject(new Error('Consumer closed'));
else if (consumer.handled)
return Promise.reject(new Error('Consumer already handled by a Transport'));
// Check whether we can receive this Consumer.
if (!consumer.supported)
{
return Promise.reject(
new Error('cannot receive this Consumer, unsupported codecs'));
}
let consumerTrack;
consumer.setHandled('tmp');
// Call the handler.

@@ -473,4 +526,5 @@ return Promise.resolve()

{
id : consumer.id,
paused : consumer.locallyPaused
id : consumer.id,
transportId : this.id,
paused : consumer.locallyPaused
};

@@ -482,13 +536,3 @@

{
consumer.setHandled(true, consumerTrack);
this._consumers.set(consumer.id, consumer);
this._handleConsumer(consumer);
return consumerTrack;
})
.catch((error) =>
{
consumer.setHandled(false);
throw error;
consumer.setTrack(consumerTrack);
});

@@ -504,84 +548,2 @@ }

}
_handleProducer(producer)
{
producer.on('@close', (originator, appData) =>
{
this._producers.delete(producer.id);
// Enqueue command.
this._commandQueue.push('removeProducer', { producer })
.catch(() => {});
if (originator === 'local')
{
this.safeEmit(
'@notify', 'closeProducer', { id: producer.id, appData });
}
});
producer.on('@pause', (appData) =>
{
const data =
{
id : producer.id,
appData : appData
};
this.safeEmit('@notify', 'pauseProducer', data);
});
producer.on('@resume', (appData) =>
{
const data =
{
id : producer.id,
appData : appData
};
this.safeEmit('@notify', 'resumeProducer', data);
});
producer.on('@replacetrack', (track, callback, errback) =>
{
// Enqueue command.
return this._commandQueue.push('replaceProducerTrack', { producer, track })
.then(callback)
.catch(errback);
});
}
_handleConsumer(consumer)
{
consumer.on('@close', () =>
{
this._consumers.delete(consumer.id);
// Enqueue command.
this._commandQueue.push('removeConsumer', { consumer })
.catch(() => {});
});
consumer.on('@pause', (appData) =>
{
const data =
{
id : consumer.id,
appData : appData
};
this.safeEmit('@notify', 'pauseConsumer', data);
});
consumer.on('@resume', (appData) =>
{
const data =
{
id : consumer.id,
appData : appData
};
this.safeEmit('@notify', 'resumeConsumer', data);
});
}
}

@@ -172,7 +172,8 @@ import randomNumberLib from 'random-number';

{
name : 'rtx',
mimeType : `${capCodec.kind}/rtx`,
clockRate : capCodec.clockRate,
payloadType : capCodec.recvRtxPayloadType,
parameters :
name : 'rtx',
mimeType : `${capCodec.kind}/rtx`,
kind : capCodec.kind,
clockRate : capCodec.clockRate,
preferredPayloadType : capCodec.recvRtxPayloadType,
parameters :
{

@@ -179,0 +180,0 @@ apt : capCodec.recvPayloadType

@@ -250,2 +250,3 @@ # mediasoup protocol

id: 3333,
transportId: 9999,
paused: false

@@ -332,5 +333,5 @@ }

### newPeer
### producerClosed
A new `Peer` has joined the server-side `Room`.
A server-side `Producer` has been closed in the server.

@@ -341,15 +342,5 @@ Notification:

{
method: 'newPeer',
method: 'producerClosed',
notification: true,
name: 'alice',
consumers:
[
{
id: 5555,
kind: 'audio',
rtpParameters: {},
paused: false,
appData: Any
}
],
id: 2222,
appData: Any

@@ -360,5 +351,5 @@ }

### peerClosed
### producerPaused
A server-side `Peer` has been closed (it may have left the room or his server-side `Peer` has been closed in the server).
A server-side `Producer` has been paused in the server.

@@ -369,5 +360,5 @@ Notification:

{
method: 'peerClosed',
method: 'producerPaused',
notification: true,
name: 'alice',
id: 2222,
appData: Any

@@ -378,5 +369,5 @@ }

### producerClosed
### producerResumed
A server-side `Producer` has been closed in the server.
A server-side `Producer` has been resumed in the server.

@@ -387,3 +378,3 @@ Notification:

{
method: 'producerClosed',
method: 'producerResumed',
notification: true,

@@ -396,5 +387,5 @@ id: 2222,

### producerPaused
### newPeer
A server-side `Producer` has been paused in the server.
A new `Peer` has joined the server-side `Room`.

@@ -405,5 +396,15 @@ Notification:

{
method: 'producerPaused',
method: 'newPeer',
notification: true,
id: 2222,
name: 'alice',
consumers:
[
{
id: 5555,
kind: 'audio',
rtpParameters: {},
paused: false,
appData: Any
}
],
appData: Any

@@ -414,5 +415,5 @@ }

### producerResumed
### peerClosed
A server-side `Producer` has been resumed in the server.
A server-side `Peer` has been closed (it may have left the room or his server-side `Peer` has been closed in the server).

@@ -423,5 +424,5 @@ Notification:

{
method: 'producerResumed',
method: 'peerClosed',
notification: true,
id: 2222,
name: 'alice',
appData: Any

@@ -428,0 +429,0 @@ }

{
"name": "mediasoup-client",
"version": "0.3.1",
"version": "0.4.0",
"description": "mediasoup client SDK for mediasoup >= 2.0.0",

@@ -11,3 +11,3 @@ "author": "Iñaki Baz Castillo <ibc@aliax.net> (https://inakibaz.me)",

"bowser": "^1.7.2",
"debug": "git://github.com/ibc/debug.git#disable-colors-in-edge-and-ie",
"debug": "^3.0.1",
"random-number": "0.0.9",

@@ -14,0 +14,0 @@ "sdp-transform": "^2.3.0"

@@ -66,7 +66,7 @@ # mediasoup-client

// Send our audio.
sendTransport.send(audioProducer)
audioProducer.send(sendTransport)
.then(() => console.log('sending our mic'));
// Send our video.
sendTransport.send(videoProducer)
videoProducer.send(sendTransport)
.then(() => console.log('sending our webcam'));

@@ -98,4 +98,4 @@ });

{
// Error response, so pass the error message to the local Room.
errback(String(error));
// Error response, so pass the error to the local Room.
errback(error);
});

@@ -157,3 +157,3 @@ });

// Receive the media over our receiving Transport.
recvTransport.receive(consumer)
consumer.receive(recvTransport)
.then((track) =>

@@ -160,0 +160,0 @@ {

@@ -22,18 +22,6 @@ # TODO

- This is for both sending and receiving PeerConnections.
Currently, in Firefox50.removeProducer/Consumer, we don't do SDP O/A if this is the latest Producer/Consumer. However, it does not work. When clater adding a new Producer Firefox sends nothing. I think that it's changing the transport ICE and DTLS stuff...
Hummm, no no, it was a problem with H264 (not yet properly negotiated). When using opus and VP8, if I close the audio Producer, Firefox stops sending VP8. Fucking SDP and BUNDLE.
https://github.com/versatica/mediasoup-client/issues/2
* Implement `getStats()` in browsers? or better report uniformely from mediasoup?
# TODO in mediasoup 2.0.0 (server)
* Rename `RtpReceiver` to `Producer` and `RtpSender` to `Consumer`
*
* mediasoup should accept `peer.createTransport()` by passing a `transportId` number. The same for `RtpReceiver`.
* mediasoup should provide `const transport = peer.Transport()` rather than `createTransport()` (that returns a Promise).
* May have to react on DTLS ALERT CLOSE in the server and make it "really" close the Transport and notify the client. Bufff... I don't like this...
* mediasoup must be ready for the case in which the client closes a `Transport` on which a `Producer` was running.
* Upon a `updateProducer` notification, map the new SSRCs of the `Producer` and send a PLI back to the browser (otherwise, consumers will get frozen video).
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