@100mslive/hls-stats 0.1.1-alpha.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,10 @@
1
- import { HlsInstance, HlsPlayerStats } from '../interfaces';
1
+ import Hls from 'hls.js';
2
+ import { HlsPlayerStats } from '../interfaces';
2
3
  export declare abstract class BaseAdapter {
3
- hlsInstance: HlsInstance;
4
+ hlsInstance: Hls;
4
5
  videoEl: HTMLVideoElement;
5
6
  hlsStatsState: HlsPlayerStats;
6
- constructor(hlsInstance: HlsInstance, videoEl: HTMLVideoElement);
7
+ constructor(hlsInstance: Hls, videoEl: HTMLVideoElement);
7
8
  abstract startGatheringStats(): void;
8
9
  abstract finishGatheringStats(): void;
9
10
  getState(): HlsPlayerStats;
@@ -1,11 +1,12 @@
1
+ import Hls from 'hls.js';
1
2
  import { BaseAdapter } from '../adapters/BaseAdapter';
2
- import { HlsInstance, HlsPlayerStats } from '../interfaces';
3
+ import { HlsPlayerStats } from '../interfaces';
3
4
  import { IHlsStats } from '../interfaces/IHlsStats';
4
5
  export declare class HlsStats implements IHlsStats {
5
6
  adapter: BaseAdapter;
6
7
  intervalFunctionId: number;
7
- constructor(hlsLibraryInstance: HlsInstance, videoEl: HTMLVideoElement);
8
- subscribe(callback: (state: HlsPlayerStats) => void, interval?: number): () => void;
9
- unsubscribe(): void;
10
- getState(): HlsPlayerStats;
8
+ constructor(hlsLibraryInstance: Hls, videoEl: HTMLVideoElement);
9
+ subscribe: (callback: (state: HlsPlayerStats) => void, interval?: number) => () => void;
10
+ unsubscribe: () => void;
11
+ getState: () => HlsPlayerStats;
11
12
  }
package/dist/index.cjs.js CHANGED
@@ -1,2 +1,2 @@
1
- var u=Object.create;var n=Object.defineProperty,E=Object.defineProperties,I=Object.getOwnPropertyDescriptor,b=Object.getOwnPropertyDescriptors,g=Object.getOwnPropertyNames,p=Object.getOwnPropertySymbols,L=Object.getPrototypeOf,m=Object.prototype.hasOwnProperty,A=Object.prototype.propertyIsEnumerable;var v=(e,t,s)=>t in e?n(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s,l=(e,t)=>{for(var s in t||(t={}))m.call(t,s)&&v(e,s,t[s]);if(p)for(var s of p(t))A.call(t,s)&&v(e,s,t[s]);return e},d=(e,t)=>E(e,b(t)),H=e=>n(e,"__esModule",{value:!0});var y=(e,t)=>{H(e);for(var s in t)n(e,s,{get:t[s],enumerable:!0})},G=(e,t,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of g(t))!m.call(e,a)&&a!=="default"&&n(e,a,{get:()=>t[a],enumerable:!(s=I(t,a))||s.enumerable});return e},F=e=>G(H(n(e!=null?u(L(e)):{},"default",e&&e.__esModule&&"default"in e?{get:()=>e.default,enumerable:!0}:{value:e,enumerable:!0})),e);y(exports,{HlsStats:()=>S});var r=F(require("hls.js"));var h=class{constructor(t,s){this.hlsInstance={};this.hlsStatsState={};this.hlsInstance=t,this.videoEl=s}getState(){return this.hlsStatsState}};var c=class extends h{constructor(){super(...arguments);this.timeUpdateHandler=()=>{let t=this.videoEl.buffered.length>0?this.videoEl.buffered.end(0)-this.videoEl.buffered.start(0):0,s=(this.hlsInstance.liveSyncPosition?this.hlsInstance.liveSyncPosition-this.videoEl.currentTime:0)*1e3,i=this.videoEl.getVideoPlaybackQuality().droppedVideoFrames;this.hlsStatsState=d(l({},this.hlsStatsState),{distanceFromLive:s>0?s:0,bufferedDuration:t,droppedFrames:i})};this.levelLoadedHandler=(t,{level:s})=>{let a=this.hlsInstance.levels[s],{bitrate:i,height:o,width:f}=a;this.hlsStatsState=d(l({},this.hlsStatsState),{bitrate:i,videoSize:{height:o,width:f}})};this.fragChangedHandler=(t,{frag:s})=>{let{stats:a,baseurl:i}=s,{bwEstimate:o}=a;this.hlsStatsState=d(l({},this.hlsStatsState),{bandwidthEstimate:o,url:i})}}startGatheringStats(){this.hlsInstance.on(r.default.Events.FRAG_CHANGED,this.fragChangedHandler),this.hlsInstance.on(r.default.Events.LEVEL_LOADED,this.levelLoadedHandler),this.videoEl.addEventListener("timeupdate",this.timeUpdateHandler)}finishGatheringStats(){this.videoEl.removeEventListener("timeupdate",this.timeUpdateHandler),this.hlsInstance.off(r.default.Events.FRAG_CHANGED,this.fragChangedHandler),this.hlsInstance.off(r.default.Events.LEVEL_LOADED,this.levelLoadedHandler)}};var S=class{constructor(t,s){this.intervalFunctionId=-1;let a=new c(t,s);this.adapter=a}subscribe(t,s=2e3){return this.adapter.startGatheringStats(),this.intervalFunctionId=setInterval(()=>{t(this.getState())},s),this.unsubscribe.bind(this)}unsubscribe(){clearInterval(this.intervalFunctionId),this.adapter.finishGatheringStats()}getState(){return this.adapter.getState()}};
1
+ var u=Object.create;var r=Object.defineProperty,E=Object.defineProperties,b=Object.getOwnPropertyDescriptor,g=Object.getOwnPropertyDescriptors,I=Object.getOwnPropertyNames,p=Object.getOwnPropertySymbols,L=Object.getPrototypeOf,S=Object.prototype.hasOwnProperty,y=Object.prototype.propertyIsEnumerable;var v=(e,t,s)=>t in e?r(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s,l=(e,t)=>{for(var s in t||(t={}))S.call(t,s)&&v(e,s,t[s]);if(p)for(var s of p(t))y.call(t,s)&&v(e,s,t[s]);return e},o=(e,t)=>E(e,g(t)),f=e=>r(e,"__esModule",{value:!0});var A=(e,t)=>{f(e);for(var s in t)r(e,s,{get:t[s],enumerable:!0})},G=(e,t,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of I(t))!S.call(e,a)&&a!=="default"&&r(e,a,{get:()=>t[a],enumerable:!(s=b(t,a))||s.enumerable});return e},F=e=>G(f(r(e!=null?u(L(e)):{},"default",e&&e.__esModule&&"default"in e?{get:()=>e.default,enumerable:!0}:{value:e,enumerable:!0})),e);A(exports,{HlsStats:()=>m});var n=F(require("hls.js"));var h=class{constructor(t,s){this.hlsStatsState={};this.hlsInstance=t,this.videoEl=s}getState(){return this.hlsStatsState}};var c=class extends h{constructor(){super(...arguments);this.timeUpdateHandler=()=>{let t=this.videoEl.buffered.length>0?this.videoEl.buffered.end(0)-this.videoEl.buffered.start(0):0,s=(this.hlsInstance.liveSyncPosition?this.hlsInstance.liveSyncPosition-this.videoEl.currentTime:0)*1e3,i=this.videoEl.getVideoPlaybackQuality().droppedVideoFrames;this.hlsStatsState=o(l({},this.hlsStatsState),{distanceFromLive:s>0?s:0,bufferedDuration:t,droppedFrames:i})};this.levelLoadedHandler=(t,{level:s})=>{let a=this.hlsInstance.levels[s],{bitrate:i,height:d,width:H}=a;this.hlsStatsState=o(l({},this.hlsStatsState),{bitrate:i,videoSize:{height:d,width:H}})};this.fragChangedHandler=(t,{frag:s})=>{let{stats:a,baseurl:i}=s,{bwEstimate:d}=a;this.hlsStatsState=o(l({},this.hlsStatsState),{bandwidthEstimate:d,url:i})}}startGatheringStats(){this.hlsInstance.on(n.default.Events.FRAG_CHANGED,this.fragChangedHandler),this.hlsInstance.on(n.default.Events.LEVEL_LOADED,this.levelLoadedHandler),this.videoEl.addEventListener("timeupdate",this.timeUpdateHandler)}finishGatheringStats(){this.videoEl.removeEventListener("timeupdate",this.timeUpdateHandler),this.hlsInstance.off(n.default.Events.FRAG_CHANGED,this.fragChangedHandler),this.hlsInstance.off(n.default.Events.LEVEL_LOADED,this.levelLoadedHandler)}};var m=class{constructor(t,s){this.intervalFunctionId=-1;this.subscribe=(t,s=2e3)=>(this.adapter.startGatheringStats(),this.intervalFunctionId=setInterval(()=>{t(this.getState())},s),this.unsubscribe);this.unsubscribe=()=>{clearInterval(this.intervalFunctionId),this.adapter.finishGatheringStats()};this.getState=()=>this.adapter.getState();let a=new c(t,s);this.adapter=a}};
2
2
  //# sourceMappingURL=index.cjs.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts", "../src/adapters/HlsJsAdapter.ts", "../src/adapters/BaseAdapter.ts", "../src/controllers/HlsStats.ts"],
4
- "sourcesContent": ["export { HlsStats } from './controllers/HlsStats';\nexport type { IHlsStats } from './interfaces/IHlsStats';\n", "import Hls from 'hls.js';\nimport { BaseAdapter } from './BaseAdapter';\n\nexport class HlsJsAdapter extends BaseAdapter {\n timeUpdateHandler = () => {\n const bufferedDuration =\n this.videoEl.buffered.length > 0 ? this.videoEl.buffered.end(0) - this.videoEl.buffered.start(0) : 0;\n const distanceFromLive =\n (this.hlsInstance.liveSyncPosition ? this.hlsInstance.liveSyncPosition - this.videoEl.currentTime : 0) * 1000;\n const quality = this.videoEl.getVideoPlaybackQuality();\n const droppedFrames = quality.droppedVideoFrames;\n this.hlsStatsState = {\n ...this.hlsStatsState,\n distanceFromLive: distanceFromLive > 0 ? distanceFromLive : 0,\n bufferedDuration,\n droppedFrames,\n };\n };\n\n levelLoadedHandler = (_: any, { level }: { level: number }) => {\n const currentLevel = this.hlsInstance.levels[level];\n const { bitrate, height, width } = currentLevel;\n this.hlsStatsState = {\n ...this.hlsStatsState,\n bitrate,\n videoSize: {\n height,\n width,\n },\n };\n };\n\n fragChangedHandler = (_: any, { frag }: { frag: { stats: { bwEstimate: number }; baseurl: string } }) => {\n const { stats, baseurl } = frag;\n const { bwEstimate } = stats;\n this.hlsStatsState = {\n ...this.hlsStatsState,\n bandwidthEstimate: bwEstimate,\n url: baseurl,\n };\n };\n\n startGatheringStats(): void {\n this.hlsInstance.on(Hls.Events.FRAG_CHANGED, this.fragChangedHandler);\n this.hlsInstance.on(Hls.Events.LEVEL_LOADED, this.levelLoadedHandler);\n this.videoEl.addEventListener('timeupdate', this.timeUpdateHandler);\n }\n\n finishGatheringStats(): void {\n this.videoEl.removeEventListener('timeupdate', this.timeUpdateHandler);\n this.hlsInstance.off(Hls.Events.FRAG_CHANGED, this.fragChangedHandler);\n this.hlsInstance.off(Hls.Events.LEVEL_LOADED, this.levelLoadedHandler);\n }\n}\n", "import { HlsInstance, HlsPlayerStats } from '../interfaces';\n\nexport abstract class BaseAdapter {\n hlsInstance: HlsInstance = {} as HlsInstance;\n videoEl: HTMLVideoElement;\n hlsStatsState: HlsPlayerStats = {};\n constructor(hlsInstance: HlsInstance, videoEl: HTMLVideoElement) {\n this.hlsInstance = hlsInstance;\n this.videoEl = videoEl;\n }\n abstract startGatheringStats(): void;\n abstract finishGatheringStats(): void;\n getState() {\n return this.hlsStatsState;\n }\n}\n", "import { BaseAdapter } from '../adapters/BaseAdapter';\nimport { HlsJsAdapter } from '../adapters/HlsJsAdapter';\nimport { HlsInstance, HlsPlayerStats } from '../interfaces';\nimport { IHlsStats } from '../interfaces/IHlsStats';\n\nexport class HlsStats implements IHlsStats {\n adapter: BaseAdapter;\n intervalFunctionId = -1;\n constructor(hlsLibraryInstance: HlsInstance, videoEl: HTMLVideoElement) {\n const hlsJsAdapter = new HlsJsAdapter(hlsLibraryInstance, videoEl);\n this.adapter = hlsJsAdapter;\n }\n\n subscribe(callback: (state: HlsPlayerStats) => void, interval = 2000) {\n this.adapter.startGatheringStats();\n //@ts-ignore\n this.intervalFunctionId = setInterval(() => {\n callback(this.getState());\n }, interval);\n return this.unsubscribe.bind(this);\n }\n unsubscribe() {\n clearInterval(this.intervalFunctionId);\n this.adapter.finishGatheringStats();\n }\n\n getState() {\n return this.adapter.getState();\n }\n}\n"],
5
- "mappings": "s6BAAA,4BCAA,MAAgB,qBCET,WAA2B,CAIhC,YAAY,EAA0B,EAA2B,CAHjE,iBAA2B,GAE3B,mBAAgC,GAE9B,KAAK,YAAc,EACnB,KAAK,QAAU,EAIjB,UAAW,CACT,MAAO,MAAK,gBDVT,mBAA2B,EAAY,CAAvC,aAHP,CAGO,oBACL,uBAAoB,IAAM,CACxB,GAAM,GACJ,KAAK,QAAQ,SAAS,OAAS,EAAI,KAAK,QAAQ,SAAS,IAAI,GAAK,KAAK,QAAQ,SAAS,MAAM,GAAK,EAC/F,EACH,MAAK,YAAY,iBAAmB,KAAK,YAAY,iBAAmB,KAAK,QAAQ,YAAc,GAAK,IAErG,EAAgB,AADN,KAAK,QAAQ,0BACC,mBAC9B,KAAK,cAAgB,OAChB,KAAK,eADW,CAEnB,iBAAkB,EAAmB,EAAI,EAAmB,EAC5D,mBACA,mBAIJ,wBAAqB,CAAC,EAAQ,CAAE,WAA+B,CAC7D,GAAM,GAAe,KAAK,YAAY,OAAO,GACvC,CAAE,UAAS,SAAQ,SAAU,EACnC,KAAK,cAAgB,OAChB,KAAK,eADW,CAEnB,UACA,UAAW,CACT,SACA,YAKN,wBAAqB,CAAC,EAAQ,CAAE,UAAyE,CACvG,GAAM,CAAE,QAAO,WAAY,EACrB,CAAE,cAAe,EACvB,KAAK,cAAgB,OAChB,KAAK,eADW,CAEnB,kBAAmB,EACnB,IAAK,KAIT,qBAA4B,CAC1B,KAAK,YAAY,GAAG,UAAI,OAAO,aAAc,KAAK,oBAClD,KAAK,YAAY,GAAG,UAAI,OAAO,aAAc,KAAK,oBAClD,KAAK,QAAQ,iBAAiB,aAAc,KAAK,mBAGnD,sBAA6B,CAC3B,KAAK,QAAQ,oBAAoB,aAAc,KAAK,mBACpD,KAAK,YAAY,IAAI,UAAI,OAAO,aAAc,KAAK,oBACnD,KAAK,YAAY,IAAI,UAAI,OAAO,aAAc,KAAK,sBE9ChD,WAAoC,CAGzC,YAAY,EAAiC,EAA2B,CADxE,wBAAqB,GAEnB,GAAM,GAAe,GAAI,GAAa,EAAoB,GAC1D,KAAK,QAAU,EAGjB,UAAU,EAA2C,EAAW,IAAM,CACpE,YAAK,QAAQ,sBAEb,KAAK,mBAAqB,YAAY,IAAM,CAC1C,EAAS,KAAK,aACb,GACI,KAAK,YAAY,KAAK,MAE/B,aAAc,CACZ,cAAc,KAAK,oBACnB,KAAK,QAAQ,uBAGf,UAAW,CACT,MAAO,MAAK,QAAQ",
4
+ "sourcesContent": ["export { HlsStats } from './controllers/HlsStats';\nexport type { IHlsStats } from './interfaces/IHlsStats';\nexport type { HlsPlayerStats } from './interfaces/index';\n", "import Hls from 'hls.js';\nimport { BaseAdapter } from './BaseAdapter';\n\nexport class HlsJsAdapter extends BaseAdapter {\n timeUpdateHandler = () => {\n const bufferedDuration =\n this.videoEl.buffered.length > 0 ? this.videoEl.buffered.end(0) - this.videoEl.buffered.start(0) : 0;\n const distanceFromLive =\n (this.hlsInstance.liveSyncPosition ? this.hlsInstance.liveSyncPosition - this.videoEl.currentTime : 0) * 1000;\n const quality = this.videoEl.getVideoPlaybackQuality();\n const droppedFrames = quality.droppedVideoFrames;\n this.hlsStatsState = {\n ...this.hlsStatsState,\n distanceFromLive: distanceFromLive > 0 ? distanceFromLive : 0,\n bufferedDuration,\n droppedFrames,\n };\n };\n\n levelLoadedHandler = (_: any, { level }: { level: number }) => {\n const currentLevel = this.hlsInstance.levels[level];\n const { bitrate, height, width } = currentLevel;\n this.hlsStatsState = {\n ...this.hlsStatsState,\n bitrate,\n videoSize: {\n height,\n width,\n },\n };\n };\n\n fragChangedHandler = (_: any, { frag }: { frag: { stats: { bwEstimate: number }; baseurl: string } }) => {\n const { stats, baseurl } = frag;\n const { bwEstimate } = stats;\n this.hlsStatsState = {\n ...this.hlsStatsState,\n bandwidthEstimate: bwEstimate,\n url: baseurl,\n };\n };\n\n startGatheringStats(): void {\n this.hlsInstance.on(Hls.Events.FRAG_CHANGED, this.fragChangedHandler);\n this.hlsInstance.on(Hls.Events.LEVEL_LOADED, this.levelLoadedHandler);\n this.videoEl.addEventListener('timeupdate', this.timeUpdateHandler);\n }\n\n finishGatheringStats(): void {\n this.videoEl.removeEventListener('timeupdate', this.timeUpdateHandler);\n this.hlsInstance.off(Hls.Events.FRAG_CHANGED, this.fragChangedHandler);\n this.hlsInstance.off(Hls.Events.LEVEL_LOADED, this.levelLoadedHandler);\n }\n}\n", "import Hls from 'hls.js';\nimport { HlsPlayerStats } from '../interfaces';\nexport abstract class BaseAdapter {\n hlsInstance: Hls;\n videoEl: HTMLVideoElement;\n hlsStatsState: HlsPlayerStats = {};\n constructor(hlsInstance: Hls, videoEl: HTMLVideoElement) {\n this.hlsInstance = hlsInstance;\n this.videoEl = videoEl;\n }\n abstract startGatheringStats(): void;\n abstract finishGatheringStats(): void;\n getState() {\n return this.hlsStatsState;\n }\n}\n", "import Hls from 'hls.js';\nimport { BaseAdapter } from '../adapters/BaseAdapter';\nimport { HlsJsAdapter } from '../adapters/HlsJsAdapter';\nimport { HlsPlayerStats } from '../interfaces';\nimport { IHlsStats } from '../interfaces/IHlsStats';\n\nexport class HlsStats implements IHlsStats {\n adapter: BaseAdapter;\n intervalFunctionId = -1;\n constructor(hlsLibraryInstance: Hls, videoEl: HTMLVideoElement) {\n const hlsJsAdapter = new HlsJsAdapter(hlsLibraryInstance, videoEl);\n this.adapter = hlsJsAdapter;\n }\n\n subscribe = (callback: (state: HlsPlayerStats) => void, interval = 2000) => {\n this.adapter.startGatheringStats();\n //@ts-ignore\n this.intervalFunctionId = setInterval(() => {\n callback(this.getState());\n }, interval);\n return this.unsubscribe;\n };\n unsubscribe = () => {\n clearInterval(this.intervalFunctionId);\n this.adapter.finishGatheringStats();\n };\n\n getState = () => {\n return this.adapter.getState();\n };\n}\n"],
5
+ "mappings": "s6BAAA,4BCAA,MAAgB,qBCET,WAA2B,CAIhC,YAAY,EAAkB,EAA2B,CADzD,mBAAgC,GAE9B,KAAK,YAAc,EACnB,KAAK,QAAU,EAIjB,UAAW,CACT,MAAO,MAAK,gBDVT,mBAA2B,EAAY,CAAvC,aAHP,CAGO,oBACL,uBAAoB,IAAM,CACxB,GAAM,GACJ,KAAK,QAAQ,SAAS,OAAS,EAAI,KAAK,QAAQ,SAAS,IAAI,GAAK,KAAK,QAAQ,SAAS,MAAM,GAAK,EAC/F,EACH,MAAK,YAAY,iBAAmB,KAAK,YAAY,iBAAmB,KAAK,QAAQ,YAAc,GAAK,IAErG,EAAgB,AADN,KAAK,QAAQ,0BACC,mBAC9B,KAAK,cAAgB,OAChB,KAAK,eADW,CAEnB,iBAAkB,EAAmB,EAAI,EAAmB,EAC5D,mBACA,mBAIJ,wBAAqB,CAAC,EAAQ,CAAE,WAA+B,CAC7D,GAAM,GAAe,KAAK,YAAY,OAAO,GACvC,CAAE,UAAS,SAAQ,SAAU,EACnC,KAAK,cAAgB,OAChB,KAAK,eADW,CAEnB,UACA,UAAW,CACT,SACA,YAKN,wBAAqB,CAAC,EAAQ,CAAE,UAAyE,CACvG,GAAM,CAAE,QAAO,WAAY,EACrB,CAAE,cAAe,EACvB,KAAK,cAAgB,OAChB,KAAK,eADW,CAEnB,kBAAmB,EACnB,IAAK,KAIT,qBAA4B,CAC1B,KAAK,YAAY,GAAG,UAAI,OAAO,aAAc,KAAK,oBAClD,KAAK,YAAY,GAAG,UAAI,OAAO,aAAc,KAAK,oBAClD,KAAK,QAAQ,iBAAiB,aAAc,KAAK,mBAGnD,sBAA6B,CAC3B,KAAK,QAAQ,oBAAoB,aAAc,KAAK,mBACpD,KAAK,YAAY,IAAI,UAAI,OAAO,aAAc,KAAK,oBACnD,KAAK,YAAY,IAAI,UAAI,OAAO,aAAc,KAAK,sBE7ChD,WAAoC,CAGzC,YAAY,EAAyB,EAA2B,CADhE,wBAAqB,GAMrB,eAAY,CAAC,EAA2C,EAAW,MACjE,MAAK,QAAQ,sBAEb,KAAK,mBAAqB,YAAY,IAAM,CAC1C,EAAS,KAAK,aACb,GACI,KAAK,aAEd,iBAAc,IAAM,CAClB,cAAc,KAAK,oBACnB,KAAK,QAAQ,wBAGf,cAAW,IACF,KAAK,QAAQ,WAlBpB,GAAM,GAAe,GAAI,GAAa,EAAoB,GAC1D,KAAK,QAAU",
6
6
  "names": []
7
7
  }
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export { HlsStats } from './controllers/HlsStats';
2
2
  export type { IHlsStats } from './interfaces/IHlsStats';
