simple-peer视频聊天之adapter-latest.js

(function(f){if(typeof exports===“object”&&typeof module!“undefined”){module.exports=f()}else if(typeof define=“function”&&define.amd){define([],f)}else{var g;if(typeof window!“undefined”){g=window}else if(typeof global!“undefined”){g=global}else if(typeof self!==“undefined”){g=self}else{g=this}g.adapter = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c=“function”==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error(“Cannot find module '”+i+"’");throw a.code=“MODULE_NOT_FOUND”,a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function®{var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u=“function”==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
/*

  • Copyright © 2016 The WebRTC project authors. All Rights Reserved.
  • Use of this source code is governed by a BSD-style license
  • that can be found in the LICENSE file in the root of the source
  • tree.
    /
    /
    eslint-env node */

‘use strict’;

var _adapter_factory = require(’./adapter_factory.js’);

var adapter = (0, _adapter_factory.adapterFactory)({ window: window });
module.exports = adapter; // this is the difference from adapter_core.

},{"./adapter_factory.js":2}],2:[function(require,module,exports){
‘use strict’;

Object.defineProperty(exports, “__esModule”, {
value: true
});
exports.adapterFactory = adapterFactory;

var _utils = require(’./utils’);

var utils = _interopRequireWildcard(_utils);

var _chrome_shim = require(’./chrome/chrome_shim’);

var chromeShim = _interopRequireWildcard(_chrome_shim);

var _edge_shim = require(’./edge/edge_shim’);

var edgeShim = _interopRequireWildcard(_edge_shim);

var _firefox_shim = require(’./firefox/firefox_shim’);

var firefoxShim = _interopRequireWildcard(_firefox_shim);

var _safari_shim = require(’./safari/safari_shim’);

var safariShim = _interopRequireWildcard(_safari_shim);

var _common_shim = require(’./common_shim’);

var commonShim = _interopRequireWildcard(_common_shim);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

// Shimming starts here.
/*

  • Copyright © 2016 The WebRTC project authors. All Rights Reserved.
  • Use of this source code is governed by a BSD-style license
  • that can be found in the LICENSE file in the root of the source
  • tree.
    */
    function adapterFactory() {
    var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
    window = _ref.window;

var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
shimChrome: true,
shimFirefox: true,
shimEdge: true,
shimSafari: true
};

// Utils.
var logging = utils.log;
var browserDetails = utils.detectBrowser(window);

var adapter = {
browserDetails: browserDetails,
commonShim: commonShim,
extractVersion: utils.extractVersion,
disableLog: utils.disableLog,
disableWarnings: utils.disableWarnings
};

// Shim browser if found.
switch (browserDetails.browser) {
case ‘chrome’:
if (!chromeShim || !chromeShim.shimPeerConnection || !options.shimChrome) {
logging(‘Chrome shim is not included in this adapter release.’);
return adapter;
}
logging(‘adapter.js shimming chrome.’);
// Export to the adapter global object visible in the browser.
adapter.browserShim = chromeShim;

  chromeShim.shimGetUserMedia(window);
  chromeShim.shimMediaStream(window);
  chromeShim.shimPeerConnection(window);
  chromeShim.shimOnTrack(window);
  chromeShim.shimAddTrackRemoveTrack(window);
  chromeShim.shimGetSendersWithDtmf(window);
  chromeShim.shimGetStats(window);
  chromeShim.shimSenderReceiverGetStats(window);
  chromeShim.fixNegotiationNeeded(window);

  commonShim.shimRTCIceCandidate(window);
  commonShim.shimConnectionState(window);
  commonShim.shimMaxMessageSize(window);
  commonShim.shimSendThrowTypeError(window);
  commonShim.removeAllowExtmapMixed(window);
  break;
case 'firefox':
  if (!firefoxShim || !firefoxShim.shimPeerConnection || !options.shimFirefox) {
    logging('Firefox shim is not included in this adapter release.');
    return adapter;
  }
  logging('adapter.js shimming firefox.');
  // Export to the adapter global object visible in the browser.
  adapter.browserShim = firefoxShim;

  firefoxShim.shimGetUserMedia(window);
  firefoxShim.shimPeerConnection(window);
  firefoxShim.shimOnTrack(window);
  firefoxShim.shimRemoveStream(window);
  firefoxShim.shimSenderGetStats(window);
  firefoxShim.shimReceiverGetStats(window);
  firefoxShim.shimRTCDataChannel(window);

  commonShim.shimRTCIceCandidate(window);
  commonShim.shimConnectionState(window);
  commonShim.shimMaxMessageSize(window);
  commonShim.shimSendThrowTypeError(window);
  break;
case 'edge':
  if (!edgeShim || !edgeShim.shimPeerConnection || !options.shimEdge) {
    logging('MS edge shim is not included in this adapter release.');
    return adapter;
  }
  logging('adapter.js shimming edge.');
  // Export to the adapter global object visible in the browser.
  adapter.browserShim = edgeShim;

  edgeShim.shimGetUserMedia(window);
  edgeShim.shimGetDisplayMedia(window);
  edgeShim.shimPeerConnection(window);
  edgeShim.shimReplaceTrack(window);

  // the edge shim implements the full RTCIceCandidate object.

  commonShim.shimMaxMessageSize(window);
  commonShim.shimSendThrowTypeError(window);
  break;
case 'safari':
  if (!safariShim || !options.shimSafari) {
    logging('Safari shim is not included in this adapter release.');
    return adapter;
  }
  logging('adapter.js shimming safari.');
  // Export to the adapter global object visible in the browser.
  adapter.browserShim = safariShim;

  safariShim.shimRTCIceServerUrls(window);
  safariShim.shimCreateOfferLegacy(window);
  safariShim.shimCallbacksAPI(window);
  safariShim.shimLocalStreamsAPI(window);
  safariShim.shimRemoteStreamsAPI(window);
  safariShim.shimTrackEventTransceiver(window);
  safariShim.shimGetUserMedia(window);

  commonShim.shimRTCIceCandidate(window);
  commonShim.shimMaxMessageSize(window);
  commonShim.shimSendThrowTypeError(window);
  commonShim.removeAllowExtmapMixed(window);
  break;
default:
  logging('Unsupported browser!');
  break;

}

return adapter;
}

// Browser shims.

},{"./chrome/chrome_shim":3,"./common_shim":6,"./edge/edge_shim":7,"./firefox/firefox_shim":11,"./safari/safari_shim":14,"./utils":15}],3:[function(require,module,exports){

/*

  • Copyright © 2016 The WebRTC project authors. All Rights Reserved.
  • Use of this source code is governed by a BSD-style license
  • that can be found in the LICENSE file in the root of the source
  • tree.
    /
    /
    eslint-env node */
    ‘use strict’;

Object.defineProperty(exports, “__esModule”, {
value: true
});
exports.shimGetDisplayMedia = exports.shimGetUserMedia = undefined;

var _typeof = typeof Symbol === “function” && typeof Symbol.iterator === “symbol” ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === “function” && obj.constructor === Symbol && obj !== Symbol.prototype ? “symbol” : typeof obj; };

var _getusermedia = require(’./getusermedia’);

Object.defineProperty(exports, ‘shimGetUserMedia’, {
enumerable: true,
get: function get() {
return _getusermedia.shimGetUserMedia;
}
});

var _getdisplaymedia = require(’./getdisplaymedia’);

Object.defineProperty(exports, ‘shimGetDisplayMedia’, {
enumerable: true,
get: function get() {
return _getdisplaymedia.shimGetDisplayMedia;
}
});
exports.shimMediaStream = shimMediaStream;
exports.shimOnTrack = shimOnTrack;
exports.shimGetSendersWithDtmf = shimGetSendersWithDtmf;
exports.shimGetStats = shimGetStats;
exports.shimSenderReceiverGetStats = shimSenderReceiverGetStats;
exports.shimAddTrackRemoveTrackWithNative = shimAddTrackRemoveTrackWithNative;
exports.shimAddTrackRemoveTrack = shimAddTrackRemoveTrack;
exports.shimPeerConnection = shimPeerConnection;
exports.fixNegotiationNeeded = fixNegotiationNeeded;

var _utils = require(’…/utils.js’);

var utils = _interopRequireWildcard(_utils);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function shimMediaStream(window) {
window.MediaStream = window.MediaStream || window.webkitMediaStream;
}

function shimOnTrack(window) {
if ((typeof window === ‘undefined’ ? ‘undefined’ : _typeof(window)) === ‘object’ && window.RTCPeerConnection && !(‘ontrack’ in window.RTCPeerConnection.prototype)) {
Object.defineProperty(window.RTCPeerConnection.prototype, ‘ontrack’, {
get: function get() {
return this._ontrack;
},
set: function set(f) {
if (this._ontrack) {
this.removeEventListener(‘track’, this._ontrack);
}
this.addEventListener(‘track’, this._ontrack = f);
},

  enumerable: true,
  configurable: true
});
var origSetRemoteDescription = window.RTCPeerConnection.prototype.setRemoteDescription;
window.RTCPeerConnection.prototype.setRemoteDescription = function () {
  var _this = this;

  if (!this._ontrackpoly) {
    this._ontrackpoly = function (e) {
      // onaddstream does not fire when a track is added to an existing
      // stream. But stream.onaddtrack is implemented so we use that.
      e.stream.addEventListener('addtrack', function (te) {
        var receiver = void 0;
        if (window.RTCPeerConnection.prototype.getReceivers) {
          receiver = _this.getReceivers().find(function (r) {
            return r.track && r.track.id === te.track.id;
          });
        } else {
          receiver = { track: te.track };
        }

        var event = new Event('track');
        event.track = te.track;
        event.receiver = receiver;
        event.transceiver = { receiver: receiver };
        event.streams = [e.stream];
        _this.dispatchEvent(event);
      });
      e.stream.getTracks().forEach(function (track) {
        var receiver = void 0;
        if (window.RTCPeerConnection.prototype.getReceivers) {
          receiver = _this.getReceivers().find(function (r) {
            return r.track && r.track.id === track.id;
          });
        } else {
          receiver = { track: track };
        }
        var event = new Event('track');
        event.track = track;
        event.receiver = receiver;
        event.transceiver = { receiver: receiver };
        event.streams = [e.stream];
        _this.dispatchEvent(event);
      });
    };
    this.addEventListener('addstream', this._ontrackpoly);
  }
  return origSetRemoteDescription.apply(this, arguments);
};

} else {
// even if RTCRtpTransceiver is in window, it is only used and
// emitted in unified-plan. Unfortunately this means we need
// to unconditionally wrap the event.
utils.wrapPeerConnectionEvent(window, ‘track’, function (e) {
if (!e.transceiver) {
Object.defineProperty(e, ‘transceiver’, { value: { receiver: e.receiver } });
}
return e;
});
}
}

function shimGetSendersWithDtmf(window) {
// Overrides addTrack/removeTrack, depends on shimAddTrackRemoveTrack.
if ((typeof window === ‘undefined’ ? ‘undefined’ : _typeof(window)) === ‘object’ && window.RTCPeerConnection && !(‘getSenders’ in window.RTCPeerConnection.prototype) && ‘createDTMFSender’ in window.RTCPeerConnection.prototype) {
var shimSenderWithDtmf = function shimSenderWithDtmf(pc, track) {
return {
track: track,
get dtmf() {
if (this._dtmf === undefined) {
if (track.kind === ‘audio’) {
this._dtmf = pc.createDTMFSender(track);
} else {
this._dtmf = null;
}
}
return this._dtmf;
},
_pc: pc
};
};

// augment addTrack when getSenders is not available.
if (!window.RTCPeerConnection.prototype.getSenders) {
  window.RTCPeerConnection.prototype.getSenders = function () {
    this._senders = this._senders || [];
    return this._senders.slice(); // return a copy of the internal state.
  };
  var origAddTrack = window.RTCPeerConnection.prototype.addTrack;
  window.RTCPeerConnection.prototype.addTrack = function (track, stream) {
    var sender = origAddTrack.apply(this, arguments);
    if (!sender) {
      sender = shimSenderWithDtmf(this, track);
      this._senders.push(sender);
    }
    return sender;
  };

  var origRemoveTrack = window.RTCPeerConnection.prototype.removeTrack;
  window.RTCPeerConnection.prototype.removeTrack = function (sender) {
    origRemoveTrack.apply(this, arguments);
    var idx = this._senders.indexOf(sender);
    if (idx !== -1) {
      this._senders.splice(idx, 1);
    }
  };
}
var origAddStream = window.RTCPeerConnection.prototype.addStream;
window.RTCPeerConnection.prototype.addStream = function (stream) {
  var _this2 = this;

  this._senders = this._senders || [];
  origAddStream.apply(this, [stream]);
  stream.getTracks().forEach(function (track) {
    _this2._senders.push(shimSenderWithDtmf(_this2, track));
  });
};

var origRemoveStream = window.RTCPeerConnection.prototype.removeStream;
window.RTCPeerConnection.prototype.removeStream = function (stream) {
  var _this3 = this;

  this._senders = this._senders || [];
  origRemoveStream.apply(this, [stream]);

  stream.getTracks().forEach(function (track) {
    var sender = _this3._senders.find(function (s) {
      return s.track === track;
    });
    if (sender) {
      // remove sender
      _this3._senders.splice(_this3._senders.indexOf(sender), 1);
    }
  });
};

} else if ((typeof window === ‘undefined’ ? ‘undefined’ : _typeof(window)) === ‘object’ && window.RTCPeerConnection && ‘getSenders’ in window.RTCPeerConnection.prototype && ‘createDTMFSender’ in window.RTCPeerConnection.prototype && window.RTCRtpSender && !(‘dtmf’ in window.RTCRtpSender.prototype)) {
var origGetSenders = window.RTCPeerConnection.prototype.getSenders;
window.RTCPeerConnection.prototype.getSenders = function () {
var _this4 = this;

  var senders = origGetSenders.apply(this, []);
  senders.forEach(function (sender) {
    return sender._pc = _this4;
  });
  return senders;
};

Object.defineProperty(window.RTCRtpSender.prototype, 'dtmf', {
  get: function get() {
    if (this._dtmf === undefined) {
      if (this.track.kind === 'audio') {
        this._dtmf = this._pc.createDTMFSender(this.track);
      } else {
        this._dtmf = null;
      }
    }
    return this._dtmf;
  }
});

}
}

function shimGetStats(window) {
if (!window.RTCPeerConnection) {
return;
}

var origGetStats = window.RTCPeerConnection.prototype.getStats;
window.RTCPeerConnection.prototype.getStats = function (selector, successCallback, errorCallback) {
var _this5 = this;

var args = arguments;

// If selector is a function then we are in the old style stats so just
// pass back the original getStats format to avoid breaking old users.
if (arguments.length > 0 && typeof selector === 'function') {
  return origGetStats.apply(this, arguments);
}

// When spec-style getStats is supported, return those when called with
// either no arguments or the selector argument is null.
if (origGetStats.length === 0 && (arguments.length === 0 || typeof arguments[0] !== 'function')) {
  return origGetStats.apply(this, []);
}

var fixChromeStats_ = function fixChromeStats_(response) {
  var standardReport = {};
  var reports = response.result();
  reports.forEach(function (report) {
    var standardStats = {
      id: report.id,
      timestamp: report.timestamp,
      type: {
        localcandidate: 'local-candidate',
        remotecandidate: 'remote-candidate'
      }[report.type] || report.type
    };
    report.names().forEach(function (name) {
      standardStats[name] = report.stat(name);
    });
    standardReport[standardStats.id] = standardStats;
  });

  return standardReport;
};

// shim getStats with maplike support
var makeMapStats = function makeMapStats(stats) {
  return new Map(Object.keys(stats).map(function (key) {
    return [key, stats[key]];
  }));
};

if (arguments.length >= 2) {
  var successCallbackWrapper_ = function successCallbackWrapper_(response) {
    args[1](makeMapStats(fixChromeStats_(response)));
  };

  return origGetStats.apply(this, [successCallbackWrapper_, arguments[0]]);
}

// promise-support
return new Promise(function (resolve, reject) {
  origGetStats.apply(_this5, [function (response) {
    resolve(makeMapStats(fixChromeStats_(response)));
  }, reject]);
}).then(successCallback, errorCallback);

};
}

function shimSenderReceiverGetStats(window) {
if (!((typeof window === ‘undefined’ ? ‘undefined’ : _typeof(window)) === ‘object’ && window.RTCPeerConnection && window.RTCRtpSender && window.RTCRtpReceiver)) {
return;
}

// shim sender stats.
if (!(‘getStats’ in window.RTCRtpSender.prototype)) {
var origGetSenders = window.RTCPeerConnection.prototype.getSenders;
if (origGetSenders) {
window.RTCPeerConnection.prototype.getSenders = function () {
var _this6 = this;

    var senders = origGetSenders.apply(this, []);
    senders.forEach(function (sender) {
      return sender._pc = _this6;
    });
    return senders;
  };
}

var origAddTrack = window.RTCPeerConnection.prototype.addTrack;
if (origAddTrack) {
  window.RTCPeerConnection.prototype.addTrack = function () {
    var sender = origAddTrack.apply(this, arguments);
    sender._pc = this;
    return sender;
  };
}
window.RTCRtpSender.prototype.getStats = function () {
  var sender = this;
  return this._pc.getStats().then(function (result) {
    return (
      /* Note: this will include stats of all senders that
       *   send a track with the same id as sender.track as
       *   it is not possible to identify the RTCRtpSender.
       */
      utils.filterStats(result, sender.track, true)
    );
  });
};

}

// shim receiver stats.
if (!(‘getStats’ in window.RTCRtpReceiver.prototype)) {
var origGetReceivers = window.RTCPeerConnection.prototype.getReceivers;
if (origGetReceivers) {
window.RTCPeerConnection.prototype.getReceivers = function () {
var _this7 = this;

    var receivers = origGetReceivers.apply(this, []);
    receivers.forEach(function (receiver) {
      return receiver._pc = _this7;
    });
    return receivers;
  };
}
utils.wrapPeerConnectionEvent(window, 'track', function (e) {
  e.receiver._pc = e.srcElement;
  return e;
});
window.RTCRtpReceiver.prototype.getStats = function () {
  var receiver = this;
  return this._pc.getStats().then(function (result) {
    return utils.filterStats(result, receiver.track, false);
  });
};

}

if (!(‘getStats’ in window.RTCRtpSender.prototype && ‘getStats’ in window.RTCRtpReceiver.prototype)) {
return;
}

// shim RTCPeerConnection.getStats(track).
var origGetStats = window.RTCPeerConnection.prototype.getStats;
window.RTCPeerConnection.prototype.getStats = function () {
if (arguments.length > 0 && arguments[0] instanceof window.MediaStreamTrack) {
var track = arguments[0];
var sender = void 0;
var receiver = void 0;
var err = void 0;
this.getSenders().forEach(function (s) {
if (s.track === track) {
if (sender) {
err = true;
} else {
sender = s;
}
}
});
this.getReceivers().forEach(function ® {
if (r.track === track) {
if (receiver) {
err = true;
} else {
receiver = r;
}
}
return r.track === track;
});
if (err || sender && receiver) {
return Promise.reject(new DOMException(‘There are more than one sender or receiver for the track.’, ‘InvalidAccessError’));
} else if (sender) {
return sender.getStats();
} else if (receiver) {
return receiver.getStats();
}
return Promise.reject(new DOMException(‘There is no sender or receiver for the track.’, ‘InvalidAccessError’));
}
return origGetStats.apply(this, arguments);
};
}

function shimAddTrackRemoveTrackWithNative(window) {
// shim addTrack/removeTrack with native variants in order to make
// the interactions with legacy getLocalStreams behave as in other browsers.
// Keeps a mapping stream.id => [stream, rtpsenders…]
window.RTCPeerConnection.prototype.getLocalStreams = function () {
var _this8 = this;

this._shimmedLocalStreams = this._shimmedLocalStreams || {};
return Object.keys(this._shimmedLocalStreams).map(function (streamId) {
  return _this8._shimmedLocalStreams[streamId][0];
});

};

var origAddTrack = window.RTCPeerConnection.prototype.addTrack;
window.RTCPeerConnection.prototype.addTrack = function (track, stream) {
if (!stream) {
return origAddTrack.apply(this, arguments);
}
this._shimmedLocalStreams = this._shimmedLocalStreams || {};

var sender = origAddTrack.apply(this, arguments);
if (!this._shimmedLocalStreams[stream.id]) {
  this._shimmedLocalStreams[stream.id] = [stream, sender];
} else if (this._shimmedLocalStreams[stream.id].indexOf(sender) === -1) {
  this._shimmedLocalStreams[stream.id].push(sender);
}
return sender;

};

var origAddStream = window.RTCPeerConnection.prototype.addStream;
window.RTCPeerConnection.prototype.addStream = function (stream) {
var _this9 = this;

this._shimmedLocalStreams = this._shimmedLocalStreams || {};

stream.getTracks().forEach(function (track) {
  var alreadyExists = _this9.getSenders().find(function (s) {
    return s.track === track;
  });
  if (alreadyExists) {
    throw new DOMException('Track already exists.', 'InvalidAccessError');
  }
});
var existingSenders = this.getSenders();
origAddStream.apply(this, arguments);
var newSenders = this.getSenders().filter(function (newSender) {
  return existingSenders.indexOf(newSender) === -1;
});
this._shimmedLocalStreams[stream.id] = [stream].concat(newSenders);

};

var origRemoveStream = window.RTCPeerConnection.prototype.removeStream;
window.RTCPeerConnection.prototype.removeStream = function (stream) {
this._shimmedLocalStreams = this._shimmedLocalStreams || {};
delete this._shimmedLocalStreams[stream.id];
return origRemoveStream.apply(this, arguments);
};

var origRemoveTrack = window.RTCPeerConnection.prototype.removeTrack;
window.RTCPeerConnection.prototype.removeTrack = function (sender) {
var _this10 = this;

this._shimmedLocalStreams = this._shimmedLocalStreams || {};
if (sender) {
  Object.keys(this._shimmedLocalStreams).forEach(function (streamId) {
    var idx = _this10._shimmedLocalStreams[streamId].indexOf(sender);
    if (idx !== -1) {
      _this10._shimmedLocalStreams[streamId].splice(idx, 1);
    }
    if (_this10._shimmedLocalStreams[streamId].length === 1) {
      delete _this10._shimmedLocalStreams[streamId];
    }
  });
}
return origRemoveTrack.apply(this, arguments);

};
}

function shimAddTrackRemoveTrack(window) {
if (!window.RTCPeerConnection) {
return;
}
var browserDetails = utils.detectBrowser(window);
// shim addTrack and removeTrack.
if (window.RTCPeerConnection.prototype.addTrack && browserDetails.version >= 65) {
return shimAddTrackRemoveTrackWithNative(window);
}

// also shim pc.getLocalStreams when addTrack is shimmed
// to return the original streams.
var origGetLocalStreams = window.RTCPeerConnection.prototype.getLocalStreams;
window.RTCPeerConnection.prototype.getLocalStreams = function () {
var _this11 = this;

var nativeStreams = origGetLocalStreams.apply(this);
this._reverseStreams = this._reverseStreams || {};
return nativeStreams.map(function (stream) {
  return _this11._reverseStreams[stream.id];
});

};

var origAddStream = window.RTCPeerConnection.prototype.addStream;
window.RTCPeerConnection.prototype.addStream = function (stream) {
var _this12 = this;

this._streams = this._streams || {};
this._reverseStreams = this._reverseStreams || {};

stream.getTracks().forEach(function (track) {
  var alreadyExists = _this12.getSenders().find(function (s) {
    return s.track === track;
  });
  if (alreadyExists) {
    throw new DOMException('Track already exists.', 'InvalidAccessError');
  }
});
// Add identity mapping for consistency with addTrack.
// Unless this is being used with a stream from addTrack.
if (!this._reverseStreams[stream.id]) {
  var newStream = new window.MediaStream(stream.getTracks());
  this._streams[stream.id] = newStream;
  this._reverseStreams[newStream.id] = stream;
  stream = newStream;
}
origAddStream.apply(this, [stream]);

};

var origRemoveStream = window.RTCPeerConnection.prototype.removeStream;
window.RTCPeerConnection.prototype.removeStream = function (stream) {
this._streams = this._streams || {};
this._reverseStreams = this._reverseStreams || {};

origRemoveStream.apply(this, [this._streams[stream.id] || stream]);
delete this._reverseStreams[this._streams[stream.id] ? this._streams[stream.id].id : stream.id];
delete this._streams[stream.id];

};

window.RTCPeerConnection.prototype.addTrack = function (track, stream) {
var _this13 = this;

if (this.signalingState === 'closed') {
  throw new DOMException('The RTCPeerConnection\'s signalingState is \'closed\'.', 'InvalidStateError');
}
var streams = [].slice.call(arguments, 1);
if (streams.length !== 1 || !streams[0].getTracks().find(function (t) {
  return t === track;
})) {
  // this is not fully correct but all we can manage without
  // [[associated MediaStreams]] internal slot.
  throw new DOMException('The adapter.js addTrack polyfill only supports a single ' + ' stream which is associated with the specified track.', 'NotSupportedError');
}

var alreadyExists = this.getSenders().find(function (s) {
  return s.track === track;
});
if (alreadyExists) {
  throw new DOMException('Track already exists.', 'InvalidAccessError');
}

this._streams = this._streams || {};
this._reverseStreams = this._reverseStreams || {};
var oldStream = this._streams[stream.id];
if (oldStream) {
  // this is using odd Chrome behaviour, use with caution:
  // https://bugs.chromium.org/p/webrtc/issues/detail?id=7815
  // Note: we rely on the high-level addTrack/dtmf shim to
  // create the sender with a dtmf sender.
  oldStream.addTrack(track);

  // Trigger ONN async.
  Promise.resolve().then(function () {
    _this13.dispatchEvent(new Event('negotiationneeded'));
  });
} else {
  var newStream = new window.MediaStream([track]);
  this._streams[stream.id] = newStream;
  this._reverseStreams[newStream.id] = stream;
  this.addStream(newStream);
}
return this.getSenders().find(function (s) {
  return s.track === track;
});

};

// replace the internal stream id with the external one and
// vice versa.
function replaceInternalStreamId(pc, description) {
var sdp = description.sdp;
Object.keys(pc._reverseStreams || []).forEach(function (internalId) {
var externalStream = pc._reverseStreams[internalId];
var internalStream = pc._streams[externalStream.id];
sdp = sdp.replace(new RegExp(internalStream.id, ‘g’), externalStream.id);
});
return new RTCSessionDescription({
type: description.type,
sdp: sdp
});
}
function replaceExternalStreamId(pc, description) {
var sdp = description.sdp;
Object.keys(pc._reverseStreams || []).forEach(function (internalId) {
var externalStream = pc._reverseStreams[internalId];
var internalStream = pc._streams[externalStream.id];
sdp = sdp.replace(new RegExp(externalStream.id, ‘g’), internalStream.id);
});
return new RTCSessionDescription({
type: description.type,
sdp: sdp
});
}
[‘createOffer’, ‘createAnswer’].forEach(function (method) {
var nativeMethod = window.RTCPeerConnection.prototype[method];
window.RTCPeerConnection.prototype[method] = function () {
var _this14 = this;

  var args = arguments;
  var isLegacyCall = arguments.length && typeof arguments[0] === 'function';
  if (isLegacyCall) {
    return nativeMethod.apply(this, [function (description) {
      var desc = replaceInternalStreamId(_this14, description);
      args[0].apply(null, [desc]);
    }, function (err) {
      if (args[1]) {
        args[1].apply(null, err);
      }
    }, arguments[2]]);
  }
  return nativeMethod.apply(this, arguments).then(function (description) {
    return replaceInternalStreamId(_this14, description);
  });
};

});

var origSetLocalDescription = window.RTCPeerConnection.prototype.setLocalDescription;
window.RTCPeerConnection.prototype.setLocalDescription = function () {
if (!arguments.length || !arguments[0].type) {
return origSetLocalDescription.apply(this, arguments);
}
arguments[0] = replaceExternalStreamId(this, arguments[0]);
return origSetLocalDescription.apply(this, arguments);
};

// TODO: mangle getStats: https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamstats-streamidentifier

var origLocalDescription = Object.getOwnPropertyDescriptor(window.RTCPeerConnection.prototype, ‘localDescription’);
Object.defineProperty(window.RTCPeerConnection.prototype, ‘localDescription’, {
get: function get() {
var description = origLocalDescription.get.apply(this);
if (description.type === ‘’) {
return description;
}
return replaceInternalStreamId(this, description);
}
});

window.RTCPeerConnection.prototype.removeTrack = function (sender) {
var _this15 = this;

if (this.signalingState === 'closed') {
  throw new DOMException('The RTCPeerConnection\'s signalingState is \'closed\'.', 'InvalidStateError');
}
// We can not yet check for sender instanceof RTCRtpSender
// since we shim RTPSender. So we check if sender._pc is set.
if (!sender._pc) {
  throw new DOMException('Argument 1 of RTCPeerConnection.removeTrack ' + 'does not implement interface RTCRtpSender.', 'TypeError');
}
var isLocal = sender._pc === this;
if (!isLocal) {
  throw new DOMException('Sender was not created by this connection.', 'InvalidAccessError');
}

// Search for the native stream the senders track belongs to.
this._streams = this._streams || {};
var stream = void 0;
Object.keys(this._streams).forEach(function (streamid) {
  var hasTrack = _this15._streams[streamid].getTracks().find(function (track) {
    return sender.track === track;
  });
  if (hasTrack) {
    stream = _this15._streams[streamid];
  }
});

if (stream) {
  if (stream.getTracks().length === 1) {
    // if this is the last track of the stream, remove the stream. This
    // takes care of any shimmed _senders.
    this.removeStream(this._reverseStreams[stream.id]);
  } else {
    // relying on the same odd chrome behaviour as above.
    stream.removeTrack(sender.track);
  }
  this.dispatchEvent(new Event('negotiationneeded'));
}

};
}

function shimPeerConnection(window) {
if (!window.RTCPeerConnection && window.webkitRTCPeerConnection) {
// very basic support for old versions.
window.RTCPeerConnection = window.webkitRTCPeerConnection;
}
if (!window.RTCPeerConnection) {
return;
}

// shim implicit creation of RTCSessionDescription/RTCIceCandidate
[‘setLocalDescription’, ‘setRemoteDescription’, ‘addIceCandidate’].forEach(function (method) {
var nativeMethod = window.RTCPeerConnection.prototype[method];
window.RTCPeerConnection.prototype[method] = function () {
arguments[0] = new (method === ‘addIceCandidate’ ? window.RTCIceCandidate : window.RTCSessionDescription)(arguments[0]);
return nativeMethod.apply(this, arguments);
};
});

// support for addIceCandidate(null or undefined)
var nativeAddIceCandidate = window.RTCPeerConnection.prototype.addIceCandidate;
window.RTCPeerConnection.prototype.addIceCandidate = function () {
if (!arguments[0]) {
if (arguments[1]) {
arguments[1].apply(null);
}
return Promise.resolve();
}
return nativeAddIceCandidate.apply(this, arguments);
};
}

function fixNegotiationNeeded(window) {
utils.wrapPeerConnectionEvent(window, ‘negotiationneeded’, function (e) {
var pc = e.target;
if (pc.signalingState !== ‘stable’) {
return;
}
return e;
});
}

},{"…/utils.js":15,"./getdisplaymedia":4,"./getusermedia":5}],4:[function(require,module,exports){
/*

  • Copyright © 2018 The adapter.js project authors. All Rights Reserved.
  • Use of this source code is governed by a BSD-style license
  • that can be found in the LICENSE file in the root of the source
  • tree.
    /
    /
    eslint-env node */
    ‘use strict’;

Object.defineProperty(exports, “__esModule”, {
value: true
});
exports.shimGetDisplayMedia = shimGetDisplayMedia;
function shimGetDisplayMedia(window, getSourceId) {
if (window.navigator.mediaDevices && ‘getDisplayMedia’ in window.navigator.mediaDevices) {
return;
}
if (!window.navigator.mediaDevices) {
return;
}
// getSourceId is a function that returns a promise resolving with
// the sourceId of the screen/window/tab to be shared.
if (typeof getSourceId !== ‘function’) {
console.error('shimGetDisplayMedia: getSourceId argument is not ’ + ‘a function’);
return;
}
window.navigator.mediaDevices.getDisplayMedia = function (constraints) {
return getSourceId(constraints).then(function (sourceId) {
var widthSpecified = constraints.video && constraints.video.width;
var heightSpecified = constraints.video && constraints.video.height;
var frameRateSpecified = constraints.video && constraints.video.frameRate;
constraints.video = {
mandatory: {
chromeMediaSource: ‘desktop’,
chromeMediaSourceId: sourceId,
maxFrameRate: frameRateSpecified || 3
}
};
if (widthSpecified) {
constraints.video.mandatory.maxWidth = widthSpecified;
}
if (heightSpecified) {
constraints.video.mandatory.maxHeight = heightSpecified;
}
return window.navigator.mediaDevices.getUserMedia(constraints);
});
};
}

},{}],5:[function(require,module,exports){
/*

  • Copyright © 2016 The WebRTC project authors. All Rights Reserved.
  • Use of this source code is governed by a BSD-style license
  • that can be found in the LICENSE file in the root of the source
  • tree.
    /
    /
    eslint-env node */
    ‘use strict’;

Object.defineProperty(exports, “__esModule”, {
value: true
});

var _typeof = typeof Symbol === “function” && typeof Symbol.iterator === “symbol” ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === “function” && obj.constructor === Symbol && obj !== Symbol.prototype ? “symbol” : typeof obj; };

exports.shimGetUserMedia = shimGetUserMedia;

var _utils = require(’…/utils.js’);

var utils = _interopRequireWildcard(_utils);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

var logging = utils.log;

function shimGetUserMedia(window) {
var navigator = window && window.navigator;

if (!navigator.mediaDevices) {
return;
}

var browserDetails = utils.detectBrowser(window);

var constraintsToChrome_ = function constraintsToChrome_© {
if ((typeof c === ‘undefined’ ? ‘undefined’ : typeof©) !== ‘object’ || c.mandatory || c.optional) {
return c;
}
var cc = {};
Object.keys©.forEach(function (key) {
if (key === ‘require’ || key === ‘advanced’ || key === ‘mediaSource’) {
return;
}
var r = typeof(c[key]) === ‘object’ ? c[key] : { ideal: c[key] };
if (r.exact !== undefined && typeof r.exact === ‘number’) {
r.min = r.max = r.exact;
}
var oldname
= function oldname
(prefix, name) {
if (pr

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Simple-Peer是一个基于JavaScript的WebRTC库,用于在浏览器中实现点对点通信。它提供了一种简单的方式来创建和管理WebRTC连接,并且支持数据通道和音视频通信。引用中的代码表明Simple-Peer禁止了拷贝和赋值操作,这是为了确保每个Simple-Peer对象都是唯一的。 引用简要介绍了STUN(Simple Traversal of User Datagram Protocol Through Network Address Translators)协议,它用于在锥形NAT下实现WebRTC的穿透功能。通过STUN协议,两个WebRTC终端可以通过暴露在公网上的地址进行直接通信。 引用中的代码示例演示了如何修改SDP(Session Description Protocol)来调整数据通道的传输速度限制。通过将SDP中的'b=AS:30'替换为'b=AS:262144',可以将传输速度限制提高到256K。 综上所述,Simple-Peer是一个用于实现WebRTC点对点通信的JavaScript库,它支持数据通道和音视频通信。同时,通过STUN协议和修改SDP,可以实现在不同网络环境下的穿透和调整传输速度的功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [【webrtc】SimplePeerConnection :一个webrtc 客户端简单实现](https://blog.csdn.net/commshare/article/details/114361543)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [WebRTC初学Demo](https://blog.csdn.net/holdsky/article/details/120841013)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宁静之峰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值