UNPKG

trtc-sdk-v5

Version:
2 lines (1 loc) 12.5 kB
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).SmallStreamAutoSwitcher=e()}(this,(function(){"use strict";function t(t,e){(null==e||e>t.length)&&(e=t.length);for(var o=0,i=Array(e);o<e;o++)i[o]=t[o];return i}function e(t,e,o){return e&&function(t,e){for(var o=0;o<e.length;o++){var i=e[o];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,r(i.key),i)}}(t.prototype,e),Object.defineProperty(t,"prototype",{writable:!1}),t}function o(t,e){var o="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(!o){if(Array.isArray(t)||(o=a(t))||e){o&&(t=o);var i=0,n=function(){};return{s:n,n:function(){return i>=t.length?{done:!0}:{done:!1,value:t[i++]}},e:function(t){throw t},f:n}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var r,s=!0,u=!1;return{s:function(){o=o.call(t)},n:function(){var t=o.next();return s=t.done,t},e:function(t){u=!0,r=t},f:function(){try{s||null==o.return||o.return()}finally{if(u)throw r}}}}function i(t,e){return function(t){if(Array.isArray(t))return t}(t)||function(t,e){var o=null==t?null:"undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(null!=o){var i,n,r,s,a=[],u=!0,l=!1;try{if(r=(o=o.call(t)).next,0===e);else for(;!(u=(i=r.call(o)).done)&&(a.push(i.value),a.length!==e);u=!0);}catch(t){l=!0,n=t}finally{try{if(!u&&null!=o.return&&(s=o.return(),Object(s)!==s))return}finally{if(l)throw n}}return a}}(t,e)||a(t,e)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function n(e){return function(e){if(Array.isArray(e))return t(e)}(e)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(e)||a(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function r(t){var e=function(t,e){if("object"!=typeof t||!t)return t;var o=t[Symbol.toPrimitive];if(void 0!==o){var i=o.call(t,e);if("object"!=typeof i)return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(t)}(t,"string");return"symbol"==typeof e?e:e+""}function s(t){return s="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},s(t)}function a(e,o){if(e){if("string"==typeof e)return t(e,o);var i={}.toString.call(e).slice(8,-1);return"Object"===i&&e.constructor&&(i=e.constructor.name),"Map"===i||"Set"===i?Array.from(e):"Arguments"===i||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(i)?t(e,o):void 0}}var u=Object.defineProperty,l=Object.getOwnPropertySymbols,h=Object.prototype.hasOwnProperty,c=Object.prototype.propertyIsEnumerable,f=function(t,e,o){return e in t?u(t,e,{enumerable:!0,configurable:!0,writable:!0,value:o}):t[e]=o},p=function(t,e){for(var i in e||(e={}))h.call(e,i)&&f(t,i,e[i]);if(l){var n,r=o(l(e));try{for(r.s();!(n=r.n()).done;){i=n.value;c.call(e,i)&&f(t,i,e[i])}}catch(t){r.e(t)}finally{r.f()}}return t},m=function(t,e,o){return f(t,"symbol"!==s(e)?e+"":e,o)},d={rttPoorLimit:200,lossPoorLimit:20,rttGoodLimit:100,lossGoodLimit:10,sleepTime:3e4,poorDuration:1e4,goodDuration:2e4,maxAutoSwitchToSmallCount:2},v=0,g=function(){function t(e){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.core=e,m(this,"log"),m(this,"options",d),m(this,"rttQueue",[]),m(this,"lossQueue",[]),m(this,"autoSwitchToSmallCountMap",new Map),m(this,"sleepMap",new Map),m(this,"fpsSmallQueueMap",new Map),m(this,"fpsBigQueueMap",new Map),m(this,"checkIntervalTime",2e3),m(this,"rttOverCount",0),m(this,"lossOverCount",0),m(this,"rttUnderCount",0),m(this,"lossUnderCount",0),m(this,"checkInterval",null),m(this,"beforeSwitchFpsTrackingMap",new Map),m(this,"isAutoSwitching",!1),m(this,"testCount"),m(this,"poorCount"),m(this,"goodCount"),this.log=e.log.createChild({id:"".concat(this.getAlias()).concat(v)}),this.log.info("created id=".concat(this.getAlias()).concat(v)),v+=1}return e(t,[{key:"getName",value:function(){return t.Name}},{key:"getAlias",value:function(){return"ssas"}},{key:"getGroup",value:function(){return"ssas"}},{key:"destroy",value:function(){this.log.debug("destroy"),this.stop()}},{key:"getValidateRule",value:function(){return{type:this.core.enums.BASIC_TYPE.Object,required:!1}}},{key:"start",value:function(t){var e=this,n=this.core.room.scheduleResult.autoSwitchSmallConfig||{};this.options=p(p(p({},d),t),n),this.log.info("start with options:",this.options),this.poorCount=Math.floor(this.options.poorDuration/this.checkIntervalTime),this.goodCount=Math.floor(this.options.goodDuration/this.checkIntervalTime),this.testCount=Math.max(1,this.poorCount,this.goodCount),this.core.trtc.on(this.core.TRTC.EVENT.STATISTICS,this.onStatistics,this),this.core.trtc.on(this.core.TRTC.EVENT.NETWORK_QUALITY,this.onNetworkQuality,this),this.core.room.on(this.core.enums.RoomEvent.SUBSCRIBE_SMALL_VIDEO_CHANGED,this.onSmallVideoChanged,this),this.core.room.on(this.core.enums.RoomEvent.PEER_LEAVE,this.onRemoteUserLeave,this),this.checkInterval=setInterval((function(){var t=e.core.room;if(0!==t.remotePublishedUserMap.size){var n,r=o(e.sleepMap);try{for(r.s();!(n=r.n()).done;){var s=i(n.value,2),a=s[0],u=s[1];if(u>0){var l=u-e.checkIntervalTime;l<=0?e.sleepMap.delete(a):e.sleepMap.set(a,l)}}}catch(t){r.e(t)}finally{r.f()}var h,c=e.getShouldSwitchToSmallUserList(),f=e.getShouldSwitchToBigUserList(),p=o(c);try{for(p.s();!(h=p.n()).done;){var m=h.value;if(!((e.sleepMap.get(m)||0)>0)){var d=t.remotePublishedUserMap.get(m),v=e.isBigVideoSubscribed(t,m),g=null==d?void 0:d.muteState.hasSmall;if(d&&v&&g){var y=e.autoSwitchToSmallCountMap.get(m)||0;y>=e.options.maxAutoSwitchToSmallCount||(e.toggleSmall(d,!0),e.fpsBigQueueMap.set(m,[]),e.autoSwitchToSmallCountMap.set(m,y+1),e.sleepMap.set(m,e.options.sleepTime))}}}}catch(t){p.e(t)}finally{p.f()}var S,b=o(f);try{for(b.s();!(S=b.n()).done;){var T=S.value;if(!((e.sleepMap.get(T)||0)>0)){var M=t.remotePublishedUserMap.get(T),C=e.isSmallVideoSubscribed(t,T);if(M&&C)(e.autoSwitchToSmallCountMap.get(T)||0)===e.options.maxAutoSwitchToSmallCount-1&&(e.toggleSmall(M,!1),e.fpsSmallQueueMap.set(T,[]),e.sleepMap.set(T,e.options.sleepTime))}}}catch(t){b.e(t)}finally{b.f()}}}),this.checkIntervalTime),this.log.info("started")}},{key:"update",value:function(){this.log.info("update")}},{key:"stop",value:function(){this.core.trtc.off(this.core.TRTC.EVENT.NETWORK_QUALITY,this.onNetworkQuality,this),this.core.trtc.off(this.core.TRTC.EVENT.STATISTICS,this.onStatistics,this),this.core.room.off(this.core.enums.RoomEvent.SUBSCRIBE_SMALL_VIDEO_CHANGED,this.onSmallVideoChanged,this),this.core.room.off(this.core.enums.RoomEvent.PEER_LEAVE,this.onRemoteUserLeave,this),this.fpsBigQueueMap.clear(),this.fpsSmallQueueMap.clear(),this.rttQueue=[],this.lossQueue=[],this.rttOverCount=0,this.lossOverCount=0,this.rttUnderCount=0,this.lossUnderCount=0,this.sleepMap.clear(),this.autoSwitchToSmallCountMap.clear(),this.beforeSwitchFpsTrackingMap.clear(),this.checkInterval&&(clearInterval(this.checkInterval),this.checkInterval=null),this.log.info("stopped")}},{key:"toggleSmall",value:function(t,e){var o=this,i=t.userId;this.log.info("autoswitch ".concat(i," to ").concat(e?"small":"big"," stream")),this.isAutoSwitching=!0,this.core.room.changeType(e,t),setTimeout((function(){return o.isAutoSwitching=!1}),0),this.takeSnapshot(i,e);var n=e?593e3:593001;if(this.core.kvStatManager.addCount({key:n}),e){var r=this.fpsBigQueueMap.get(i);if(!r)return;var s=r.reduce((function(t,e){return t+e}),0)/r.length;if(this.fpsSmallQueueMap.set(i,[]),0===s)return;this.beforeSwitchFpsTrackingMap.set(i,s)}}},{key:"onSmallVideoChanged",value:function(t){if(!this.isAutoSwitching){var e=t.userId,o=t.isSmall;this.log.info("small video changed: userId=".concat(e,", isSmall=").concat(o)),o?this.autoSwitchToSmallCountMap.set(e,this.options.maxAutoSwitchToSmallCount):(this.autoSwitchToSmallCountMap.set(e,0),this.sleepMap.set(e,this.options.sleepTime))}}},{key:"onRemoteUserLeave",value:function(t){this.fpsBigQueueMap.delete(t),this.fpsSmallQueueMap.delete(t),this.autoSwitchToSmallCountMap.delete(t),this.sleepMap.delete(t),this.beforeSwitchFpsTrackingMap.delete(t)}},{key:"onNetworkQuality",value:function(t){var e=t.downlinkRTT,o=t.downlinkLoss;this.rttQueue.push(e),this.lossQueue.push(o),this.rttQueue.length>this.testCount&&this.rttQueue.shift(),this.lossQueue.length>this.testCount&&this.lossQueue.shift(),this.rttOverCount=e>this.options.rttPoorLimit?this.rttOverCount+1:0,this.lossOverCount=o>this.options.lossPoorLimit?this.lossOverCount+1:0,this.rttUnderCount=e<this.options.rttGoodLimit?this.rttUnderCount+1:0,this.lossUnderCount=o<this.options.lossGoodLimit?this.lossUnderCount+1:0}},{key:"onStatistics",value:function(t){var e,o=this;if(null==(e=null==t?void 0:t.remoteStatistics)?void 0:e.length)try{t.remoteStatistics.forEach((function(t){var e,i,n,r=t.userId;if(r&&(null==(e=t.video)?void 0:e.length)){var s=(null==(i=t.video.find((function(t){return"big"===t.videoType})))?void 0:i.frameRate)||0,a=(null==(n=t.video.find((function(t){return"small"===t.videoType})))?void 0:n.frameRate)||0,u=function(t,e){var i=t.get(r);i||(i=[],t.set(r,i)),i.push(e),i.length>o.testCount&&i.shift()};u(o.fpsBigQueueMap,s),u(o.fpsSmallQueueMap,a),o.checkAndReportFpsRatio(r)}}))}catch(t){this.log.warn("onStatistics error",t)}}},{key:"checkAndReportFpsRatio",value:function(t){var e=this.beforeSwitchFpsTrackingMap.get(t);if(e){var o=this.fpsSmallQueueMap.get(t);if(o&&!(o.length<this.testCount)){var i=o.reduce((function(t,e){return t+e}),0)/o.length,n=i/e*100,r=Math.round(Math.max(1,Math.min(1e3,n)));this.core.kvStatManager.addNumber({key:593800,value:r,split:[0,100,200,300,400,500,800,1e3],max:1e3}),this.log.debug("beforeSwitchFps: ".concat(e,", afterSwitchFps: ").concat(i,", afterSwitchQueue: ").concat(o.join(","))),this.log.info("FPS ratio reported for user ".concat(t,": ").concat(r.toFixed(2),"% (before: ").concat(e.toFixed(1),", after: ").concat(i.toFixed(1),")")),this.beforeSwitchFpsTrackingMap.delete(t)}}}},{key:"getBadFrameRateUserList",value:function(){var t,e=[],r=o(this.fpsBigQueueMap);try{for(r.s();!(t=r.n()).done;){var s=i(t.value,2),a=s[0],u=s[1];if(u&&0!==u.length){var l=Math.max.apply(Math,n(u)),h=Math.min.apply(Math,n(u));u.length!==this.testCount||0!==h||0!==l?0!==l&&l-h>l/3&&e.push(a):e.push(a)}}}catch(t){r.e(t)}finally{r.f()}return e}},{key:"getGoodFrameRateUserList",value:function(){var t,e=[],r=o(this.fpsSmallQueueMap);try{for(r.s();!(t=r.n()).done;){var s=i(t.value,2),a=s[0],u=s[1];if(u&&0!==u.length){var l=Math.max.apply(Math,n(u)),h=Math.min.apply(Math,n(u));0!==l&&l-h<=l/3&&e.push(a)}}}catch(t){r.e(t)}finally{r.f()}return e}},{key:"getShouldSwitchToSmallUserList",value:function(){if(this.rttQueue.length<this.testCount||this.lossQueue.length<this.testCount)return[];if(!(this.rttOverCount>=this.poorCount||this.lossOverCount>=this.poorCount))return[];var t=this.getBadFrameRateUserList();return t.length>0&&this.log.debug("badFrameRateUserList: ".concat(t.join(","))),t}},{key:"getShouldSwitchToBigUserList",value:function(){if(!(this.rttUnderCount>=this.goodCount&&this.lossUnderCount>=this.goodCount))return[];var t=this.getGoodFrameRateUserList();return t.length>0&&this.log.debug("goodFrameRateUserList: ".concat(t.join(","))),t}},{key:"takeSnapshot",value:function(t,e){this.log.info("Network stats at snapshot: RTTQueue=".concat(this.rttQueue.join(","),", LossQueue=").concat(this.lossQueue.join(",")));var o=e?this.fpsBigQueueMap.get(t):this.fpsSmallQueueMap.get(t);this.log.info("".concat(e?"big":"small"," frame rate stats at snapshot: ").concat((null==o?void 0:o.join(","))||"N/A"))}},{key:"isBigVideoSubscribed",value:function(t,e){var o=t.remotePublishedUserMap.get(e);return!!o&&o.remoteVideoTrack.mediaType===this.core.enums.MediaType.BIG_VIDEO}},{key:"isSmallVideoSubscribed",value:function(t,e){var o=t.remotePublishedUserMap.get(e);return!!o&&o.remoteVideoTrack.mediaType===this.core.enums.MediaType.SMALL_VIDEO}}])}();return m(g,"Name","SmallStreamAutoSwitcher"),g}));