jiti-meet/react/features/base/lib-jitsi-meet/native/polyfills-webrtc.js

156 lines
5.6 KiB
JavaScript

(global => {
const {
MediaStream,
MediaStreamTrack,
RTCPeerConnection,
RTCSessionDescription,
getUserMedia
} = require('react-native-webrtc');
if (typeof global.webkitMediaStream === 'undefined') {
global.webkitMediaStream = MediaStream;
}
if (typeof global.MediaStreamTrack === 'undefined') {
global.MediaStreamTrack = MediaStreamTrack;
}
if (typeof global.webkitRTCPeerConnection === 'undefined') {
// XXX At the time of this writing extending RTCPeerConnection using ES6
// 'class' and 'extends' causes a runtime error related to the attempt
// to define the onaddstream property setter. The error mentions that
// babelHelpers.set is undefined which appears to be a thing inside
// React Native's packager. As a workaround, extend using the pre-ES6
// way.
/* eslint-disable no-inner-declarations */
/**
* The RTCPeerConnection provided by react-native-webrtc fires
* onaddstream before it remembers remotedescription (and thus makes it
* available to API clients). Because that appears to be a problem for
* lib-jitsi-meet which has been successfully running
* on Chrome, Firefox, Temasys, etc. for a very long time, attempt to
* meets its expectations (by extending RTCPPeerConnection).
*
* @class
*/
function _RTCPeerConnection(...args) {
/* eslint-disable no-invalid-this */
RTCPeerConnection.apply(this, args);
this.onaddstream = (...args) => // eslint-disable-line no-shadow
(this._onaddstreamQueue
? this._queueOnaddstream
: this._invokeOnaddstream)
.apply(this, args);
// Shadow RTCPeerConnection's onaddstream but after
// _RTCPeerConnection has assigned to the property in question.
// Defining the property on _RTCPeerConnection's prototype may (or
// may not, I don't know) work but I don't want to try because the
// following approach appears to work and I understand it.
Object.defineProperty(this, 'onaddstream', {
configurable: true,
enumerable: true,
get() {
return this._onaddstream;
},
set(value) {
this._onaddstream = value;
}
});
/* eslint-enable no-invalid-this */
}
/* eslint-enable no-inner-declarations */
_RTCPeerConnection.prototype
= Object.create(RTCPeerConnection.prototype);
_RTCPeerConnection.prototype.constructor = _RTCPeerConnection;
_RTCPeerConnection.prototype._invokeOnaddstream = function(...args) {
const onaddstream = this._onaddstream;
let r;
if (onaddstream) {
r = onaddstream.apply(this, args);
}
return r;
};
_RTCPeerConnection.prototype._invokeQueuedOnaddstream = function(q) {
q && q.every(function(args) {
try {
this._invokeOnaddstream(...args);
} catch (e) {
// TODO Determine whether the combination of the standard
// setRemoteDescription and onaddstream results in a similar
// swallowing of errors.
console && console.error && console.error(e);
}
return true;
}, this);
};
_RTCPeerConnection.prototype._queueOnaddstream = function(...args) {
this._onaddstreamQueue.push(Array.from(args));
};
_RTCPeerConnection.prototype.setRemoteDescription
= function(sessionDescription, successCallback, errorCallback) {
// Ensure I'm not remembering onaddstream invocations from
// previous setRemoteDescription calls. I shouldn't be but...
// anyway.
this._onaddstreamQueue = [];
return RTCPeerConnection.prototype.setRemoteDescription.call(
this,
sessionDescription,
(...args) => {
let r;
let q;
try {
if (successCallback) {
r = successCallback(...args);
}
} finally {
q = this._onaddstreamQueue;
this._onaddstreamQueue = undefined;
}
this._invokeQueuedOnaddstream(q);
return r;
},
(...args) => {
let r;
this._onaddstreamQueue = undefined;
if (errorCallback) {
r = errorCallback(...args);
}
return r;
});
};
global.webkitRTCPeerConnection = _RTCPeerConnection;
}
if (typeof global.RTCSessionDescription === 'undefined') {
global.RTCSessionDescription = RTCSessionDescription;
}
const navigator = global.navigator;
if (navigator) {
if (typeof navigator.webkitGetUserMedia === 'undefined') {
navigator.webkitGetUserMedia = getUserMedia;
}
}
})(global || window || this); // eslint-disable-line no-invalid-this