3
+ export type { HlsPlayerStats } from './interfaces/index';
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- var v=Object.defineProperty,H=Object.defineProperties;var f=Object.getOwnPropertyDescriptors;var c=Object.getOwnPropertySymbols;var u=Object.prototype.hasOwnProperty,E=Object.prototype.propertyIsEnumerable;var S=(s,e,t)=>e in s?v(s,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):s[e]=t,n=(s,e)=>{for(var t in e||(e={}))u.call(e,t)&&S(s,t,e[t]);if(c)for(var t of c(e))E.call(e,t)&&S(s,t,e[t]);return s},r=(s,e)=>H(s,f(e));import l from"hls.js";var o=class{constructor(e,t){this.hlsInstance={};this.hlsStatsState={};this.hlsInstance=e,this.videoEl=t}getState(){return this.hlsStatsState}};var h=class extends o{constructor(){super(...arguments);this.timeUpdateHandler=()=>{let e=this.videoEl.buffered.length>0?this.videoEl.buffered.end(0)-this.videoEl.buffered.start(0):0,t=(this.hlsInstance.liveSyncPosition?this.hlsInstance.liveSyncPosition-this.videoEl.currentTime:0)*1e3,i=this.videoEl.getVideoPlaybackQuality().droppedVideoFrames;this.hlsStatsState=r(n({},this.hlsStatsState),{distanceFromLive:t>0?t:0,bufferedDuration:e,droppedFrames:i})};this.levelLoadedHandler=(e,{level:t})=>{let a=this.hlsInstance.levels[t],{bitrate:i,height:d,width:m}=a;this.hlsStatsState=r(n({},this.hlsStatsState),{bitrate:i,videoSize:{height:d,width:m}})};this.fragChangedHandler=(e,{frag:t})=>{let{stats:a,baseurl:i}=t,{bwEstimate:d}=a;this.hlsStatsState=r(n({},this.hlsStatsState),{bandwidthEstimate:d,url:i})}}startGatheringStats(){this.hlsInstance.on(l.Events.FRAG_CHANGED,this.fragChangedHandler),this.hlsInstance.on(l.Events.LEVEL_LOADED,this.levelLoadedHandler),this.videoEl.addEventListener("timeupdate",this.timeUpdateHandler)}finishGatheringStats(){this.videoEl.removeEventListener("timeupdate",this.timeUpdateHandler),this.hlsInstance.off(l.Events.FRAG_CHANGED,this.fragChangedHandler),this.hlsInstance.off(l.Events.LEVEL_LOADED,this.levelLoadedHandler)}};var p=class{constructor(e,t){this.intervalFunctionId=-1;let a=new h(e,t);this.adapter=a}subscribe(e,t=2e3){return this.adapter.startGatheringStats(),this.intervalFunctionId=setInterval(()=>{e(this.getState())},t),this.unsubscribe.bind(this)}unsubscribe(){clearInterval(this.intervalFunctionId),this.adapter.finishGatheringStats()}getState(){return this.adapter.getState()}};export{p as HlsStats};
1
+ var v=Object.defineProperty,f=Object.defineProperties;var H=Object.getOwnPropertyDescriptors;var c=Object.getOwnPropertySymbols;var u=Object.prototype.hasOwnProperty,E=Object.prototype.propertyIsEnumerable;var m=(s,e,t)=>e in s?v(s,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):s[e]=t,r=(s,e)=>{for(var t in e||(e={}))u.call(e,t)&&m(s,t,e[t]);if(c)for(var t of c(e))E.call(e,t)&&m(s,t,e[t]);return s},n=(s,e)=>f(s,H(e));import l from"hls.js";var d=class{constructor(e,t){this.hlsStatsState={};this.hlsInstance=e,this.videoEl=t}getState(){return this.hlsStatsState}};var h=class extends d{constructor(){super(...arguments);this.timeUpdateHandler=()=>{let e=this.videoEl.buffered.length>0?this.videoEl.buffered.end(0)-this.videoEl.buffered.start(0):0,t=(this.hlsInstance.liveSyncPosition?this.hlsInstance.liveSyncPosition-this.videoEl.currentTime:0)*1e3,i=this.videoEl.getVideoPlaybackQuality().droppedVideoFrames;this.hlsStatsState=n(r({},this.hlsStatsState),{distanceFromLive:t>0?t:0,bufferedDuration:e,droppedFrames:i})};this.levelLoadedHandler=(e,{level:t})=>{let a=this.hlsInstance.levels[t],{bitrate:i,height:o,width:S}=a;this.hlsStatsState=n(r({},this.hlsStatsState),{bitrate:i,videoSize:{height:o,width:S}})};this.fragChangedHandler=(e,{frag:t})=>{let{stats:a,baseurl:i}=t,{bwEstimate:o}=a;this.hlsStatsState=n(r({},this.hlsStatsState),{bandwidthEstimate:o,url:i})}}startGatheringStats(){this.hlsInstance.on(l.Events.FRAG_CHANGED,this.fragChangedHandler),this.hlsInstance.on(l.Events.LEVEL_LOADED,this.levelLoadedHandler),this.videoEl.addEventListener("timeupdate",this.timeUpdateHandler)}finishGatheringStats(){this.videoEl.removeEventListener("timeupdate",this.timeUpdateHandler),this.hlsInstance.off(l.Events.FRAG_CHANGED,this.fragChangedHandler),this.hlsInstance.off(l.Events.LEVEL_LOADED,this.levelLoadedHandler)}};var p=class{constructor(e,t){this.intervalFunctionId=-1;this.subscribe=(e,t=2e3)=>(this.adapter.startGatheringStats(),this.intervalFunctionId=setInterval(()=>{e(this.getState())},t),this.unsubscribe);this.unsubscribe=()=>{clearInterval(this.intervalFunctionId),this.adapter.finishGatheringStats()};this.getState=()=>this.adapter.getState();let a=new h(e,t);this.adapter=a}};export{p as HlsStats};
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/adapters/HlsJsAdapter.ts", "../src/adapters/BaseAdapter.ts", "../src/controllers/HlsStats.ts"],
4
- "sourcesContent": ["import Hls from 'hls.js';\nimport { BaseAdapter } from './BaseAdapter';\n\nexport class HlsJsAdapter extends BaseAdapter {\n timeUpdateHandler = () => {\n const bufferedDuration =\n this.videoEl.buffered.length > 0 ? this.videoEl.buffered.end(0) - this.videoEl.buffered.start(0) : 0;\n const distanceFromLive =\n (this.hlsInstance.liveSyncPosition ? this.hlsInstance.liveSyncPosition - this.videoEl.currentTime : 0) * 1000;\n const quality = this.videoEl.getVideoPlaybackQuality();\n const droppedFrames = quality.droppedVideoFrames;\n this.hlsStatsState = {\n ...this.hlsStatsState,\n distanceFromLive: distanceFromLive > 0 ? distanceFromLive : 0,\n bufferedDuration,\n droppedFrames,\n };\n };\n\n levelLoadedHandler = (_: any, { level }: { level: number }) => {\n const currentLevel = this.hlsInstance.levels[level];\n const { bitrate, height, width } = currentLevel;\n this.hlsStatsState = {\n ...this.hlsStatsState,\n bitrate,\n videoSize: {\n height,\n width,\n },\n };\n };\n\n fragChangedHandler = (_: any, { frag }: { frag: { stats: { bwEstimate: number }; baseurl: string } }) => {\n const { stats, baseurl } = frag;\n const { bwEstimate } = stats;\n this.hlsStatsState = {\n ...this.hlsStatsState,\n bandwidthEstimate: bwEstimate,\n url: baseurl,\n };\n };\n\n startGatheringStats(): void {\n this.hlsInstance.on(Hls.Events.FRAG_CHANGED, this.fragChangedHandler);\n this.hlsInstance.on(Hls.Events.LEVEL_LOADED, this.levelLoadedHandler);\n this.videoEl.addEventListener('timeupdate', this.timeUpdateHandler);\n }\n\n finishGatheringStats(): void {\n this.videoEl.removeEventListener('timeupdate', this.timeUpdateHandler);\n this.hlsInstance.off(Hls.Events.FRAG_CHANGED, this.fragChangedHandler);\n this.hlsInstance.off(Hls.Events.LEVEL_LOADED, this.levelLoadedHandler);\n }\n}\n", "import { HlsInstance, HlsPlayerStats } from '../interfaces';\n\nexport abstract class BaseAdapter {\n hlsInstance: HlsInstance = {} as HlsInstance;\n videoEl: HTMLVideoElement;\n hlsStatsState: HlsPlayerStats = {};\n constructor(hlsInstance: HlsInstance, videoEl: HTMLVideoElement) {\n this.hlsInstance = hlsInstance;\n this.videoEl = videoEl;\n }\n abstract startGatheringStats(): void;\n abstract finishGatheringStats(): void;\n getState() {\n return this.hlsStatsState;\n }\n}\n", "import { BaseAdapter } from '../adapters/BaseAdapter';\nimport { HlsJsAdapter } from '../adapters/HlsJsAdapter';\nimport { HlsInstance, HlsPlayerStats } from '../interfaces';\nimport { IHlsStats } from '../interfaces/IHlsStats';\n\nexport class HlsStats implements IHlsStats {\n adapter: BaseAdapter;\n intervalFunctionId = -1;\n constructor(hlsLibraryInstance: HlsInstance, videoEl: HTMLVideoElement) {\n const hlsJsAdapter = new HlsJsAdapter(hlsLibraryInstance, videoEl);\n this.adapter = hlsJsAdapter;\n }\n\n subscribe(callback: (state: HlsPlayerStats) => void, interval = 2000) {\n this.adapter.startGatheringStats();\n //@ts-ignore\n this.intervalFunctionId = setInterval(() => {\n callback(this.getState());\n }, interval);\n return this.unsubscribe.bind(this);\n }\n unsubscribe() {\n clearInterval(this.intervalFunctionId);\n this.adapter.finishGatheringStats();\n }\n\n getState() {\n return this.adapter.getState();\n }\n}\n"],
5
- "mappings": "6aAAA,sBCEO,WAA2B,CAIhC,YAAY,EAA0B,EAA2B,CAHjE,iBAA2B,GAE3B,mBAAgC,GAE9B,KAAK,YAAc,EACnB,KAAK,QAAU,EAIjB,UAAW,CACT,MAAO,MAAK,gBDVT,mBAA2B,EAAY,CAAvC,aAHP,CAGO,oBACL,uBAAoB,IAAM,CACxB,GAAM,GACJ,KAAK,QAAQ,SAAS,OAAS,EAAI,KAAK,QAAQ,SAAS,IAAI,GAAK,KAAK,QAAQ,SAAS,MAAM,GAAK,EAC/F,EACH,MAAK,YAAY,iBAAmB,KAAK,YAAY,iBAAmB,KAAK,QAAQ,YAAc,GAAK,IAErG,EAAgB,AADN,KAAK,QAAQ,0BACC,mBAC9B,KAAK,cAAgB,OAChB,KAAK,eADW,CAEnB,iBAAkB,EAAmB,EAAI,EAAmB,EAC5D,mBACA,mBAIJ,wBAAqB,CAAC,EAAQ,CAAE,WAA+B,CAC7D,GAAM,GAAe,KAAK,YAAY,OAAO,GACvC,CAAE,UAAS,SAAQ,SAAU,EACnC,KAAK,cAAgB,OAChB,KAAK,eADW,CAEnB,UACA,UAAW,CACT,SACA,YAKN,wBAAqB,CAAC,EAAQ,CAAE,UAAyE,CACvG,GAAM,CAAE,QAAO,WAAY,EACrB,CAAE,cAAe,EACvB,KAAK,cAAgB,OAChB,KAAK,eADW,CAEnB,kBAAmB,EACnB,IAAK,KAIT,qBAA4B,CAC1B,KAAK,YAAY,GAAG,EAAI,OAAO,aAAc,KAAK,oBAClD,KAAK,YAAY,GAAG,EAAI,OAAO,aAAc,KAAK,oBAClD,KAAK,QAAQ,iBAAiB,aAAc,KAAK,mBAGnD,sBAA6B,CAC3B,KAAK,QAAQ,oBAAoB,aAAc,KAAK,mBACpD,KAAK,YAAY,IAAI,EAAI,OAAO,aAAc,KAAK,oBACnD,KAAK,YAAY,IAAI,EAAI,OAAO,aAAc,KAAK,sBE9ChD,WAAoC,CAGzC,YAAY,EAAiC,EAA2B,CADxE,wBAAqB,GAEnB,GAAM,GAAe,GAAI,GAAa,EAAoB,GAC1D,KAAK,QAAU,EAGjB,UAAU,EAA2C,EAAW,IAAM,CACpE,YAAK,QAAQ,sBAEb,KAAK,mBAAqB,YAAY,IAAM,CAC1C,EAAS,KAAK,aACb,GACI,KAAK,YAAY,KAAK,MAE/B,aAAc,CACZ,cAAc,KAAK,oBACnB,KAAK,QAAQ,uBAGf,UAAW,CACT,MAAO,MAAK,QAAQ",
4
+ "sourcesContent": ["import Hls from 'hls.js';\nimport { BaseAdapter } from './BaseAdapter';\n\nexport class HlsJsAdapter extends BaseAdapter {\n timeUpdateHandler = () => {\n const bufferedDuration =\n this.videoEl.buffered.length > 0 ? this.videoEl.buffered.end(0) - this.videoEl.buffered.start(0) : 0;\n const distanceFromLive =\n (this.hlsInstance.liveSyncPosition ? this.hlsInstance.liveSyncPosition - this.videoEl.currentTime : 0) * 1000;\n const quality = this.videoEl.getVideoPlaybackQuality();\n const droppedFrames = quality.droppedVideoFrames;\n this.hlsStatsState = {\n ...this.hlsStatsState,\n distanceFromLive: distanceFromLive > 0 ? distanceFromLive : 0,\n bufferedDuration,\n droppedFrames,\n };\n };\n\n levelLoadedHandler = (_: any, { level }: { level: number }) => {\n const currentLevel = this.hlsInstance.levels[level];\n const { bitrate, height, width } = currentLevel;\n this.hlsStatsState = {\n ...this.hlsStatsState,\n bitrate,\n videoSize: {\n height,\n width,\n },\n };\n };\n\n fragChangedHandler = (_: any, { frag }: { frag: { stats: { bwEstimate: number }; baseurl: string } }) => {\n const { stats, baseurl } = frag;\n const { bwEstimate } = stats;\n this.hlsStatsState = {\n ...this.hlsStatsState,\n bandwidthEstimate: bwEstimate,\n url: baseurl,\n };\n };\n\n startGatheringStats(): void {\n this.hlsInstance.on(Hls.Events.FRAG_CHANGED, this.fragChangedHandler);\n this.hlsInstance.on(Hls.Events.LEVEL_LOADED, this.levelLoadedHandler);\n this.videoEl.addEventListener('timeupdate', this.timeUpdateHandler);\n }\n\n finishGatheringStats(): void {\n this.videoEl.removeEventListener('timeupdate', this.timeUpdateHandler);\n this.hlsInstance.off(Hls.Events.FRAG_CHANGED, this.fragChangedHandler);\n this.hlsInstance.off(Hls.Events.LEVEL_LOADED, this.levelLoadedHandler);\n }\n}\n", "import Hls from 'hls.js';\nimport { HlsPlayerStats } from '../interfaces';\nexport abstract class BaseAdapter {\n hlsInstance: Hls;\n videoEl: HTMLVideoElement;\n hlsStatsState: HlsPlayerStats = {};\n constructor(hlsInstance: Hls, videoEl: HTMLVideoElement) {\n this.hlsInstance = hlsInstance;\n this.videoEl = videoEl;\n }\n abstract startGatheringStats(): void;\n abstract finishGatheringStats(): void;\n getState() {\n return this.hlsStatsState;\n }\n}\n", "import Hls from 'hls.js';\nimport { BaseAdapter } from '../adapters/BaseAdapter';\nimport { HlsJsAdapter } from '../adapters/HlsJsAdapter';\nimport { HlsPlayerStats } from '../interfaces';\nimport { IHlsStats } from '../interfaces/IHlsStats';\n\nexport class HlsStats implements IHlsStats {\n adapter: BaseAdapter;\n intervalFunctionId = -1;\n constructor(hlsLibraryInstance: Hls, videoEl: HTMLVideoElement) {\n const hlsJsAdapter = new HlsJsAdapter(hlsLibraryInstance, videoEl);\n this.adapter = hlsJsAdapter;\n }\n\n subscribe = (callback: (state: HlsPlayerStats) => void, interval = 2000) => {\n this.adapter.startGatheringStats();\n //@ts-ignore\n this.intervalFunctionId = setInterval(() => {\n callback(this.getState());\n }, interval);\n return this.unsubscribe;\n };\n unsubscribe = () => {\n clearInterval(this.intervalFunctionId);\n this.adapter.finishGatheringStats();\n };\n\n getState = () => {\n return this.adapter.getState();\n };\n}\n"],
5
+ "mappings": "6aAAA,sBCEO,WAA2B,CAIhC,YAAY,EAAkB,EAA2B,CADzD,mBAAgC,GAE9B,KAAK,YAAc,EACnB,KAAK,QAAU,EAIjB,UAAW,CACT,MAAO,MAAK,gBDVT,mBAA2B,EAAY,CAAvC,aAHP,CAGO,oBACL,uBAAoB,IAAM,CACxB,GAAM,GACJ,KAAK,QAAQ,SAAS,OAAS,EAAI,KAAK,QAAQ,SAAS,IAAI,GAAK,KAAK,QAAQ,SAAS,MAAM,GAAK,EAC/F,EACH,MAAK,YAAY,iBAAmB,KAAK,YAAY,iBAAmB,KAAK,QAAQ,YAAc,GAAK,IAErG,EAAgB,AADN,KAAK,QAAQ,0BACC,mBAC9B,KAAK,cAAgB,OAChB,KAAK,eADW,CAEnB,iBAAkB,EAAmB,EAAI,EAAmB,EAC5D,mBACA,mBAIJ,wBAAqB,CAAC,EAAQ,CAAE,WAA+B,CAC7D,GAAM,GAAe,KAAK,YAAY,OAAO,GACvC,CAAE,UAAS,SAAQ,SAAU,EACnC,KAAK,cAAgB,OAChB,KAAK,eADW,CAEnB,UACA,UAAW,CACT,SACA,YAKN,wBAAqB,CAAC,EAAQ,CAAE,UAAyE,CACvG,GAAM,CAAE,QAAO,WAAY,EACrB,CAAE,cAAe,EACvB,KAAK,cAAgB,OAChB,KAAK,eADW,CAEnB,kBAAmB,EACnB,IAAK,KAIT,qBAA4B,CAC1B,KAAK,YAAY,GAAG,EAAI,OAAO,aAAc,KAAK,oBAClD,KAAK,YAAY,GAAG,EAAI,OAAO,aAAc,KAAK,oBAClD,KAAK,QAAQ,iBAAiB,aAAc,KAAK,mBAGnD,sBAA6B,CAC3B,KAAK,QAAQ,oBAAoB,aAAc,KAAK,mBACpD,KAAK,YAAY,IAAI,EAAI,OAAO,aAAc,KAAK,oBACnD,KAAK,YAAY,IAAI,EAAI,OAAO,aAAc,KAAK,sBE7ChD,WAAoC,CAGzC,YAAY,EAAyB,EAA2B,CADhE,wBAAqB,GAMrB,eAAY,CAAC,EAA2C,EAAW,MACjE,MAAK,QAAQ,sBAEb,KAAK,mBAAqB,YAAY,IAAM,CAC1C,EAAS,KAAK,aACb,GACI,KAAK,aAEd,iBAAc,IAAM,CAClB,cAAc,KAAK,oBACnB,KAAK,QAAQ,wBAGf,cAAW,IACF,KAAK,QAAQ,WAlBpB,GAAM,GAAe,GAAI,GAAa,EAAoB,GAC1D,KAAK,QAAU",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@100mslive/hls-stats",
3
- "version": "0.1.1-alpha.0",
3
+ "version": "0.2.0",
4
4
  "description": "A simple library that provides stats for your hls stream",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.js",
