You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

polyfills-webrtc.js 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. (global => {
  2. const {
  3. MediaStream,
  4. MediaStreamTrack,
  5. RTCPeerConnection,
  6. RTCSessionDescription,
  7. getUserMedia
  8. } = require('react-native-webrtc');
  9. if (typeof global.webkitMediaStream === 'undefined') {
  10. global.webkitMediaStream = MediaStream;
  11. }
  12. if (typeof global.MediaStreamTrack === 'undefined') {
  13. global.MediaStreamTrack = MediaStreamTrack;
  14. }
  15. if (typeof global.webkitRTCPeerConnection === 'undefined') {
  16. // XXX At the time of this writing extending RTCPeerConnection using ES6
  17. // 'class' and 'extends' causes a runtime error related to the attempt
  18. // to define the onaddstream property setter. The error mentions that
  19. // babelHelpers.set is undefined which appears to be a thing inside
  20. // React Native's packager. As a workaround, extend using the pre-ES6
  21. // way.
  22. /* eslint-disable no-inner-declarations */
  23. /**
  24. * The RTCPeerConnection provided by react-native-webrtc fires
  25. * onaddstream before it remembers remotedescription (and thus makes it
  26. * available to API clients). Because that appears to be a problem for
  27. * lib-jitsi-meet which has been successfully running
  28. * on Chrome, Firefox, Temasys, etc. for a very long time, attempt to
  29. * meets its expectations (by extending RTCPPeerConnection).
  30. *
  31. * @class
  32. */
  33. function _RTCPeerConnection(...args) {
  34. /* eslint-disable no-invalid-this */
  35. RTCPeerConnection.apply(this, args);
  36. this.onaddstream = (...args) => // eslint-disable-line no-shadow
  37. (this._onaddstreamQueue
  38. ? this._queueOnaddstream
  39. : this._invokeOnaddstream)
  40. .apply(this, args);
  41. // Shadow RTCPeerConnection's onaddstream but after
  42. // _RTCPeerConnection has assigned to the property in question.
  43. // Defining the property on _RTCPeerConnection's prototype may (or
  44. // may not, I don't know) work but I don't want to try because the
  45. // following approach appears to work and I understand it.
  46. Object.defineProperty(this, 'onaddstream', {
  47. configurable: true,
  48. enumerable: true,
  49. get() {
  50. return this._onaddstream;
  51. },
  52. set(value) {
  53. this._onaddstream = value;
  54. }
  55. });
  56. /* eslint-enable no-invalid-this */
  57. }
  58. /* eslint-enable no-inner-declarations */
  59. _RTCPeerConnection.prototype
  60. = Object.create(RTCPeerConnection.prototype);
  61. _RTCPeerConnection.prototype.constructor = _RTCPeerConnection;
  62. _RTCPeerConnection.prototype._invokeOnaddstream = function(...args) {
  63. const onaddstream = this._onaddstream;
  64. let r;
  65. if (onaddstream) {
  66. r = onaddstream.apply(this, args);
  67. }
  68. return r;
  69. };
  70. _RTCPeerConnection.prototype._invokeQueuedOnaddstream = function(q) {
  71. q && q.every(function(args) {
  72. try {
  73. this._invokeOnaddstream(...args);
  74. } catch (e) {
  75. // TODO Determine whether the combination of the standard
  76. // setRemoteDescription and onaddstream results in a similar
  77. // swallowing of errors.
  78. console && console.error && console.error(e);
  79. }
  80. return true;
  81. }, this);
  82. };
  83. _RTCPeerConnection.prototype._queueOnaddstream = function(...args) {
  84. this._onaddstreamQueue.push(Array.from(args));
  85. };
  86. _RTCPeerConnection.prototype.setRemoteDescription
  87. = function(sessionDescription, successCallback, errorCallback) {
  88. // Ensure I'm not remembering onaddstream invocations from
  89. // previous setRemoteDescription calls. I shouldn't be but...
  90. // anyway.
  91. this._onaddstreamQueue = [];
  92. return RTCPeerConnection.prototype.setRemoteDescription.call(
  93. this,
  94. sessionDescription,
  95. (...args) => {
  96. let r;
  97. let q;
  98. try {
  99. if (successCallback) {
  100. r = successCallback(...args);
  101. }
  102. } finally {
  103. q = this._onaddstreamQueue;
  104. this._onaddstreamQueue = undefined;
  105. }
  106. this._invokeQueuedOnaddstream(q);
  107. return r;
  108. },
  109. (...args) => {
  110. let r;
  111. this._onaddstreamQueue = undefined;
  112. if (errorCallback) {
  113. r = errorCallback(...args);
  114. }
  115. return r;
  116. });
  117. };
  118. global.webkitRTCPeerConnection = _RTCPeerConnection;
  119. }
  120. if (typeof global.RTCSessionDescription === 'undefined') {
  121. global.RTCSessionDescription = RTCSessionDescription;
  122. }
  123. const navigator = global.navigator;
  124. if (navigator) {
  125. if (typeof navigator.webkitGetUserMedia === 'undefined') {
  126. navigator.webkitGetUserMedia = getUserMedia;
  127. }
  128. }
  129. })(global || window || this); // eslint-disable-line no-invalid-this