@twilio/webrtc
Advanced tools
Comparing version 2.3.0 to 2.4.0
@@ -0,1 +1,14 @@ | ||
2.4.0 (November 11, 2019) | ||
========================= | ||
New Features | ||
------------ | ||
- ChromeRTCPeerConnection will now support Unified Plan SDPs in Chrome 72 and above. (JSDK-2313) | ||
Bug Fixes | ||
--------- | ||
- Fixed a bug where `audioLevel` returned by getStats() was not in the range [0-32767]. (JSDK-2318) | ||
2.3.0 (March 18, 2019) | ||
@@ -40,3 +53,3 @@ ====================== | ||
- Removed workaround for this Chrome [bug](https://bugs.chromium.org/p/chromium/issues/detail?id=774303). | ||
Now, we no longer suppress the RTCPeerConnection's native `RTCTrackEvent`. | ||
Now, we no longer suppress the RTCPeerConnection's native `RTCTrackEvent`. | ||
- Worked around the [deprecation](https://blog.mozilla.org/webrtc/getstats-isremote-65/) of the | ||
@@ -155,3 +168,3 @@ `isRemote` property in `RTCInboundRTPStreamStats` and `RTCOutboundRTPStreamStats` in Firefox. | ||
- `RTCSessionDescription` properties are now read-only, and therefore standards-compliant. (JSDK-1503) | ||
- `RTCSessionDescription` properties are now read-only, and therefore standards-compliant. (JSDK-1503) | ||
@@ -158,0 +171,0 @@ 1.0.0 (August 17, 2017) |
@@ -17,2 +17,4 @@ 'use strict'; | ||
var CHROME_LEGACY_MAX_AUDIO_LEVEL = 32767; | ||
/** | ||
@@ -574,2 +576,3 @@ * Get the standardized {@link RTCPeerConnection} statistics. | ||
if (typeof audioLevel === 'number') { | ||
audioLevel = Math.round(audioLevel * CHROME_LEGACY_MAX_AUDIO_LEVEL); | ||
if (isRemote) { | ||
@@ -576,0 +579,0 @@ standardizedStats.audioOutputLevel = audioLevel; |
@@ -36,3 +36,3 @@ /* globals RTCDataChannel, RTCPeerConnection, RTCSessionDescription */ | ||
? { iceTransports: configuration.iceTransportPolicy } | ||
: {}, { sdpSemantics: 'plan-b' }, configuration); | ||
: {}, configuration); | ||
@@ -151,8 +151,2 @@ util.interceptEvent(this, 'datachannel'); | ||
if (RTCPeerConnection.prototype.addTrack) { | ||
if (sdpFormat === 'unified') { | ||
sender = getActiveSenders(this._peerConnection).get(track) | ||
|| this._peerConnection.addTrack.apply(this._peerConnection, args); | ||
this._senders.set(track, sender); | ||
return sender; | ||
} | ||
return this._peerConnection.addTrack.apply(this._peerConnection, args); | ||
@@ -170,18 +164,2 @@ } | ||
// NOTE(mmalavalli): This shim works around a Chrome bug in "unified-plan" | ||
// SDPs where adding a MediaStreamTrack that was previously added and removed | ||
// generates an SDP where the MSID does not match the MediaStreamTrack ID. | ||
// | ||
// Chrome bug: https://bugs.chromium.org/p/chromium/issues/detail?id=894231 | ||
// | ||
if (RTCPeerConnection.prototype.addTransceiver) { | ||
ChromeRTCPeerConnection.prototype.addTransceiver = function addTransceiver() { | ||
var transceiver = this._peerConnection.addTransceiver.apply(this._peerConnection, arguments); | ||
var sender = transceiver.sender; | ||
var track = sender.track; | ||
this._senders.set(track, sender); | ||
return transceiver; | ||
}; | ||
} | ||
// NOTE(mmalavalli): This shim supports our limited case of removing | ||
@@ -191,8 +169,3 @@ // MediaStreamTracks from one MediaStream. It has been implemented this | ||
// supported natively in Chrome. | ||
// NOTE(mmalavalli): This shim also works around a Chrome bug in "unified-plan" | ||
// SDPs where adding a MediaStreamTrack that was previously added and removed | ||
// generates an SDP where the MSID does not match the MediaStreamTrack ID. | ||
// | ||
// Chrome bug: https://bugs.chromium.org/p/chromium/issues/detail?id=894231 | ||
// | ||
ChromeRTCPeerConnection.prototype.removeTrack = function removeTrack(sender) { | ||
@@ -205,9 +178,3 @@ if (this._peerConnection.signalingState === 'closed') { | ||
try { | ||
if (sdpFormat === 'unified') { | ||
if (sender.track) { | ||
this._senders.set(sender.track, new RTCRtpSenderShim(null)); | ||
} | ||
} else { | ||
this._peerConnection.removeTrack(sender); | ||
} | ||
this._peerConnection.removeTrack(sender); | ||
} | ||
@@ -237,3 +204,3 @@ catch (error) { | ||
ChromeRTCPeerConnection.prototype.getSenders = function getSenders() { | ||
return this._peerConnection.getSenders && sdpFormat === 'planb' | ||
return this._peerConnection.getSenders | ||
? this._peerConnection.getSenders() | ||
@@ -556,15 +523,2 @@ : Array.from(this._senders.values()); | ||
/** | ||
* Gets the active RTCRtpSenders of the RTCPeerConnection. | ||
* @param peerConnection | ||
* @returns {Map<MediaStreamTrack, RTCRtpSender>} | ||
*/ | ||
function getActiveSenders(peerConnection) { | ||
return new Map(peerConnection.getSenders().filter(function(sender) { | ||
return sender.track; | ||
}).map(function(sender) { | ||
return [sender.track, sender]; | ||
})); | ||
} | ||
/** | ||
* Update the mappings from MediaStreamTrack IDs to SSRCs as indicated by both | ||
@@ -571,0 +525,0 @@ * the Map from MediaStreamTrack IDs to SSRCs and the SDP itself. This method |
@@ -6,3 +6,2 @@ /* globals RTCPeerConnection */ | ||
var FirefoxRTCSessionDescription = require('../rtcsessiondescription/firefox'); | ||
var RTCRtpSenderShim = require('../rtcrtpsender'); | ||
var inherits = require('util').inherits; | ||
@@ -67,5 +66,2 @@ var updateTracksToSSRCs = require('../util/sdp').updateUnifiedPlanTrackIdsToSSRCs; | ||
}, | ||
_senders: { | ||
value: new Map() | ||
}, | ||
_tracksToSSRCs: { | ||
@@ -131,66 +127,11 @@ value: new Map() | ||
// NOTE(mmalavalli): Because we are not delegating to the native | ||
// RTCPeerConnection#removeTrack(), we have to manually maintain a list of added | ||
// tracks. So we disable the delegation to the native RTCPeerConnection#addTrack() | ||
// for now. | ||
FirefoxRTCPeerConnection.prototype.addTrack = function addTrack() { | ||
var args = [].slice.call(arguments); | ||
var track = args[0]; | ||
var sender = this._senders.get(track); | ||
if (sender && sender.track) { | ||
throw new Error('Cannot add MediaStreamTrack [' + track.id + ', ' | ||
+ track.kind + ']: RTCPeerConnection already has it'); | ||
} | ||
sender = getActiveSenders(this._peerConnection).get(track) | ||
|| this._peerConnection.addTrack.apply(this._peerConnection, args); | ||
if (needsWorkaroundForBug1480277) { | ||
if (needsWorkaroundForBug1480277) { | ||
FirefoxRTCPeerConnection.prototype.addTrack = function addTrack() { | ||
var track = arguments[0]; | ||
var sender = this._peerConnection.addTrack.apply(this._peerConnection, arguments); | ||
sender.replaceTrack(track); | ||
} | ||
this._senders.set(track, sender); | ||
return sender; | ||
}; | ||
if (RTCPeerConnection.prototype.addTransceiver) { | ||
FirefoxRTCPeerConnection.prototype.addTransceiver = function addTransceiver() { | ||
var transceiver = this._peerConnection.addTransceiver.apply(this._peerConnection, arguments); | ||
var sender = transceiver.sender; | ||
var track = sender.track; | ||
if (track && needsWorkaroundForBug1480277) { | ||
sender.replaceTrack(track); | ||
} | ||
this._senders.set(track, sender); | ||
return transceiver; | ||
return sender; | ||
}; | ||
} | ||
// NOTE(mmalavalli): RTCPeerConnection#removeTrack() has a bug in the | ||
// Firefox <--> Chrome interop case, which is mentioned below. So we disable | ||
// its delegation for now. Also, we maintain only one RTCRtpSender per | ||
// MediaStreamTrack for our use case, and not worry about multiple RTCRtpSenders | ||
// due to replaceTrack(). | ||
// Bugzilla: https://bugzilla.mozilla.org/show_bug.cgi?id=1133874 | ||
FirefoxRTCPeerConnection.prototype.removeTrack = function removeTrack(sender) { | ||
if (this._isClosed) { | ||
throw new Error('Cannot remove MediaStreamTrack: RTCPeerConnection is closed'); | ||
} | ||
var track = sender.track; | ||
if (!track) { | ||
return; | ||
} | ||
sender = this._senders.get(track); | ||
if (sender && sender.track) { | ||
this._senders.set(track, new RTCRtpSenderShim(null)); | ||
} | ||
}; | ||
// NOTE(mmalavalli): Because we are not delegating to the native | ||
// RTCPeerConnection#removeTrack(), we have to manually maintain a list of added | ||
// tracks. So we disable the delegation to the native RTCPeerConnection#getSenders() | ||
// for now. | ||
FirefoxRTCPeerConnection.prototype.getSenders = function getSenders() { | ||
return Array.from(this._senders.values()); | ||
}; | ||
FirefoxRTCPeerConnection.prototype.createAnswer = function createAnswer() { | ||
@@ -393,15 +334,2 @@ var args = [].slice.call(arguments); | ||
/** | ||
* Gets the active RTCRtpSenders of the RTCPeerConnection. | ||
* @param peerConnection | ||
* @returns {Map<MediaStreamTrack, RTCRtpSender>} | ||
*/ | ||
function getActiveSenders(peerConnection) { | ||
return new Map(peerConnection.getSenders().filter(function(sender) { | ||
return sender.track; | ||
}).map(function(sender) { | ||
return [sender.track, sender]; | ||
})); | ||
} | ||
module.exports = FirefoxRTCPeerConnection; |
@@ -7,3 +7,2 @@ /* globals RTCPeerConnection, RTCSessionDescription */ | ||
var Latch = require('../util/latch'); | ||
var RTCRtpSenderShim = require('../rtcrtpsender'); | ||
var sdpUtils = require('../util/sdp'); | ||
@@ -52,5 +51,2 @@ var util = require('../util'); | ||
}, | ||
_senders: { | ||
value: new Map() | ||
}, | ||
_signalingStateLatch: { | ||
@@ -246,77 +242,11 @@ value: new Latch() | ||
// NOTE(mmalavalli): Because we are not delegating to the native | ||
// RTCPeerConnection#removeTrack(), we have to manually maintain a list of added | ||
// tracks. So we disable the delegation to the native RTCPeerConnection#addTrack() | ||
// for now. Also, we maintain only one RTCRtpSender per MediaStreamTrack for our | ||
// use case, and not worry about multiple RTCRtpSenders due to replaceTrack(). | ||
SafariRTCPeerConnection.prototype.addTrack = function addTrack() { | ||
var args = [].slice.call(arguments); | ||
var track = args[0]; | ||
var sender = this._senders.get(track); | ||
if (sender && sender.track) { | ||
throw new Error('Cannot add MediaStreamTrack [' + track.id + ', ' | ||
+ track.kind + ']: RTCPeerConnection already has it'); | ||
} | ||
sender = getActiveSenders(this._peerConnection).get(track) | ||
|| this._peerConnection.addTrack.apply(this._peerConnection, args); | ||
// NOTE(mmalavalli): webrtc-adapter has a bug where the "addTrack" shim | ||
// does not return an RTCRtpSender and returns undefined instead. An issue | ||
// [https://github.com/webrtc/adapter/issues/714] has been filed. For now, | ||
// we manually get the RTCRtpSender associated with the added track and | ||
// return it. | ||
sender = sender || getActiveSenders(this._peerConnection).get(track); | ||
this._senders.set(track, sender); | ||
return sender; | ||
}; | ||
// NOTE(mmalavalli): This shim works around a Safari bug in "unified-plan" | ||
// SDPs where adding a MediaStreamTrack that was previously added and removed | ||
// generates an SDP where the MSID does not match the MediaStreamTrack ID. | ||
// NOTE(mmalavalli): This shim works around the following bug in | ||
// RTCPeerConnection#removeTrack(): | ||
// https://bugs.webkit.org/show_bug.cgi?id=174327 | ||
// | ||
// Safari bug: https://bugs.webkit.org/show_bug.cgi?id=192101 | ||
// | ||
if (RTCPeerConnection.prototype.addTransceiver) { | ||
SafariRTCPeerConnection.prototype.addTransceiver = function addTransceiver() { | ||
var transceiver = this._peerConnection.addTransceiver.apply(this._peerConnection, arguments); | ||
var sender = transceiver.sender; | ||
var track = sender.track; | ||
this._senders.set(track, sender); | ||
return transceiver; | ||
}; | ||
} | ||
// NOTE(mroberts): We can't really remove tracks right now, at least if we | ||
// ever want to add them back... | ||
// | ||
// https://bugs.webkit.org/show_bug.cgi?id=174327 | ||
// | ||
// NOTE(mmalavalli): This shim also works around a Safari bug in "unified-plan" | ||
// SDPs where adding a MediaStreamTrack that was previously added and removed | ||
// generates an SDP where the MSID does not match the MediaStreamTrack ID. | ||
// | ||
// Safari bug: https://bugs.webkit.org/show_bug.cgi?id=192101 | ||
// | ||
SafariRTCPeerConnection.prototype.removeTrack = function removeTrack(sender) { | ||
if (this._isClosed) { | ||
throw new Error('Cannot remove MediaStreamTrack: RTCPeerConnection is closed'); | ||
} | ||
var track = sender.track; | ||
if (!track) { | ||
return; | ||
} | ||
sender = this._senders.get(track); | ||
if (sender && sender.track) { | ||
this._senders.set(track, new RTCRtpSenderShim(null)); | ||
} | ||
sender.replaceTrack(null); | ||
this._peerConnection.removeTrack(sender); | ||
}; | ||
// NOTE(mmalavalli): Because we are not delegating to the native | ||
// RTCPeerConnection#removeTrack(), we have to manually maintain a list of added | ||
// tracks. So we disable the delegation to the native RTCPeerConnection#getSenders() | ||
// for now. | ||
SafariRTCPeerConnection.prototype.getSenders = function getSenders() { | ||
return Array.from(this._senders.values()); | ||
}; | ||
util.delegateMethods( | ||
@@ -428,15 +358,2 @@ RTCPeerConnection.prototype, | ||
/** | ||
* Gets the active RTCRtpSenders of the RTCPeerConnection. | ||
* @param peerConnection | ||
* @returns {Map<MediaStreamTrack, RTCRtpSender>} | ||
*/ | ||
function getActiveSenders(peerConnection) { | ||
return new Map(peerConnection.getSenders().filter(function(sender) { | ||
return sender.track; | ||
}).map(function(sender) { | ||
return [sender.track, sender]; | ||
})); | ||
} | ||
module.exports = SafariRTCPeerConnection; |
@@ -7,27 +7,2 @@ /* globals RTCPeerConnection, RTCRtpTransceiver */ | ||
// NOTE(mmalavalli): We cache Chrome's sdpSemantics support in order to prevent | ||
// instantiation of more than one RTCPeerConnection. | ||
var isSdpSemanticsSupported; | ||
/** | ||
* Check if Chrome supports specifying sdpSemantics for an RTCPeerConnection. | ||
* @return {boolean} | ||
*/ | ||
function checkIfSdpSemanticsIsSupported() { | ||
if (typeof isSdpSemanticsSupported === 'boolean') { | ||
return isSdpSemanticsSupported; | ||
} | ||
if (typeof RTCPeerConnection === 'undefined') { | ||
isSdpSemanticsSupported = false; | ||
return isSdpSemanticsSupported; | ||
} | ||
try { | ||
new RTCPeerConnection({ sdpSemantics: 'foo' }); | ||
isSdpSemanticsSupported = false; | ||
} catch (e) { | ||
isSdpSemanticsSupported = true; | ||
} | ||
return isSdpSemanticsSupported; | ||
} | ||
// NOTE(mmalavalli): We cache Chrome's SDP format in order to prevent | ||
@@ -42,13 +17,15 @@ // instantiation of more than one RTCPeerConnection. | ||
function getChromeSdpFormat() { | ||
if (typeof chromeSdpFormat === 'string') { | ||
return chromeSdpFormat; | ||
if (!chromeSdpFormat) { | ||
if (typeof RTCPeerConnection !== 'undefined' | ||
&& 'addTransceiver' in RTCPeerConnection.prototype) { | ||
try { | ||
new RTCPeerConnection().addTransceiver('audio'); | ||
chromeSdpFormat = 'unified'; | ||
} catch (e) { | ||
chromeSdpFormat = 'planb'; | ||
} | ||
} else { | ||
chromeSdpFormat = 'planb'; | ||
} | ||
} | ||
if (checkIfSdpSemanticsIsSupported()) { | ||
chromeSdpFormat = 'planb'; | ||
return chromeSdpFormat; | ||
} | ||
chromeSdpFormat = typeof RTCPeerConnection !== 'undefined' | ||
&& 'addStream' in RTCPeerConnection.prototype | ||
? 'planb' | ||
: 'unified'; | ||
return chromeSdpFormat; | ||
@@ -55,0 +32,0 @@ } |
{ | ||
"name": "@twilio/webrtc", | ||
"version": "2.3.0", | ||
"version": "2.4.0", | ||
"description": "WebRTC-related APIs and shims used by twilio-video.js", | ||
@@ -5,0 +5,0 @@ "scripts": { |
@@ -80,5 +80,2 @@ twilio-webrtc.js | ||
more information. | ||
* Works around a [this bug](https://bugs.chromium.org/p/chromium/issues/detail?id=894231) | ||
in "unified-plan" SDPs where adding a `MediaStreamTrack` that was previously added and | ||
removed generates an SDP where the MSID does not match the `MediaStreamTrack` ID. | ||
* Does not depend on the native "track" event for "plan-b" RTCPeerConnection because | ||
@@ -99,7 +96,2 @@ of [this bug](https://bugs.chromium.org/p/chromium/issues/detail?id=774303), which partly | ||
where the browser throws when `RTCPeerConnection.prototype.peerIdentity` is accessed. | ||
* Provides a shim for the `removeTrack` method in order to work around [this bug](https://bugzilla.mozilla.org/show_bug.cgi?id=1133874). | ||
* Provides a shim for the `addTrack` method. Since `removeTrack` is shimmed, there is a necessity to | ||
maintain an explicit list of added `RTCRtpSender`s. | ||
* Provides a shim for the `getSenders` method. Since `removeTrack` is shimmed, there is a necessity to | ||
maintain an explicit list of added `RTCRtpSender`s. | ||
* Works around Firefox [Bug 1480277](https://bugzilla.mozilla.org/show_bug.cgi?id=1480277). | ||
@@ -112,9 +104,3 @@ | ||
`MediaStreamTrack`. | ||
* Provides a shim for the `removeTrack` method in order to work around [this bug](https://bugs.webkit.org/show_bug.cgi?id=174327). | ||
* Provides a shim for the `addTrack` method. Since `removeTrack` is shimmed, there is a necessity to | ||
maintain an explicit list of added `RTCRtpSender`s. | ||
* Provides a workaround for [this bug](https://github.com/webrtc/adapter/issues/714), where webrtc-adapter's shimmed | ||
`addTrack` method does not return the `RTCRtpSender` associated with the added track. | ||
* Provides a shim for the `getSenders` method. Since `removeTrack` is shimmed, there is a necessity to | ||
maintain an explicit list of added `RTCRtpSender`s. | ||
* Provides a workaround for this `removeTrack` [bug](https://bugs.webkit.org/show_bug.cgi?id=174327). | ||
@@ -121,0 +107,0 @@ ### RTCSessionDescription |
113356
2630
115