@@ -31,10 +31,10 @@
31
31
  "author": "Ragzzy-R",
32
32
  "license": "ISC",
33
33
  "devDependencies": {
34
- "hls.js": "^1.2.5"
34
+ "hls.js": "^1.3.0"
35
35
  },
36
36
  "peerDependencies": {
37
- "hls.js": "^1.2.5"
37
+ "hls.js": "^1.3.0"
38
38
  },
39
- "gitHead": "a2c7d3e49fa4de149b85e3576ebcbec51306c3fa"
39
+ "gitHead": "b008b67affec32d51602bc041b17a87469461844"
40
40
  }
@@ -1,10 +1,10 @@
1
- import { HlsInstance, HlsPlayerStats } from '../interfaces';
2
-
1
+ import Hls from 'hls.js';
2
+ import { HlsPlayerStats } from '../interfaces';
3
3
  export abstract class BaseAdapter {
4
- hlsInstance: HlsInstance = {} as HlsInstance;
4
+ hlsInstance: Hls;
5
5
  videoEl: HTMLVideoElement;
6
6
  hlsStatsState: HlsPlayerStats = {};
7
- constructor(hlsInstance: HlsInstance, videoEl: HTMLVideoElement) {
7
+ constructor(hlsInstance: Hls, videoEl: HTMLVideoElement) {
8
8
  this.hlsInstance = hlsInstance;
9
9
  this.videoEl = videoEl;
10
10
  }
@@ -1,30 +1,31 @@
1
+ import Hls from 'hls.js';
1
2
  import { BaseAdapter } from '../adapters/BaseAdapter';
2
3
  import { HlsJsAdapter } from '../adapters/HlsJsAdapter';
3
- import { HlsInstance, HlsPlayerStats } from '../interfaces';
4
+ import { HlsPlayerStats } from '../interfaces';
4
5
  import { IHlsStats } from '../interfaces/IHlsStats';
5
6
 
6
7
  export class HlsStats implements IHlsStats {
7
8
  adapter: BaseAdapter;
8
9
  intervalFunctionId = -1;
9
- constructor(hlsLibraryInstance: HlsInstance, videoEl: HTMLVideoElement) {
10
+ constructor(hlsLibraryInstance: Hls, videoEl: HTMLVideoElement) {
10
11
  const hlsJsAdapter = new HlsJsAdapter(hlsLibraryInstance, videoEl);
11
12
  this.adapter = hlsJsAdapter;
12
13
  }
13
14
 
14
- subscribe(callback: (state: HlsPlayerStats) => void, interval = 2000) {
15
+ subscribe = (callback: (state: HlsPlayerStats) => void, interval = 2000) => {
15
16
  this.adapter.startGatheringStats();
16
17
  //@ts-ignore
17
18
  this.intervalFunctionId = setInterval(() => {
18
19
  callback(this.getState());
19
20
  }, interval);
20
- return this.unsubscribe.bind(this);
21
- }
22
- unsubscribe() {
21
+ return this.unsubscribe;
22
+ };
23
+ unsubscribe = () => {
23
24
  clearInterval(this.intervalFunctionId);
24
25
  this.adapter.finishGatheringStats();
25
- }
26
+ };
26
27
 
27
- getState() {
28
+ getState = () => {
28
29
  return this.adapter.getState();
29
- }
30
+ };
30
31
  }
package/src/index.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export { HlsStats } from './controllers/HlsStats';
2
2
  export type { IHlsStats } from './interfaces/IHlsStats';
3
+ export type { HlsPlayerStats } from './interfaces/index';