From 9f16b5c553b479ea12fe368a7ecc748872ea8b98 Mon Sep 17 00:00:00 2001 From: zxl <763096477@qq.com> Date: 星期四, 12 六月 2025 11:11:27 +0800 Subject: [PATCH] 修改配置文件 --- web_src/static/js/ZLMRTCClient.js | 1356 ++++++++++++++++++++++++++++++++++++++++++++-------------- 1 files changed, 1,016 insertions(+), 340 deletions(-) diff --git a/web_src/static/js/ZLMRTCClient.js b/web_src/static/js/ZLMRTCClient.js index 288028c..30a08ef 100644 --- a/web_src/static/js/ZLMRTCClient.js +++ b/web_src/static/js/ZLMRTCClient.js @@ -6,29 +6,37 @@ WEBRTC_ICE_CANDIDATE_ERROR: 'WEBRTC_ICE_CANDIDATE_ERROR', WEBRTC_OFFER_ANWSER_EXCHANGE_FAILED: 'WEBRTC_OFFER_ANWSER_EXCHANGE_FAILED', WEBRTC_ON_REMOTE_STREAMS: 'WEBRTC_ON_REMOTE_STREAMS', - WEBRTC_ON_LOCAL_STREAM: 'WEBRTC_ON_LOCAL_STREAM' + WEBRTC_ON_LOCAL_STREAM: 'WEBRTC_ON_LOCAL_STREAM', + WEBRTC_ON_CONNECTION_STATE_CHANGE: 'WEBRTC_ON_CONNECTION_STATE_CHANGE', + WEBRTC_ON_DATA_CHANNEL_OPEN: 'WEBRTC_ON_DATA_CHANNEL_OPEN', + WEBRTC_ON_DATA_CHANNEL_CLOSE: 'WEBRTC_ON_DATA_CHANNEL_CLOSE', + WEBRTC_ON_DATA_CHANNEL_ERR: 'WEBRTC_ON_DATA_CHANNEL_ERR', + WEBRTC_ON_DATA_CHANNEL_MSG: 'WEBRTC_ON_DATA_CHANNEL_MSG', + CAPTURE_STREAM_FAILED: 'CAPTURE_STREAM_FAILED' }; - const VERSION = '1.0.1'; - const BUILD_DATE = 'Mon Apr 05 2021 10:22:48 GMT+0800 (涓浗鏍囧噯鏃堕棿)'; + const VERSION$1 = '1.0.1'; + const BUILD_DATE = 'Mon Mar 27 2023 19:11:59 GMT+0800 (China Standard Time)'; // Copyright (C) <2018> Intel Corporation // // SPDX-License-Identifier: Apache-2.0 + // eslint-disable-next-line require-jsdoc function isFirefox() { return window.navigator.userAgent.match('Firefox') !== null; - } // eslint-disable-next-line require-jsdoc - + } + // eslint-disable-next-line require-jsdoc function isChrome() { return window.navigator.userAgent.match('Chrome') !== null; - } // eslint-disable-next-line require-jsdoc - + } + // eslint-disable-next-line require-jsdoc function isEdge() { return window.navigator.userAgent.match(/Edge\/(\d+).(\d+)$/) !== null; - } // eslint-disable-next-line require-jsdoc + } // Copyright (C) <2018> Intel Corporation + /** * @class AudioSourceInfo * @classDesc Source info about an audio track. Values: 'mic', 'screen-cast', 'file', 'mixed'. @@ -36,13 +44,13 @@ * @readonly * @enum {string} */ - const AudioSourceInfo = { MIC: 'mic', SCREENCAST: 'screen-cast', FILE: 'file', MIXED: 'mixed' }; + /** * @class VideoSourceInfo * @classDesc Source info about a video track. Values: 'camera', 'screen-cast', 'file', 'mixed'. @@ -50,13 +58,13 @@ * @readonly * @enum {string} */ - const VideoSourceInfo = { CAMERA: 'camera', SCREENCAST: 'screen-cast', FILE: 'file', MIXED: 'mixed' }; + /** * @class TrackKind * @classDesc Kind of a track. Values: 'audio' for audio track, 'video' for video track, 'av' for both audio and video tracks. @@ -64,20 +72,17 @@ * @readonly * @enum {string} */ - const TrackKind = { /** * Audio tracks. * @type string */ AUDIO: 'audio', - /** * Video tracks. * @type string */ VIDEO: 'video', - /** * Both audio and video tracks. * @type string @@ -92,7 +97,6 @@ * @param {number} width * @param {number} height */ - class Resolution { // eslint-disable-next-line require-jsdoc constructor(width, height) { @@ -107,10 +111,8 @@ * @instance * @memberof Owt.Base.Resolution */ - this.height = height; } - } /* @@ -5525,7 +5527,6 @@ * @constructor * @param {Owt.Base.AudioSourceInfo} source Source info of this audio track. */ - class AudioTrackConstraints { // eslint-disable-next-line require-jsdoc constructor(source) { @@ -5538,8 +5539,6 @@ * @desc Values could be "mic", "screen-cast", "file" or "mixed". * @instance */ - - this.source = source; /** * @member {string} deviceId @@ -5548,11 +5547,10 @@ * @instance * @see https://w3c.github.io/mediacapture-main/#def-constraint-deviceId */ - this.deviceId = undefined; } - } + /** * @class VideoTrackConstraints * @classDesc Constraints for creating a video MediaStreamTrack. @@ -5560,7 +5558,6 @@ * @constructor * @param {Owt.Base.VideoSourceInfo} source Source info of this video track. */ - class VideoTrackConstraints { // eslint-disable-next-line require-jsdoc constructor(source) { @@ -5573,8 +5570,6 @@ * @desc Values could be "camera", "screen-cast", "file" or "mixed". * @instance */ - - this.source = source; /** * @member {string} deviceId @@ -5585,22 +5580,21 @@ */ this.deviceId = undefined; + /** * @member {Owt.Base.Resolution} resolution * @memberof Owt.Base.VideoTrackConstraints * @instance */ - this.resolution = undefined; + /** * @member {number} frameRate * @memberof Owt.Base.VideoTrackConstraints * @instance */ - this.frameRate = undefined; } - } /** * @class StreamConstraints @@ -5610,7 +5604,6 @@ * @param {?Owt.Base.AudioTrackConstraints} audioConstraints * @param {?Owt.Base.VideoTrackConstraints} videoConstraints */ - class StreamConstraints { // eslint-disable-next-line require-jsdoc constructor(audioConstraints = false, videoConstraints = false) { @@ -5625,22 +5618,20 @@ * @memberof Owt.Base.MediaStreamDeviceConstraints * @instance */ - this.video = videoConstraints; } + } - } // eslint-disable-next-line require-jsdoc - + // eslint-disable-next-line require-jsdoc function isVideoConstrainsForScreenCast(constraints) { return typeof constraints.video === 'object' && constraints.video.source === VideoSourceInfo.SCREENCAST; } + /** * @class MediaStreamFactory * @classDesc A factory to create MediaStream. You can also create MediaStream by yourself. * @memberof Owt.Base */ - - class MediaStreamFactory { /** * @function createMediaStream @@ -5659,29 +5650,23 @@ if (typeof constraints !== 'object' || !constraints.audio && !constraints.video) { return Promise.reject(new TypeError('Invalid constrains')); } - if (!isVideoConstrainsForScreenCast(constraints) && typeof constraints.audio === 'object' && constraints.audio.source === AudioSourceInfo.SCREENCAST) { return Promise.reject(new TypeError('Cannot share screen without video.')); } - if (isVideoConstrainsForScreenCast(constraints) && !isChrome() && !isFirefox()) { return Promise.reject(new TypeError('Screen sharing only supports Chrome and Firefox.')); } - if (isVideoConstrainsForScreenCast(constraints) && typeof constraints.audio === 'object' && constraints.audio.source !== AudioSourceInfo.SCREENCAST) { return Promise.reject(new TypeError('Cannot capture video from screen cast while capture audio from' + ' other source.')); - } // Check and convert constraints. + } - + // Check and convert constraints. if (!constraints.audio && !constraints.video) { return Promise.reject(new TypeError('At least one of audio and video must be requested.')); } - const mediaConstraints = Object.create({}); - if (typeof constraints.audio === 'object' && constraints.audio.source === AudioSourceInfo.MIC) { mediaConstraints.audio = Object.create({}); - if (isEdge()) { mediaConstraints.audio.deviceId = constraints.audio.deviceId; } else { @@ -5696,14 +5681,11 @@ mediaConstraints.audio = constraints.audio; } } - if (typeof constraints.video === 'object') { mediaConstraints.video = Object.create({}); - if (typeof constraints.video.frameRate === 'number') { mediaConstraints.video.frameRate = constraints.video.frameRate; } - if (constraints.video.resolution && constraints.video.resolution.width && constraints.video.resolution.height) { if (constraints.video.source === VideoSourceInfo.SCREENCAST) { mediaConstraints.video.width = constraints.video.resolution.width; @@ -5715,27 +5697,23 @@ mediaConstraints.video.height.exact = constraints.video.resolution.height; } } - if (typeof constraints.video.deviceId === 'string') { mediaConstraints.video.deviceId = { exact: constraints.video.deviceId }; } - if (isFirefox() && constraints.video.source === VideoSourceInfo.SCREENCAST) { mediaConstraints.video.mediaSource = 'screen'; } } else { mediaConstraints.video = constraints.video; } - if (isVideoConstrainsForScreenCast(constraints)) { return navigator.mediaDevices.getDisplayMedia(mediaConstraints); } else { return navigator.mediaDevices.getUserMedia(mediaConstraints); } } - } // Copyright (C) <2018> Intel Corporation @@ -5776,34 +5754,26 @@ this.listener = {}; this.type = type | ''; } - on(event, fn) { if (!this.listener[event]) { this.listener[event] = []; } - this.listener[event].push(fn); return true; } - off(event, fn) { if (this.listener[event]) { var index = this.listener[event].indexOf(fn); - if (index > -1) { this.listener[event].splice(index, 1); } - return true; } - return false; } - offAll() { this.listener = {}; } - dispatch(event, data) { if (this.listener[event]) { this.listener[event].map(each => { @@ -5811,10 +5781,8 @@ }); return true; } - return false; } - } var bind = function bind(fn, thisArg) { @@ -5827,11 +5795,25 @@ }; }; - /*global toString:true*/ - // utils is a library of generic helper functions non-specific to axios var toString = Object.prototype.toString; + + // eslint-disable-next-line func-names + var kindOf = (function(cache) { + // eslint-disable-next-line func-names + return function(thing) { + var str = toString.call(thing); + return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase()); + }; + })(Object.create(null)); + + function kindOfTest(type) { + type = type.toLowerCase(); + return function isKindOf(thing) { + return kindOf(thing) === type; + }; + } /** * Determine if a value is an Array @@ -5840,7 +5822,7 @@ * @returns {boolean} True if value is an Array, otherwise false */ function isArray(val) { - return toString.call(val) === '[object Array]'; + return Array.isArray(val); } /** @@ -5867,22 +5849,12 @@ /** * Determine if a value is an ArrayBuffer * + * @function * @param {Object} val The value to test * @returns {boolean} True if value is an ArrayBuffer, otherwise false */ - function isArrayBuffer(val) { - return toString.call(val) === '[object ArrayBuffer]'; - } + var isArrayBuffer = kindOfTest('ArrayBuffer'); - /** - * Determine if a value is a FormData - * - * @param {Object} val The value to test - * @returns {boolean} True if value is an FormData, otherwise false - */ - function isFormData(val) { - return (typeof FormData !== 'undefined') && (val instanceof FormData); - } /** * Determine if a value is a view on an ArrayBuffer @@ -5895,7 +5867,7 @@ if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) { result = ArrayBuffer.isView(val); } else { - result = (val) && (val.buffer) && (val.buffer instanceof ArrayBuffer); + result = (val) && (val.buffer) && (isArrayBuffer(val.buffer)); } return result; } @@ -5937,7 +5909,7 @@ * @return {boolean} True if value is a plain Object, otherwise false */ function isPlainObject(val) { - if (toString.call(val) !== '[object Object]') { + if (kindOf(val) !== 'object') { return false; } @@ -5948,32 +5920,38 @@ /** * Determine if a value is a Date * + * @function * @param {Object} val The value to test * @returns {boolean} True if value is a Date, otherwise false */ - function isDate(val) { - return toString.call(val) === '[object Date]'; - } + var isDate = kindOfTest('Date'); /** * Determine if a value is a File * + * @function * @param {Object} val The value to test * @returns {boolean} True if value is a File, otherwise false */ - function isFile(val) { - return toString.call(val) === '[object File]'; - } + var isFile = kindOfTest('File'); /** * Determine if a value is a Blob * + * @function * @param {Object} val The value to test * @returns {boolean} True if value is a Blob, otherwise false */ - function isBlob(val) { - return toString.call(val) === '[object Blob]'; - } + var isBlob = kindOfTest('Blob'); + + /** + * Determine if a value is a FileList + * + * @function + * @param {Object} val The value to test + * @returns {boolean} True if value is a File, otherwise false + */ + var isFileList = kindOfTest('FileList'); /** * Determine if a value is a Function @@ -5996,14 +5974,27 @@ } /** - * Determine if a value is a URLSearchParams object + * Determine if a value is a FormData * + * @param {Object} thing The value to test + * @returns {boolean} True if value is an FormData, otherwise false + */ + function isFormData(thing) { + var pattern = '[object FormData]'; + return thing && ( + (typeof FormData === 'function' && thing instanceof FormData) || + toString.call(thing) === pattern || + (isFunction(thing.toString) && thing.toString() === pattern) + ); + } + + /** + * Determine if a value is a URLSearchParams object + * @function * @param {Object} val The value to test * @returns {boolean} True if value is a URLSearchParams object, otherwise false */ - function isURLSearchParams(val) { - return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams; - } + var isURLSearchParams = kindOfTest('URLSearchParams'); /** * Trim excess whitespace off the beginning and end of a string @@ -6012,7 +6003,7 @@ * @returns {String} The String freed of excess whitespace */ function trim(str) { - return str.replace(/^\s*/, '').replace(/\s*$/, ''); + return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, ''); } /** @@ -6150,6 +6141,94 @@ return content; } + /** + * Inherit the prototype methods from one constructor into another + * @param {function} constructor + * @param {function} superConstructor + * @param {object} [props] + * @param {object} [descriptors] + */ + + function inherits(constructor, superConstructor, props, descriptors) { + constructor.prototype = Object.create(superConstructor.prototype, descriptors); + constructor.prototype.constructor = constructor; + props && Object.assign(constructor.prototype, props); + } + + /** + * Resolve object with deep prototype chain to a flat object + * @param {Object} sourceObj source object + * @param {Object} [destObj] + * @param {Function} [filter] + * @returns {Object} + */ + + function toFlatObject(sourceObj, destObj, filter) { + var props; + var i; + var prop; + var merged = {}; + + destObj = destObj || {}; + + do { + props = Object.getOwnPropertyNames(sourceObj); + i = props.length; + while (i-- > 0) { + prop = props[i]; + if (!merged[prop]) { + destObj[prop] = sourceObj[prop]; + merged[prop] = true; + } + } + sourceObj = Object.getPrototypeOf(sourceObj); + } while (sourceObj && (!filter || filter(sourceObj, destObj)) && sourceObj !== Object.prototype); + + return destObj; + } + + /* + * determines whether a string ends with the characters of a specified string + * @param {String} str + * @param {String} searchString + * @param {Number} [position= 0] + * @returns {boolean} + */ + function endsWith(str, searchString, position) { + str = String(str); + if (position === undefined || position > str.length) { + position = str.length; + } + position -= searchString.length; + var lastIndex = str.indexOf(searchString, position); + return lastIndex !== -1 && lastIndex === position; + } + + + /** + * Returns new array from array like object + * @param {*} [thing] + * @returns {Array} + */ + function toArray(thing) { + if (!thing) return null; + var i = thing.length; + if (isUndefined(i)) return null; + var arr = new Array(i); + while (i-- > 0) { + arr[i] = thing[i]; + } + return arr; + } + + // eslint-disable-next-line func-names + var isTypedArray = (function(TypedArray) { + // eslint-disable-next-line func-names + return function(thing) { + return TypedArray && thing instanceof TypedArray; + }; + })(typeof Uint8Array !== 'undefined' && Object.getPrototypeOf(Uint8Array)); + var utils = { isArray: isArray, isArrayBuffer: isArrayBuffer, @@ -6172,7 +6251,15 @@ merge: merge, extend: extend, trim: trim, - stripBOM: stripBOM + stripBOM: stripBOM, + inherits: inherits, + toFlatObject: toFlatObject, + kindOf: kindOf, + kindOfTest: kindOfTest, + endsWith: endsWith, + toArray: toArray, + isTypedArray: isTypedArray, + isFileList: isFileList }; function encode(val) { @@ -6254,10 +6341,12 @@ * * @return {Number} An ID used to remove interceptor later */ - InterceptorManager.prototype.use = function use(fulfilled, rejected) { + InterceptorManager.prototype.use = function use(fulfilled, rejected, options) { this.handlers.push({ fulfilled: fulfilled, - rejected: rejected + rejected: rejected, + synchronous: options ? options.synchronous : false, + runWhen: options ? options.runWhen : null }); return this.handlers.length - 1; }; @@ -6291,27 +6380,6 @@ var InterceptorManager_1 = InterceptorManager; - /** - * Transform the data for a request or a response - * - * @param {Object|String} data The data to be transformed - * @param {Array} headers The headers for the request or response - * @param {Array|Function} fns A single function or Array of functions - * @returns {*} The resulting transformed data - */ - var transformData = function transformData(data, headers, fns) { - /*eslint no-param-reassign:0*/ - utils.forEach(fns, function transform(fn) { - data = fn(data, headers); - }); - - return data; - }; - - var isCancel = function isCancel(value) { - return !!(value && value.__CANCEL__); - }; - var normalizeHeaderName = function normalizeHeaderName(headers, normalizedName) { utils.forEach(headers, function processHeader(value, name) { if (name !== normalizedName && name.toUpperCase() === normalizedName.toUpperCase()) { @@ -6322,26 +6390,27 @@ }; /** - * Update an Error with the specified config, error code, and response. + * Create an Error with the specified message, config, error code, request and response. * - * @param {Error} error The error to update. - * @param {Object} config The config. + * @param {string} message The error message. * @param {string} [code] The error code (for example, 'ECONNABORTED'). + * @param {Object} [config] The config. * @param {Object} [request] The request. * @param {Object} [response] The response. - * @returns {Error} The error. + * @returns {Error} The created error. */ - var enhanceError = function enhanceError(error, config, code, request, response) { - error.config = config; - if (code) { - error.code = code; - } + function AxiosError(message, code, config, request, response) { + Error.call(this); + this.message = message; + this.name = 'AxiosError'; + code && (this.code = code); + config && (this.config = config); + request && (this.request = request); + response && (this.response = response); + } - error.request = request; - error.response = response; - error.isAxiosError = true; - - error.toJSON = function toJSON() { + utils.inherits(AxiosError, Error, { + toJSON: function toJSON() { return { // Standard message: this.message, @@ -6356,26 +6425,127 @@ stack: this.stack, // Axios config: this.config, - code: this.code + code: this.code, + status: this.response && this.response.status ? this.response.status : null }; - }; - return error; + } + }); + + var prototype = AxiosError.prototype; + var descriptors = {}; + + [ + 'ERR_BAD_OPTION_VALUE', + 'ERR_BAD_OPTION', + 'ECONNABORTED', + 'ETIMEDOUT', + 'ERR_NETWORK', + 'ERR_FR_TOO_MANY_REDIRECTS', + 'ERR_DEPRECATED', + 'ERR_BAD_RESPONSE', + 'ERR_BAD_REQUEST', + 'ERR_CANCELED' + // eslint-disable-next-line func-names + ].forEach(function(code) { + descriptors[code] = {value: code}; + }); + + Object.defineProperties(AxiosError, descriptors); + Object.defineProperty(prototype, 'isAxiosError', {value: true}); + + // eslint-disable-next-line func-names + AxiosError.from = function(error, code, config, request, response, customProps) { + var axiosError = Object.create(prototype); + + utils.toFlatObject(error, axiosError, function filter(obj) { + return obj !== Error.prototype; + }); + + AxiosError.call(axiosError, error.message, code, config, request, response); + + axiosError.name = error.name; + + customProps && Object.assign(axiosError, customProps); + + return axiosError; + }; + + var AxiosError_1 = AxiosError; + + var transitional = { + silentJSONParsing: true, + forcedJSONParsing: true, + clarifyTimeoutError: false }; /** - * Create an Error with the specified message, config, error code, request and response. - * - * @param {string} message The error message. - * @param {Object} config The config. - * @param {string} [code] The error code (for example, 'ECONNABORTED'). - * @param {Object} [request] The request. - * @param {Object} [response] The response. - * @returns {Error} The created error. - */ - var createError = function createError(message, config, code, request, response) { - var error = new Error(message); - return enhanceError(error, config, code, request, response); - }; + * Convert a data object to FormData + * @param {Object} obj + * @param {?Object} [formData] + * @returns {Object} + **/ + + function toFormData(obj, formData) { + // eslint-disable-next-line no-param-reassign + formData = formData || new FormData(); + + var stack = []; + + function convertValue(value) { + if (value === null) return ''; + + if (utils.isDate(value)) { + return value.toISOString(); + } + + if (utils.isArrayBuffer(value) || utils.isTypedArray(value)) { + return typeof Blob === 'function' ? new Blob([value]) : Buffer.from(value); + } + + return value; + } + + function build(data, parentKey) { + if (utils.isPlainObject(data) || utils.isArray(data)) { + if (stack.indexOf(data) !== -1) { + throw Error('Circular reference detected in ' + parentKey); + } + + stack.push(data); + + utils.forEach(data, function each(value, key) { + if (utils.isUndefined(value)) return; + var fullKey = parentKey ? parentKey + '.' + key : key; + var arr; + + if (value && !parentKey && typeof value === 'object') { + if (utils.endsWith(key, '{}')) { + // eslint-disable-next-line no-param-reassign + value = JSON.stringify(value); + } else if (utils.endsWith(key, '[]') && (arr = utils.toArray(value))) { + // eslint-disable-next-line func-names + arr.forEach(function(el) { + !utils.isUndefined(el) && formData.append(fullKey, convertValue(el)); + }); + return; + } + } + + build(value, fullKey); + }); + + stack.pop(); + } else { + formData.append(parentKey, convertValue(data)); + } + } + + build(obj); + + return formData; + } + + var toFormData_1 = toFormData; /** * Resolve or reject a Promise based on response status. @@ -6389,10 +6559,10 @@ if (!response.status || !validateStatus || validateStatus(response.status)) { resolve(response); } else { - reject(createError( + reject(new AxiosError_1( 'Request failed with status code ' + response.status, + [AxiosError_1.ERR_BAD_REQUEST, AxiosError_1.ERR_BAD_RESPONSE][Math.floor(response.status / 100) - 4], response.config, - null, response.request, response )); @@ -6459,7 +6629,7 @@ // A URL is considered absolute if it begins with "<scheme>://" or "//" (protocol-relative URL). // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed // by any combination of letters, digits, plus, period, or hyphen. - return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url); + return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url); }; /** @@ -6606,12 +6776,46 @@ })() ); + /** + * A `CanceledError` is an object that is thrown when an operation is canceled. + * + * @class + * @param {string=} message The message. + */ + function CanceledError(message) { + // eslint-disable-next-line no-eq-null,eqeqeq + AxiosError_1.call(this, message == null ? 'canceled' : message, AxiosError_1.ERR_CANCELED); + this.name = 'CanceledError'; + } + + utils.inherits(CanceledError, AxiosError_1, { + __CANCEL__: true + }); + + var CanceledError_1 = CanceledError; + + var parseProtocol = function parseProtocol(url) { + var match = /^([-+\w]{1,25})(:?\/\/|:)/.exec(url); + return match && match[1] || ''; + }; + var xhr = function xhrAdapter(config) { return new Promise(function dispatchXhrRequest(resolve, reject) { var requestData = config.data; var requestHeaders = config.headers; + var responseType = config.responseType; + var onCanceled; + function done() { + if (config.cancelToken) { + config.cancelToken.unsubscribe(onCanceled); + } - if (utils.isFormData(requestData)) { + if (config.signal) { + config.signal.removeEventListener('abort', onCanceled); + } + } + + if (utils.isFormData(requestData) && utils.isStandardBrowserEnv()) { delete requestHeaders['Content-Type']; // Let the browser set it } @@ -6625,28 +6829,20 @@ } var fullPath = buildFullPath(config.baseURL, config.url); + request.open(config.method.toUpperCase(), buildURL(fullPath, config.params, config.paramsSerializer), true); // Set the request timeout in MS request.timeout = config.timeout; - // Listen for ready state - request.onreadystatechange = function handleLoad() { - if (!request || request.readyState !== 4) { + function onloadend() { + if (!request) { return; } - - // The request errored out and we didn't get a response, this will be - // handled by onerror instead - // With one exception: request that using file: protocol, most browsers - // will return status as 0 even though it's a successful request - if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) { - return; - } - // Prepare the response var responseHeaders = 'getAllResponseHeaders' in request ? parseHeaders(request.getAllResponseHeaders()) : null; - var responseData = !config.responseType || config.responseType === 'text' ? request.responseText : request.response; + var responseData = !responseType || responseType === 'text' || responseType === 'json' ? + request.responseText : request.response; var response = { data: responseData, status: request.status, @@ -6656,11 +6852,40 @@ request: request }; - settle(resolve, reject, response); + settle(function _resolve(value) { + resolve(value); + done(); + }, function _reject(err) { + reject(err); + done(); + }, response); // Clean up request request = null; - }; + } + + if ('onloadend' in request) { + // Use onloadend if available + request.onloadend = onloadend; + } else { + // Listen for ready state to emulate onloadend + request.onreadystatechange = function handleLoad() { + if (!request || request.readyState !== 4) { + return; + } + + // The request errored out and we didn't get a response, this will be + // handled by onerror instead + // With one exception: request that using file: protocol, most browsers + // will return status as 0 even though it's a successful request + if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) { + return; + } + // readystate handler is calling before onerror or ontimeout handlers, + // so we should call onloadend on the next 'tick' + setTimeout(onloadend); + }; + } // Handle browser request cancellation (as opposed to a manual cancellation) request.onabort = function handleAbort() { @@ -6668,7 +6893,7 @@ return; } - reject(createError('Request aborted', config, 'ECONNABORTED', request)); + reject(new AxiosError_1('Request aborted', AxiosError_1.ECONNABORTED, config, request)); // Clean up request request = null; @@ -6678,7 +6903,7 @@ request.onerror = function handleError() { // Real errors are hidden from us by the browser // onerror should only fire if it's a network error - reject(createError('Network Error', config, null, request)); + reject(new AxiosError_1('Network Error', AxiosError_1.ERR_NETWORK, config, request, request)); // Clean up request request = null; @@ -6686,11 +6911,15 @@ // Handle timeout request.ontimeout = function handleTimeout() { - var timeoutErrorMessage = 'timeout of ' + config.timeout + 'ms exceeded'; + var timeoutErrorMessage = config.timeout ? 'timeout of ' + config.timeout + 'ms exceeded' : 'timeout exceeded'; + var transitional$1 = config.transitional || transitional; if (config.timeoutErrorMessage) { timeoutErrorMessage = config.timeoutErrorMessage; } - reject(createError(timeoutErrorMessage, config, 'ECONNABORTED', + reject(new AxiosError_1( + timeoutErrorMessage, + transitional$1.clarifyTimeoutError ? AxiosError_1.ETIMEDOUT : AxiosError_1.ECONNABORTED, + config, request)); // Clean up request @@ -6730,16 +6959,8 @@ } // Add responseType to request if needed - if (config.responseType) { - try { - request.responseType = config.responseType; - } catch (e) { - // Expected DOMException thrown by browsers not compatible XMLHttpRequest Level 2. - // But, this can be suppressed for 'json' type as it can be parsed by default 'transformResponse' function. - if (config.responseType !== 'json') { - throw e; - } - } + if (responseType && responseType !== 'json') { + request.responseType = config.responseType; } // Handle progress if needed @@ -6752,28 +6973,43 @@ request.upload.addEventListener('progress', config.onUploadProgress); } - if (config.cancelToken) { + if (config.cancelToken || config.signal) { // Handle cancellation - config.cancelToken.promise.then(function onCanceled(cancel) { + // eslint-disable-next-line func-names + onCanceled = function(cancel) { if (!request) { return; } - + reject(!cancel || (cancel && cancel.type) ? new CanceledError_1() : cancel); request.abort(); - reject(cancel); - // Clean up request request = null; - }); + }; + + config.cancelToken && config.cancelToken.subscribe(onCanceled); + if (config.signal) { + config.signal.aborted ? onCanceled() : config.signal.addEventListener('abort', onCanceled); + } } if (!requestData) { requestData = null; } + var protocol = parseProtocol(fullPath); + + if (protocol && [ 'http', 'https', 'file' ].indexOf(protocol) === -1) { + reject(new AxiosError_1('Unsupported protocol ' + protocol + ':', AxiosError_1.ERR_BAD_REQUEST, config)); + return; + } + + // Send the request request.send(requestData); }); }; + + // eslint-disable-next-line strict + var _null = null; var DEFAULT_CONTENT_TYPE = { 'Content-Type': 'application/x-www-form-urlencoded' @@ -6797,12 +7033,31 @@ return adapter; } + function stringifySafely(rawValue, parser, encoder) { + if (utils.isString(rawValue)) { + try { + (parser || JSON.parse)(rawValue); + return utils.trim(rawValue); + } catch (e) { + if (e.name !== 'SyntaxError') { + throw e; + } + } + } + + return (encoder || JSON.stringify)(rawValue); + } + var defaults = { + + transitional: transitional, + adapter: getDefaultAdapter(), transformRequest: [function transformRequest(data, headers) { normalizeHeaderName(headers, 'Accept'); normalizeHeaderName(headers, 'Content-Type'); + if (utils.isFormData(data) || utils.isArrayBuffer(data) || utils.isBuffer(data) || @@ -6819,20 +7074,42 @@ setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8'); return data.toString(); } - if (utils.isObject(data)) { - setContentTypeIfUnset(headers, 'application/json;charset=utf-8'); - return JSON.stringify(data); + + var isObjectPayload = utils.isObject(data); + var contentType = headers && headers['Content-Type']; + + var isFileList; + + if ((isFileList = utils.isFileList(data)) || (isObjectPayload && contentType === 'multipart/form-data')) { + var _FormData = this.env && this.env.FormData; + return toFormData_1(isFileList ? {'files[]': data} : data, _FormData && new _FormData()); + } else if (isObjectPayload || contentType === 'application/json') { + setContentTypeIfUnset(headers, 'application/json'); + return stringifySafely(data); } + return data; }], transformResponse: [function transformResponse(data) { - /*eslint no-param-reassign:0*/ - if (typeof data === 'string') { + var transitional = this.transitional || defaults.transitional; + var silentJSONParsing = transitional && transitional.silentJSONParsing; + var forcedJSONParsing = transitional && transitional.forcedJSONParsing; + var strictJSONParsing = !silentJSONParsing && this.responseType === 'json'; + + if (strictJSONParsing || (forcedJSONParsing && utils.isString(data) && data.length)) { try { - data = JSON.parse(data); - } catch (e) { /* Ignore */ } + return JSON.parse(data); + } catch (e) { + if (strictJSONParsing) { + if (e.name === 'SyntaxError') { + throw AxiosError_1.from(e, AxiosError_1.ERR_BAD_RESPONSE, this, null, this.response); + } + throw e; + } + } } + return data; }], @@ -6848,14 +7125,18 @@ maxContentLength: -1, maxBodyLength: -1, + env: { + FormData: _null + }, + validateStatus: function validateStatus(status) { return status >= 200 && status < 300; - } - }; + }, - defaults.headers = { - common: { - 'Accept': 'application/json, text/plain, */*' + headers: { + common: { + 'Accept': 'application/json, text/plain, */*' + } } }; @@ -6870,11 +7151,37 @@ var defaults_1 = defaults; /** - * Throws a `Cancel` if cancellation has been requested. + * Transform the data for a request or a response + * + * @param {Object|String} data The data to be transformed + * @param {Array} headers The headers for the request or response + * @param {Array|Function} fns A single function or Array of functions + * @returns {*} The resulting transformed data + */ + var transformData = function transformData(data, headers, fns) { + var context = this || defaults_1; + /*eslint no-param-reassign:0*/ + utils.forEach(fns, function transform(fn) { + data = fn.call(context, data, headers); + }); + + return data; + }; + + var isCancel = function isCancel(value) { + return !!(value && value.__CANCEL__); + }; + + /** + * Throws a `CanceledError` if cancellation has been requested. */ function throwIfCancellationRequested(config) { if (config.cancelToken) { config.cancelToken.throwIfRequested(); + } + + if (config.signal && config.signal.aborted) { + throw new CanceledError_1(); } } @@ -6891,7 +7198,8 @@ config.headers = config.headers || {}; // Transform request data - config.data = transformData( + config.data = transformData.call( + config, config.data, config.headers, config.transformRequest @@ -6917,7 +7225,8 @@ throwIfCancellationRequested(config); // Transform response data - response.data = transformData( + response.data = transformData.call( + config, response.data, response.headers, config.transformResponse @@ -6930,7 +7239,8 @@ // Transform response data if (reason && reason.response) { - reason.response.data = transformData( + reason.response.data = transformData.call( + config, reason.response.data, reason.response.headers, config.transformResponse @@ -6955,17 +7265,6 @@ config2 = config2 || {}; var config = {}; - var valueFromConfig2Keys = ['url', 'method', 'data']; - var mergeDeepPropertiesKeys = ['headers', 'auth', 'proxy', 'params']; - var defaultToConfig2Keys = [ - 'baseURL', 'transformRequest', 'transformResponse', 'paramsSerializer', - 'timeout', 'timeoutMessage', 'withCredentials', 'adapter', 'responseType', 'xsrfCookieName', - 'xsrfHeaderName', 'onUploadProgress', 'onDownloadProgress', 'decompress', - 'maxContentLength', 'maxBodyLength', 'maxRedirects', 'transport', 'httpAgent', - 'httpsAgent', 'cancelToken', 'socketPath', 'responseEncoding' - ]; - var directMergeKeys = ['validateStatus']; - function getMergedValue(target, source) { if (utils.isPlainObject(target) && utils.isPlainObject(source)) { return utils.merge(target, source); @@ -6977,55 +7276,169 @@ return source; } + // eslint-disable-next-line consistent-return function mergeDeepProperties(prop) { if (!utils.isUndefined(config2[prop])) { - config[prop] = getMergedValue(config1[prop], config2[prop]); + return getMergedValue(config1[prop], config2[prop]); } else if (!utils.isUndefined(config1[prop])) { - config[prop] = getMergedValue(undefined, config1[prop]); + return getMergedValue(undefined, config1[prop]); } } - utils.forEach(valueFromConfig2Keys, function valueFromConfig2(prop) { + // eslint-disable-next-line consistent-return + function valueFromConfig2(prop) { if (!utils.isUndefined(config2[prop])) { - config[prop] = getMergedValue(undefined, config2[prop]); + return getMergedValue(undefined, config2[prop]); } - }); + } - utils.forEach(mergeDeepPropertiesKeys, mergeDeepProperties); - - utils.forEach(defaultToConfig2Keys, function defaultToConfig2(prop) { + // eslint-disable-next-line consistent-return + function defaultToConfig2(prop) { if (!utils.isUndefined(config2[prop])) { - config[prop] = getMergedValue(undefined, config2[prop]); + return getMergedValue(undefined, config2[prop]); } else if (!utils.isUndefined(config1[prop])) { - config[prop] = getMergedValue(undefined, config1[prop]); + return getMergedValue(undefined, config1[prop]); } - }); + } - utils.forEach(directMergeKeys, function merge(prop) { + // eslint-disable-next-line consistent-return + function mergeDirectKeys(prop) { if (prop in config2) { - config[prop] = getMergedValue(config1[prop], config2[prop]); + return getMergedValue(config1[prop], config2[prop]); } else if (prop in config1) { - config[prop] = getMergedValue(undefined, config1[prop]); + return getMergedValue(undefined, config1[prop]); } + } + + var mergeMap = { + 'url': valueFromConfig2, + 'method': valueFromConfig2, + 'data': valueFromConfig2, + 'baseURL': defaultToConfig2, + 'transformRequest': defaultToConfig2, + 'transformResponse': defaultToConfig2, + 'paramsSerializer': defaultToConfig2, + 'timeout': defaultToConfig2, + 'timeoutMessage': defaultToConfig2, + 'withCredentials': defaultToConfig2, + 'adapter': defaultToConfig2, + 'responseType': defaultToConfig2, + 'xsrfCookieName': defaultToConfig2, + 'xsrfHeaderName': defaultToConfig2, + 'onUploadProgress': defaultToConfig2, + 'onDownloadProgress': defaultToConfig2, + 'decompress': defaultToConfig2, + 'maxContentLength': defaultToConfig2, + 'maxBodyLength': defaultToConfig2, + 'beforeRedirect': defaultToConfig2, + 'transport': defaultToConfig2, + 'httpAgent': defaultToConfig2, + 'httpsAgent': defaultToConfig2, + 'cancelToken': defaultToConfig2, + 'socketPath': defaultToConfig2, + 'responseEncoding': defaultToConfig2, + 'validateStatus': mergeDirectKeys + }; + + utils.forEach(Object.keys(config1).concat(Object.keys(config2)), function computeConfigValue(prop) { + var merge = mergeMap[prop] || mergeDeepProperties; + var configValue = merge(prop); + (utils.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue); }); - - var axiosKeys = valueFromConfig2Keys - .concat(mergeDeepPropertiesKeys) - .concat(defaultToConfig2Keys) - .concat(directMergeKeys); - - var otherKeys = Object - .keys(config1) - .concat(Object.keys(config2)) - .filter(function filterAxiosKeys(key) { - return axiosKeys.indexOf(key) === -1; - }); - - utils.forEach(otherKeys, mergeDeepProperties); return config; }; + var data = { + "version": "0.27.2" + }; + + var VERSION = data.version; + + + var validators$1 = {}; + + // eslint-disable-next-line func-names + ['object', 'boolean', 'number', 'function', 'string', 'symbol'].forEach(function(type, i) { + validators$1[type] = function validator(thing) { + return typeof thing === type || 'a' + (i < 1 ? 'n ' : ' ') + type; + }; + }); + + var deprecatedWarnings = {}; + + /** + * Transitional option validator + * @param {function|boolean?} validator - set to false if the transitional option has been removed + * @param {string?} version - deprecated version / removed since version + * @param {string?} message - some message with additional info + * @returns {function} + */ + validators$1.transitional = function transitional(validator, version, message) { + function formatMessage(opt, desc) { + return '[Axios v' + VERSION + '] Transitional option \'' + opt + '\'' + desc + (message ? '. ' + message : ''); + } + + // eslint-disable-next-line func-names + return function(value, opt, opts) { + if (validator === false) { + throw new AxiosError_1( + formatMessage(opt, ' has been removed' + (version ? ' in ' + version : '')), + AxiosError_1.ERR_DEPRECATED + ); + } + + if (version && !deprecatedWarnings[opt]) { + deprecatedWarnings[opt] = true; + // eslint-disable-next-line no-console + console.warn( + formatMessage( + opt, + ' has been deprecated since v' + version + ' and will be removed in the near future' + ) + ); + } + + return validator ? validator(value, opt, opts) : true; + }; + }; + + /** + * Assert object's properties type + * @param {object} options + * @param {object} schema + * @param {boolean?} allowUnknown + */ + + function assertOptions(options, schema, allowUnknown) { + if (typeof options !== 'object') { + throw new AxiosError_1('options must be an object', AxiosError_1.ERR_BAD_OPTION_VALUE); + } + var keys = Object.keys(options); + var i = keys.length; + while (i-- > 0) { + var opt = keys[i]; + var validator = schema[opt]; + if (validator) { + var value = options[opt]; + var result = value === undefined || validator(value, opt, options); + if (result !== true) { + throw new AxiosError_1('option ' + opt + ' must be ' + result, AxiosError_1.ERR_BAD_OPTION_VALUE); + } + continue; + } + if (allowUnknown !== true) { + throw new AxiosError_1('Unknown option ' + opt, AxiosError_1.ERR_BAD_OPTION); + } + } + } + + var validator = { + assertOptions: assertOptions, + validators: validators$1 + }; + + var validators = validator.validators; /** * Create a new instance of Axios * @@ -7044,14 +7457,14 @@ * * @param {Object} config The config specific for this request (merged with this.defaults) */ - Axios.prototype.request = function request(config) { + Axios.prototype.request = function request(configOrUrl, config) { /*eslint no-param-reassign:0*/ // Allow for axios('example/url'[, config]) a la fetch API - if (typeof config === 'string') { - config = arguments[1] || {}; - config.url = arguments[0]; - } else { + if (typeof configOrUrl === 'string') { config = config || {}; + config.url = configOrUrl; + } else { + config = configOrUrl || {}; } config = mergeConfig(this.defaults, config); @@ -7065,20 +7478,71 @@ config.method = 'get'; } - // Hook up interceptors middleware - var chain = [dispatchRequest, undefined]; - var promise = Promise.resolve(config); + var transitional = config.transitional; + if (transitional !== undefined) { + validator.assertOptions(transitional, { + silentJSONParsing: validators.transitional(validators.boolean), + forcedJSONParsing: validators.transitional(validators.boolean), + clarifyTimeoutError: validators.transitional(validators.boolean) + }, false); + } + + // filter out skipped interceptors + var requestInterceptorChain = []; + var synchronousRequestInterceptors = true; this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) { - chain.unshift(interceptor.fulfilled, interceptor.rejected); + if (typeof interceptor.runWhen === 'function' && interceptor.runWhen(config) === false) { + return; + } + + synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor.synchronous; + + requestInterceptorChain.unshift(interceptor.fulfilled, interceptor.rejected); }); + var responseInterceptorChain = []; this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) { - chain.push(interceptor.fulfilled, interceptor.rejected); + responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected); }); - while (chain.length) { - promise = promise.then(chain.shift(), chain.shift()); + var promise; + + if (!synchronousRequestInterceptors) { + var chain = [dispatchRequest, undefined]; + + Array.prototype.unshift.apply(chain, requestInterceptorChain); + chain = chain.concat(responseInterceptorChain); + + promise = Promise.resolve(config); + while (chain.length) { + promise = promise.then(chain.shift(), chain.shift()); + } + + return promise; + } + + + var newConfig = config; + while (requestInterceptorChain.length) { + var onFulfilled = requestInterceptorChain.shift(); + var onRejected = requestInterceptorChain.shift(); + try { + newConfig = onFulfilled(newConfig); + } catch (error) { + onRejected(error); + break; + } + } + + try { + promise = dispatchRequest(newConfig); + } catch (error) { + return Promise.reject(error); + } + + while (responseInterceptorChain.length) { + promise = promise.then(responseInterceptorChain.shift(), responseInterceptorChain.shift()); } return promise; @@ -7086,7 +7550,8 @@ Axios.prototype.getUri = function getUri(config) { config = mergeConfig(this.defaults, config); - return buildURL(config.url, config.params, config.paramsSerializer).replace(/^\?/, ''); + var fullPath = buildFullPath(config.baseURL, config.url); + return buildURL(fullPath, config.params, config.paramsSerializer); }; // Provide aliases for supported request methods @@ -7103,34 +7568,26 @@ utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) { /*eslint func-names:0*/ - Axios.prototype[method] = function(url, data, config) { - return this.request(mergeConfig(config || {}, { - method: method, - url: url, - data: data - })); - }; + + function generateHTTPMethod(isForm) { + return function httpMethod(url, data, config) { + return this.request(mergeConfig(config || {}, { + method: method, + headers: isForm ? { + 'Content-Type': 'multipart/form-data' + } : {}, + url: url, + data: data + })); + }; + } + + Axios.prototype[method] = generateHTTPMethod(); + + Axios.prototype[method + 'Form'] = generateHTTPMethod(true); }); var Axios_1 = Axios; - - /** - * A `Cancel` is an object that is thrown when an operation is canceled. - * - * @class - * @param {string=} message The message. - */ - function Cancel(message) { - this.message = message; - } - - Cancel.prototype.toString = function toString() { - return 'Cancel' + (this.message ? ': ' + this.message : ''); - }; - - Cancel.prototype.__CANCEL__ = true; - - var Cancel_1 = Cancel; /** * A `CancelToken` is an object that can be used to request cancellation of an operation. @@ -7144,28 +7601,90 @@ } var resolvePromise; + this.promise = new Promise(function promiseExecutor(resolve) { resolvePromise = resolve; }); var token = this; + + // eslint-disable-next-line func-names + this.promise.then(function(cancel) { + if (!token._listeners) return; + + var i; + var l = token._listeners.length; + + for (i = 0; i < l; i++) { + token._listeners[i](cancel); + } + token._listeners = null; + }); + + // eslint-disable-next-line func-names + this.promise.then = function(onfulfilled) { + var _resolve; + // eslint-disable-next-line func-names + var promise = new Promise(function(resolve) { + token.subscribe(resolve); + _resolve = resolve; + }).then(onfulfilled); + + promise.cancel = function reject() { + token.unsubscribe(_resolve); + }; + + return promise; + }; + executor(function cancel(message) { if (token.reason) { // Cancellation has already been requested return; } - token.reason = new Cancel_1(message); + token.reason = new CanceledError_1(message); resolvePromise(token.reason); }); } /** - * Throws a `Cancel` if cancellation has been requested. + * Throws a `CanceledError` if cancellation has been requested. */ CancelToken.prototype.throwIfRequested = function throwIfRequested() { if (this.reason) { throw this.reason; + } + }; + + /** + * Subscribe to the cancel signal + */ + + CancelToken.prototype.subscribe = function subscribe(listener) { + if (this.reason) { + listener(this.reason); + return; + } + + if (this._listeners) { + this._listeners.push(listener); + } else { + this._listeners = [listener]; + } + }; + + /** + * Unsubscribe from the cancel signal + */ + + CancelToken.prototype.unsubscribe = function unsubscribe(listener) { + if (!this._listeners) { + return; + } + var index = this._listeners.indexOf(listener); + if (index !== -1) { + this._listeners.splice(index, 1); } }; @@ -7219,7 +7738,7 @@ * @returns {boolean} True if the payload is an error thrown by Axios, otherwise false */ var isAxiosError = function isAxiosError(payload) { - return (typeof payload === 'object') && (payload.isAxiosError === true); + return utils.isObject(payload) && (payload.isAxiosError === true); }; /** @@ -7238,6 +7757,11 @@ // Copy context to instance utils.extend(instance, context); + // Factory for creating new instances + instance.create = function create(instanceConfig) { + return createInstance(mergeConfig(defaultConfig, instanceConfig)); + }; + return instance; } @@ -7247,15 +7771,18 @@ // Expose Axios class to allow class inheritance axios$1.Axios = Axios_1; - // Factory for creating new instances - axios$1.create = function create(instanceConfig) { - return createInstance(mergeConfig(axios$1.defaults, instanceConfig)); - }; - // Expose Cancel & CancelToken - axios$1.Cancel = Cancel_1; + axios$1.CanceledError = CanceledError_1; axios$1.CancelToken = CancelToken_1; axios$1.isCancel = isCancel; + axios$1.VERSION = data.version; + axios$1.toFormData = toFormData_1; + + // Expose AxiosError class + axios$1.AxiosError = AxiosError_1; + + // alias for CanceledError for backward compatibility + axios$1.Cancel = axios$1.CanceledError; // Expose all/spread axios$1.all = function all(promises) { @@ -7284,34 +7811,52 @@ debug: false, // if output debug log zlmsdpUrl: '', - simulecast: false, + simulcast: false, useCamera: true, audioEnable: true, videoEnable: true, - recvOnly: false + recvOnly: false, + resolution: { + w: 0, + h: 0 + }, + usedatachannel: false }; this.options = Object.assign({}, defaults, options); - if (this.options.debug) { setLogger(); } - this.e = { onicecandidate: this._onIceCandidate.bind(this), ontrack: this._onTrack.bind(this), - onicecandidateerror: this._onIceCandidateError.bind(this) + onicecandidateerror: this._onIceCandidateError.bind(this), + onconnectionstatechange: this._onconnectionstatechange.bind(this), + ondatachannelopen: this._onDataChannelOpen.bind(this), + ondatachannelmsg: this._onDataChannelMsg.bind(this), + ondatachannelerr: this._onDataChannelErr.bind(this), + ondatachannelclose: this._onDataChannelClose.bind(this) }; this._remoteStream = null; this._localStream = null; + this._tracks = []; this.pc = new RTCPeerConnection(null); this.pc.onicecandidate = this.e.onicecandidate; this.pc.onicecandidateerror = this.e.onicecandidateerror; this.pc.ontrack = this.e.ontrack; + this.pc.onconnectionstatechange = this.e.onconnectionstatechange; + this.datachannel = null; + if (this.options.usedatachannel) { + this.datachannel = this.pc.createDataChannel('chat'); + this.datachannel.onclose = this.e.ondatachannelclose; + this.datachannel.onerror = this.e.ondatachannelerr; + this.datachannel.onmessage = this.e.ondatachannelmsg; + this.datachannel.onopen = this.e.ondatachannelopen; + } if (!this.options.recvOnly && (this.options.audioEnable || this.options.videoEnable)) this.start();else this.receive(); } - receive() { + //debug.error(this.TAG,'this not implement'); const AudioTransceiverInit = { direction: 'recvonly', sendEncodings: [] @@ -7320,8 +7865,12 @@ direction: 'recvonly', sendEncodings: [] }; - this.pc.addTransceiver('audio', AudioTransceiverInit); - this.pc.addTransceiver('video', VideoTransceiverInit); + if (this.options.videoEnable) { + this.pc.addTransceiver('video', VideoTransceiverInit); + } + if (this.options.audioEnable) { + this.pc.addTransceiver('audio', AudioTransceiverInit); + } this.pc.createOffer().then(desc => { log(this.TAG, 'offer:', desc.sdp); this.pc.setLocalDescription(desc).then(() => { @@ -7335,19 +7884,17 @@ } }).then(response => { let ret = response.data; //JSON.parse(response.data); - if (ret.code != 0) { - // mean failed for offer/anwser exchange + // mean failed for offer/anwser exchange this.dispatch(Events$1.WEBRTC_OFFER_ANWSER_EXCHANGE_FAILED, ret); return; } - let anwser = {}; anwser.sdp = ret.sdp; anwser.type = 'answer'; log(this.TAG, 'answer:', ret.sdp); this.pc.setRemoteDescription(anwser).then(() => { - log(this.TAG, 'set remote success'); + log(this.TAG, 'set remote sucess'); }).catch(e => { error(this.TAG, e); }); @@ -7357,11 +7904,9 @@ error(this.TAG, e); }); } - start() { let videoConstraints = false; let audioConstraints = false; - if (this.options.useCamera) { if (this.options.videoEnable) videoConstraints = new VideoTrackConstraints(VideoSourceInfo.CAMERA); if (this.options.audioEnable) audioConstraints = new AudioTrackConstraints(AudioSourceInfo.MIC); @@ -7376,7 +7921,9 @@ } } } - + if (this.options.resolution.w != 0 && this.options.resolution.h != 0 && typeof videoConstraints == 'object') { + videoConstraints.resolution = new Resolution(this.options.resolution.w, this.options.resolution.h); + } MediaStreamFactory.createMediaStream(new StreamConstraints(audioConstraints, videoConstraints)).then(stream => { this._localStream = stream; this.dispatch(Events$1.WEBRTC_ON_LOCAL_STREAM, stream); @@ -7388,43 +7935,46 @@ direction: 'sendrecv', sendEncodings: [] }; - - if (this.options.simulecast && stream.getVideoTracks().length > 0) { + if (this.options.simulcast && stream.getVideoTracks().length > 0) { VideoTransceiverInit.sendEncodings = [{ - rid: 'q', - active: true, - scaleResolutionDownBy: 4.0 - }, { rid: 'h', active: true, - scaleResolutionDownBy: 2.0 + maxBitrate: 1000000 }, { - rid: 'f', - active: true + rid: 'm', + active: true, + maxBitrate: 500000, + scaleResolutionDownBy: 2 + }, { + rid: 'l', + active: true, + maxBitrate: 200000, + scaleResolutionDownBy: 4 }]; } - - if (stream.getAudioTracks().length > 0) { - this.pc.addTransceiver(stream.getAudioTracks()[0], AudioTransceiverInit); - } else { - AudioTransceiverInit.direction = 'recvonly'; - this.pc.addTransceiver('audio', AudioTransceiverInit); + if (this.options.audioEnable) { + if (stream.getAudioTracks().length > 0) { + this.pc.addTransceiver(stream.getAudioTracks()[0], AudioTransceiverInit); + } else { + AudioTransceiverInit.direction = 'recvonly'; + this.pc.addTransceiver('audio', AudioTransceiverInit); + } + } + if (this.options.videoEnable) { + if (stream.getVideoTracks().length > 0) { + this.pc.addTransceiver(stream.getVideoTracks()[0], VideoTransceiverInit); + } else { + VideoTransceiverInit.direction = 'recvonly'; + this.pc.addTransceiver('video', VideoTransceiverInit); + } } - if (stream.getVideoTracks().length > 0) { - this.pc.addTransceiver(stream.getVideoTracks()[0], VideoTransceiverInit); - } else { - VideoTransceiverInit.direction = 'recvonly'; - this.pc.addTransceiver('video', VideoTransceiverInit); - } /* stream.getTracks().forEach((track,idx)=>{ debug.log(this.TAG,track); this.pc.addTrack(track); }); */ - - this.pc.createOffer().then(desc => { log(this.TAG, 'offer:', desc.sdp); this.pc.setLocalDescription(desc).then(() => { @@ -7438,19 +7988,17 @@ } }).then(response => { let ret = response.data; //JSON.parse(response.data); - if (ret.code != 0) { - // mean failed for offer/anwser exchange + // mean failed for offer/anwser exchange this.dispatch(Events$1.WEBRTC_OFFER_ANWSER_EXCHANGE_FAILED, ret); return; } - let anwser = {}; anwser.sdp = ret.sdp; anwser.type = 'answer'; log(this.TAG, 'answer:', ret.sdp); this.pc.setRemoteDescription(anwser).then(() => { - log(this.TAG, 'set remote success'); + log(this.TAG, 'set remote sucess'); }).catch(e => { error(this.TAG, e); }); @@ -7460,9 +8008,11 @@ error(this.TAG, e); }); }).catch(e => { - error(this.TAG, e); - }); //const offerOptions = {}; + this.dispatch(Events$1.CAPTURE_STREAM_FAILED); + //debug.error(this.TAG,e); + }); + //const offerOptions = {}; /* if (typeof this.pc.addTransceiver === 'function') { // |direction| seems not working on Safari. @@ -7477,70 +8027,196 @@ _onIceCandidate(event) { if (event.candidate) { - log('Remote ICE candidate: \n ' + event.candidate.candidate); // Send the candidate to the remote peer + log(this.TAG, 'Remote ICE candidate: \n ' + event.candidate.candidate); + // Send the candidate to the remote peer } } - _onTrack(event) { + this._tracks.push(event.track); if (this.options.element && event.streams && event.streams.length > 0) { this.options.element.srcObject = event.streams[0]; this._remoteStream = event.streams[0]; this.dispatch(Events$1.WEBRTC_ON_REMOTE_STREAMS, event); } else { - error('element pararm is failed'); + if (this.pc.getReceivers().length == this._tracks.length) { + log(this.TAG, 'play remote stream '); + this._remoteStream = new MediaStream(this._tracks); + this.options.element.srcObject = this._remoteStream; + } else { + error(this.TAG, 'wait stream track finish'); + } } } - _onIceCandidateError(event) { this.dispatch(Events$1.WEBRTC_ICE_CANDIDATE_ERROR, event); } - + _onconnectionstatechange(event) { + this.dispatch(Events$1.WEBRTC_ON_CONNECTION_STATE_CHANGE, this.pc.connectionState); + } + _onDataChannelOpen(event) { + log(this.TAG, 'ondatachannel open:', event); + this.dispatch(Events$1.WEBRTC_ON_DATA_CHANNEL_OPEN, event); + } + _onDataChannelMsg(event) { + log(this.TAG, 'ondatachannel msg:', event); + this.dispatch(Events$1.WEBRTC_ON_DATA_CHANNEL_MSG, event); + } + _onDataChannelErr(event) { + log(this.TAG, 'ondatachannel err:', event); + this.dispatch(Events$1.WEBRTC_ON_DATA_CHANNEL_ERR, event); + } + _onDataChannelClose(event) { + log(this.TAG, 'ondatachannel close:', event); + this.dispatch(Events$1.WEBRTC_ON_DATA_CHANNEL_CLOSE, event); + } + sendMsg(data) { + if (this.datachannel != null) { + this.datachannel.send(data); + } else { + error(this.TAG, 'data channel is null'); + } + } + closeDataChannel() { + if (this.datachannel) { + this.datachannel.close(); + this.datachannel = null; + } + } close() { + this.closeDataChannel(); if (this.pc) { this.pc.close(); this.pc = null; } - if (this.options) { this.options = null; } - if (this._localStream) { this._localStream.getTracks().forEach((track, idx) => { track.stop(); }); } - if (this._remoteStream) { this._remoteStream.getTracks().forEach((track, idx) => { track.stop(); }); } + this._tracks.forEach((track, idx) => { + track.stop(); + }); + this._tracks = []; } - get remoteStream() { return this._remoteStream; } - get localStream() { return this._localStream; } + } + const quickScan = [{ + 'label': '4K(UHD)', + 'width': 3840, + 'height': 2160 + }, { + 'label': '1080p(FHD)', + 'width': 1920, + 'height': 1080 + }, { + 'label': 'UXGA', + 'width': 1600, + 'height': 1200, + 'ratio': '4:3' + }, { + 'label': '720p(HD)', + 'width': 1280, + 'height': 720 + }, { + 'label': 'SVGA', + 'width': 800, + 'height': 600 + }, { + 'label': 'VGA', + 'width': 640, + 'height': 480 + }, { + 'label': '360p(nHD)', + 'width': 640, + 'height': 360 + }, { + 'label': 'CIF', + 'width': 352, + 'height': 288 + }, { + 'label': 'QVGA', + 'width': 320, + 'height': 240 + }, { + 'label': 'QCIF', + 'width': 176, + 'height': 144 + }, { + 'label': 'QQVGA', + 'width': 160, + 'height': 120 + }]; + function GetSupportCameraResolutions$1() { + return new Promise(function (resolve, reject) { + let resolutions = []; + let ok = 0; + let err = 0; + for (let i = 0; i < quickScan.length; ++i) { + let videoConstraints = new VideoTrackConstraints(VideoSourceInfo.CAMERA); + videoConstraints.resolution = new Resolution(quickScan[i].width, quickScan[i].height); + MediaStreamFactory.createMediaStream(new StreamConstraints(false, videoConstraints)).then(stream => { + resolutions.push(quickScan[i]); + ok++; + if (ok + err == quickScan.length) { + resolve(resolutions); + } + }).catch(e => { + err++; + if (ok + err == quickScan.length) { + resolve(resolutions); + } + }); + } + }); + } + function GetAllScanResolution$1() { + return quickScan; + } + function isSupportResolution$1(w, h) { + return new Promise(function (resolve, reject) { + let videoConstraints = new VideoTrackConstraints(VideoSourceInfo.CAMERA); + videoConstraints.resolution = new Resolution(w, h); + MediaStreamFactory.createMediaStream(new StreamConstraints(false, videoConstraints)).then(stream => { + resolve(); + }).catch(e => { + reject(e); + }); + }); } console.log('build date:', BUILD_DATE); - console.log('version:', VERSION); + console.log('version:', VERSION$1); const Events = Events$1; const Media = media; const Endpoint = RTCEndpoint; + const GetSupportCameraResolutions = GetSupportCameraResolutions$1; + const GetAllScanResolution = GetAllScanResolution$1; + const isSupportResolution = isSupportResolution$1; exports.Endpoint = Endpoint; exports.Events = Events; + exports.GetAllScanResolution = GetAllScanResolution; + exports.GetSupportCameraResolutions = GetSupportCameraResolutions; exports.Media = Media; + exports.isSupportResolution = isSupportResolution; Object.defineProperty(exports, '__esModule', { value: true }); return exports; -}({})); +})({}); //# sourceMappingURL=ZLMRTCClient.js.map -- Gitblit v1.8.0