@100mslive/hms-virtual-background 1.14.3-alpha.7 → 1.14.3-alpha.9

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,2 +1,2 @@
1
- "use strict";var f=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var b=Object.prototype.hasOwnProperty;var k=(r,e)=>{for(var t in e)f(r,t,{get:e[t],enumerable:!0})},v=(r,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of g(e))!b.call(r,i)&&i!==t&&f(r,i,{get:()=>e[i],enumerable:!(s=l(e,i))||s.enumerable});return r};var S=r=>v(f({},"__esModule",{value:!0}),r);var d=(r,e,t)=>new Promise((s,i)=>{var a=o=>{try{u(t.next(o))}catch(c){i(c)}},p=o=>{try{u(t.throw(o))}catch(c){i(c)}},u=o=>o.done?s(o.value):Promise.resolve(o.value).then(a,p);u((t=t.apply(r,e)).next())});var E={};k(E,{HMSEffectsPlugin:()=>h});module.exports=S(E);var m=require("effects-sdk");var n="https://assets.100ms.live/effectsdk/3.6.2/";var h=class{constructor(e,t){this.blurAmount=0;this.backgroundType="none";this.preset="balanced";this.TAG="[HMSEffectsPlugin]";this.operationQueue=Promise.resolve();this.effectRequestId=0;this.effects=new m.tsvb(e),this.onInit=t,this.initPromise=new Promise(s=>{this.resolveInit=s}),this.effects.config({sdk_url:n,models:{colorcorrector:"",facedetector:"",lowlighter:""},test_inference:!0,wasmPaths:{"ort-wasm.wasm":`${n}ort-wasm.wasm`,"ort-wasm-simd.wasm":`${n}ort-wasm-simd.wasm`,"ort-wasm-simd.jsep.wasm":`${n}ort-wasm-simd.jsep.wasm`}}),this.effects.onError(s=>{s.type==="error"&&s.message&&console.error(this.TAG,"Effects SDK error:",s.message)}),this.effects.cache(),this.effects.onReady=()=>{var s;this.effects&&(this.resolveInit(),(s=this.onInit)==null||s.call(this),this.effects.setBackgroundFitMode("fill"),this.effects.setSegmentationPreset(this.preset))}}getName(){return"HMSEffects"}isSupported(){return this.effects.isSupported()}enqueueOperation(e){return this.operationQueue=this.operationQueue.then(()=>this.initPromise).then(()=>e()).catch(t=>{console.error(this.TAG,"Operation failed:",t)}),this.operationQueue}removeBlur(){this.blurAmount=0,this.backgroundType==="blur"&&(this.backgroundType="none");let e=++this.effectRequestId;this.enqueueOperation(()=>{e===this.effectRequestId&&this.effects.clearBlur()})}removeBackground(){this.background="",this.backgroundType==="image"&&(this.backgroundType="none");let e=++this.effectRequestId;this.enqueueOperation(()=>{e===this.effectRequestId&&this.effects.clearBackground()})}setBlur(e){if(e<0||e>1)throw new Error("Blur amount should be between 0 and 1");this.blurAmount=e,this.background="",this.backgroundType="blur";let t=++this.effectRequestId;this.enqueueOperation(()=>{t===this.effectRequestId&&(this.effects.clearBackground(),this.effects.setBlur(this.blurAmount),this.effects.run())})}setPreset(e){return d(this,null,function*(){return this.preset=e,new Promise((t,s)=>{this.enqueueOperation(()=>{this.effects.setSegmentationPreset(this.preset).then(t).catch(s)})})})}onResolutionChange(e){this.onResolutionChangeCallback=e}getPreset(){return this.preset}removeEffects(){this.backgroundType="none",this.background="",this.blurAmount=0;let e=++this.effectRequestId;this.enqueueOperation(()=>{e===this.effectRequestId&&(this.effects.clearBackground(),this.effects.clearBlur(),this.effects.stop())})}setBackground(e){if(!e)throw new Error("Background url cannot be empty");this.background=e,this.blurAmount=0,this.backgroundType="image";let t=++this.effectRequestId;this.enqueueOperation(()=>{t===this.effectRequestId&&(this.effects.clearBlur(),this.effects.setBackground(this.background),this.effects.run())})}getBlurAmount(){return this.blurAmount}getBackground(){return this.background||this.backgroundType}getMetrics(){var e,t;return(t=(e=this.effects).getMetrics)==null?void 0:t.call(e)}apply(e){return this.effects.clear(),this.applyEffect(),this.effects.onChangeInputResolution(()=>{var s;let t=this.effects.getStream();if(t){let{height:i,width:a}=t.getVideoTracks()[0].getSettings();(s=this.onResolutionChangeCallback)==null||s.call(this,a,i)}}),this.effects.useStream(e),this.effects.getStream()||e}stop(){this.removeEffects()}applyEffect(){this.blurAmount?this.setBlur(this.blurAmount):this.background&&this.setBackground(this.background)}};
1
+ "use strict";var f=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var b=Object.prototype.hasOwnProperty;var k=(r,e)=>{for(var t in e)f(r,t,{get:e[t],enumerable:!0})},v=(r,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of g(e))!b.call(r,i)&&i!==t&&f(r,i,{get:()=>e[i],enumerable:!(s=l(e,i))||s.enumerable});return r};var S=r=>v(f({},"__esModule",{value:!0}),r);var d=(r,e,t)=>new Promise((s,i)=>{var a=o=>{try{u(t.next(o))}catch(c){i(c)}},p=o=>{try{u(t.throw(o))}catch(c){i(c)}},u=o=>o.done?s(o.value):Promise.resolve(o.value).then(a,p);u((t=t.apply(r,e)).next())});var E={};k(E,{HMSEffectsPlugin:()=>h});module.exports=S(E);var m=require("effects-sdk");var n="https://static.100ms.live/effectsdk/3.6.2/";var h=class{constructor(e,t){this.blurAmount=0;this.backgroundType="none";this.preset="balanced";this.TAG="[HMSEffectsPlugin]";this.operationQueue=Promise.resolve();this.effectRequestId=0;this.effects=new m.tsvb(e),this.onInit=t,this.initPromise=new Promise(s=>{this.resolveInit=s}),this.effects.config({sdk_url:n,models:{colorcorrector:"",facedetector:"",lowlighter:""},test_inference:!0,wasmPaths:{"ort-wasm.wasm":`${n}ort-wasm.wasm`,"ort-wasm-simd.wasm":`${n}ort-wasm-simd.wasm`,"ort-wasm-simd.jsep.wasm":`${n}ort-wasm-simd.jsep.wasm`}}),this.effects.onError(s=>{s.type==="error"&&s.message&&console.error(this.TAG,"Effects SDK error:",s.message)}),this.effects.cache(),this.effects.onReady=()=>{var s;this.effects&&(this.resolveInit(),(s=this.onInit)==null||s.call(this),this.effects.setBackgroundFitMode("fill"),this.effects.setSegmentationPreset(this.preset))}}getName(){return"HMSEffects"}isSupported(){return this.effects.isSupported()}enqueueOperation(e){return this.operationQueue=this.operationQueue.then(()=>this.initPromise).then(()=>e()).catch(t=>{console.error(this.TAG,"Operation failed:",t)}),this.operationQueue}removeBlur(){this.blurAmount=0,this.backgroundType==="blur"&&(this.backgroundType="none");let e=++this.effectRequestId;this.enqueueOperation(()=>{e===this.effectRequestId&&this.effects.clearBlur()})}removeBackground(){this.background="",this.backgroundType==="image"&&(this.backgroundType="none");let e=++this.effectRequestId;this.enqueueOperation(()=>{e===this.effectRequestId&&this.effects.clearBackground()})}setBlur(e){if(e<0||e>1)throw new Error("Blur amount should be between 0 and 1");this.blurAmount=e,this.background="",this.backgroundType="blur";let t=++this.effectRequestId;this.enqueueOperation(()=>{t===this.effectRequestId&&(this.effects.clearBackground(),this.effects.setBlur(this.blurAmount),this.effects.run())})}setPreset(e){return d(this,null,function*(){return this.preset=e,new Promise((t,s)=>{this.enqueueOperation(()=>{this.effects.setSegmentationPreset(this.preset).then(t).catch(s)})})})}onResolutionChange(e){this.onResolutionChangeCallback=e}getPreset(){return this.preset}removeEffects(){this.backgroundType="none",this.background="",this.blurAmount=0;let e=++this.effectRequestId;this.enqueueOperation(()=>{e===this.effectRequestId&&(this.effects.clearBackground(),this.effects.clearBlur(),this.effects.stop())})}setBackground(e){if(!e)throw new Error("Background url cannot be empty");this.background=e,this.blurAmount=0,this.backgroundType="image";let t=++this.effectRequestId;this.enqueueOperation(()=>{t===this.effectRequestId&&(this.effects.clearBlur(),this.effects.setBackground(this.background),this.effects.run())})}getBlurAmount(){return this.blurAmount}getBackground(){return this.background||this.backgroundType}getMetrics(){var e,t;return(t=(e=this.effects).getMetrics)==null?void 0:t.call(e)}apply(e){return this.effects.clear(),this.applyEffect(),this.effects.onChangeInputResolution(()=>{var s;let t=this.effects.getStream();if(t){let{height:i,width:a}=t.getVideoTracks()[0].getSettings();(s=this.onResolutionChangeCallback)==null||s.call(this,a,i)}}),this.effects.useStream(e),this.effects.getStream()||e}stop(){this.removeEffects()}applyEffect(){this.blurAmount?this.setBlur(this.blurAmount):this.background&&this.setBackground(this.background)}};
2
2
  //# sourceMappingURL=HMSEffectsPlugin.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/HMSEffectsPlugin.ts", "../../src/constants.ts"],
4
- "sourcesContent": ["import { tsvb } from 'effects-sdk';\nimport { HMSMediaStreamPlugin } from '@100mslive/hms-video-store';\nimport { EFFECTS_SDK_ASSETS } from './constants';\nimport { HMSVirtualBackgroundTypes } from './interfaces';\n\nexport type HMSEffectsBackground = string | MediaStream | MediaStreamTrack | HTMLVideoElement;\n\nexport class HMSEffectsPlugin implements HMSMediaStreamPlugin {\n private effects: tsvb;\n // Ranges from 0 to 1, inclusive\n private blurAmount = 0;\n private background?: HMSEffectsBackground;\n private backgroundType = HMSVirtualBackgroundTypes.NONE;\n private preset: 'balanced' | 'quality' | 'lightning' = 'balanced';\n private initPromise: Promise<void>;\n private resolveInit!: () => void;\n private onInit;\n private onResolutionChangeCallback?: (width: number, height: number) => void;\n private TAG = '[HMSEffectsPlugin]';\n // Queue to serialize effect operations and prevent race conditions\n private operationQueue: Promise<void> = Promise.resolve();\n // Counter to track the latest effect request and skip stale operations\n private effectRequestId = 0;\n\n constructor(effectsSDKKey: string, onInit?: () => void) {\n this.effects = new tsvb(effectsSDKKey);\n this.onInit = onInit;\n this.initPromise = new Promise(resolve => {\n this.resolveInit = resolve;\n });\n this.effects.config({\n sdk_url: EFFECTS_SDK_ASSETS,\n models: {\n colorcorrector: '',\n facedetector: '',\n lowlighter: '',\n },\n // provider: 'auto',\n test_inference: true,\n wasmPaths: {\n 'ort-wasm.wasm': `${EFFECTS_SDK_ASSETS}ort-wasm.wasm`,\n 'ort-wasm-simd.wasm': `${EFFECTS_SDK_ASSETS}ort-wasm-simd.wasm`,\n 'ort-wasm-simd.jsep.wasm': `${EFFECTS_SDK_ASSETS}ort-wasm-simd.jsep.wasm`,\n },\n });\n this.effects.onError(err => {\n // The SDK fires various messages through onError:\n // - Info messages with type='info' (we ignore these)\n // - Error messages with type='error' and a message property\n // - Raw Event objects with no message (we ignore these as they're not actionable)\n if (err.type === 'error' && err.message) {\n console.error(this.TAG, 'Effects SDK error:', err.message);\n }\n });\n this.effects.cache();\n this.effects.onReady = () => {\n if (this.effects) {\n this.resolveInit();\n this.onInit?.();\n this.effects.setBackgroundFitMode('fill');\n this.effects.setSegmentationPreset(this.preset);\n }\n };\n }\n\n getName(): string {\n return 'HMSEffects';\n }\n\n isSupported(): boolean {\n return this.effects.isSupported();\n }\n\n private enqueueOperation(callback: () => void): Promise<void> {\n this.operationQueue = this.operationQueue\n .then(() => this.initPromise)\n .then(() => callback())\n .catch(err => {\n console.error(this.TAG, 'Operation failed:', err);\n });\n return this.operationQueue;\n }\n\n removeBlur() {\n this.blurAmount = 0;\n if (this.backgroundType === HMSVirtualBackgroundTypes.BLUR) {\n this.backgroundType = HMSVirtualBackgroundTypes.NONE;\n }\n const requestId = ++this.effectRequestId;\n this.enqueueOperation(() => {\n // Skip if a newer effect request was made\n if (requestId !== this.effectRequestId) {\n return;\n }\n this.effects.clearBlur();\n });\n }\n\n removeBackground() {\n this.background = '';\n if (this.backgroundType === HMSVirtualBackgroundTypes.IMAGE) {\n this.backgroundType = HMSVirtualBackgroundTypes.NONE;\n }\n const requestId = ++this.effectRequestId;\n this.enqueueOperation(() => {\n // Skip if a newer effect request was made\n if (requestId !== this.effectRequestId) {\n return;\n }\n this.effects.clearBackground();\n });\n }\n\n /**\n * @param blur ranges between 0 and 1\n */\n setBlur(blur: number) {\n if (blur < 0 || blur > 1) {\n throw new Error('Blur amount should be between 0 and 1');\n }\n this.blurAmount = blur;\n this.background = '';\n this.backgroundType = HMSVirtualBackgroundTypes.BLUR;\n const requestId = ++this.effectRequestId;\n this.enqueueOperation(() => {\n // Skip if a newer effect request was made\n if (requestId !== this.effectRequestId) {\n return;\n }\n this.effects.clearBackground();\n this.effects.setBlur(this.blurAmount);\n this.effects.run();\n });\n }\n\n /**\n * @param preset can be 'quality' or 'balanced'. The 'quality' preset has better quality but higher CPU usage than 'balanced'\n */\n async setPreset(preset: 'quality' | 'balanced') {\n this.preset = preset;\n return new Promise((resolve, reject) => {\n this.enqueueOperation(() => {\n this.effects.setSegmentationPreset(this.preset).then(resolve).catch(reject);\n });\n });\n }\n\n onResolutionChange(callback: (width: number, height: number) => void) {\n this.onResolutionChangeCallback = callback;\n }\n\n getPreset() {\n return this.preset;\n }\n\n removeEffects() {\n this.backgroundType = HMSVirtualBackgroundTypes.NONE;\n this.background = '';\n this.blurAmount = 0;\n const requestId = ++this.effectRequestId;\n this.enqueueOperation(() => {\n // Skip if a newer effect request was made\n if (requestId !== this.effectRequestId) {\n return;\n }\n this.effects.clearBackground();\n this.effects.clearBlur();\n this.effects.stop();\n });\n }\n\n setBackground(url: HMSEffectsBackground) {\n if (!url) {\n throw new Error('Background url cannot be empty');\n }\n this.background = url;\n this.blurAmount = 0;\n this.backgroundType = HMSVirtualBackgroundTypes.IMAGE;\n const requestId = ++this.effectRequestId;\n this.enqueueOperation(() => {\n // Skip if a newer effect request was made\n if (requestId !== this.effectRequestId) {\n return;\n }\n this.effects.clearBlur();\n this.effects.setBackground(this.background);\n this.effects.run();\n });\n }\n\n getBlurAmount() {\n return this.blurAmount;\n }\n\n getBackground() {\n return this.background || this.backgroundType;\n }\n\n /**\n * Get performance metrics from the effects SDK\n * @returns metrics object with fps, processing time, etc.\n */\n getMetrics() {\n return this.effects.getMetrics?.();\n }\n\n apply(stream: MediaStream): MediaStream {\n this.effects.clear();\n this.applyEffect();\n this.effects.onChangeInputResolution(() => {\n const effectsStream = this.effects.getStream();\n if (effectsStream) {\n const { height, width } = effectsStream.getVideoTracks()[0].getSettings();\n this.onResolutionChangeCallback?.(width!, height!);\n }\n });\n this.effects.useStream(stream);\n return this.effects.getStream() || stream;\n }\n\n stop() {\n this.removeEffects();\n }\n\n private applyEffect() {\n if (this.blurAmount) {\n this.setBlur(this.blurAmount);\n } else if (this.background) {\n this.setBackground(this.background);\n }\n }\n}\n", "export const EFFECTS_SDK_ASSETS = 'https://assets.100ms.live/effectsdk/3.6.2/';\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { tsvb } from 'effects-sdk';\nimport { HMSMediaStreamPlugin } from '@100mslive/hms-video-store';\nimport { EFFECTS_SDK_ASSETS } from './constants';\nimport { HMSVirtualBackgroundTypes } from './interfaces';\n\nexport type HMSEffectsBackground = string | MediaStream | MediaStreamTrack | HTMLVideoElement;\n\nexport class HMSEffectsPlugin implements HMSMediaStreamPlugin {\n private effects: tsvb;\n // Ranges from 0 to 1, inclusive\n private blurAmount = 0;\n private background?: HMSEffectsBackground;\n private backgroundType = HMSVirtualBackgroundTypes.NONE;\n private preset: 'balanced' | 'quality' | 'lightning' = 'balanced';\n private initPromise: Promise<void>;\n private resolveInit!: () => void;\n private onInit;\n private onResolutionChangeCallback?: (width: number, height: number) => void;\n private TAG = '[HMSEffectsPlugin]';\n // Queue to serialize effect operations and prevent race conditions\n private operationQueue: Promise<void> = Promise.resolve();\n // Counter to track the latest effect request and skip stale operations\n private effectRequestId = 0;\n\n constructor(effectsSDKKey: string, onInit?: () => void) {\n this.effects = new tsvb(effectsSDKKey);\n this.onInit = onInit;\n this.initPromise = new Promise(resolve => {\n this.resolveInit = resolve;\n });\n this.effects.config({\n sdk_url: EFFECTS_SDK_ASSETS,\n models: {\n colorcorrector: '',\n facedetector: '',\n lowlighter: '',\n },\n // provider: 'auto',\n test_inference: true,\n wasmPaths: {\n 'ort-wasm.wasm': `${EFFECTS_SDK_ASSETS}ort-wasm.wasm`,\n 'ort-wasm-simd.wasm': `${EFFECTS_SDK_ASSETS}ort-wasm-simd.wasm`,\n 'ort-wasm-simd.jsep.wasm': `${EFFECTS_SDK_ASSETS}ort-wasm-simd.jsep.wasm`,\n },\n });\n this.effects.onError(err => {\n // The SDK fires various messages through onError:\n // - Info messages with type='info' (we ignore these)\n // - Error messages with type='error' and a message property\n // - Raw Event objects with no message (we ignore these as they're not actionable)\n if (err.type === 'error' && err.message) {\n console.error(this.TAG, 'Effects SDK error:', err.message);\n }\n });\n this.effects.cache();\n this.effects.onReady = () => {\n if (this.effects) {\n this.resolveInit();\n this.onInit?.();\n this.effects.setBackgroundFitMode('fill');\n this.effects.setSegmentationPreset(this.preset);\n }\n };\n }\n\n getName(): string {\n return 'HMSEffects';\n }\n\n isSupported(): boolean {\n return this.effects.isSupported();\n }\n\n private enqueueOperation(callback: () => void): Promise<void> {\n this.operationQueue = this.operationQueue\n .then(() => this.initPromise)\n .then(() => callback())\n .catch(err => {\n console.error(this.TAG, 'Operation failed:', err);\n });\n return this.operationQueue;\n }\n\n removeBlur() {\n this.blurAmount = 0;\n if (this.backgroundType === HMSVirtualBackgroundTypes.BLUR) {\n this.backgroundType = HMSVirtualBackgroundTypes.NONE;\n }\n const requestId = ++this.effectRequestId;\n this.enqueueOperation(() => {\n // Skip if a newer effect request was made\n if (requestId !== this.effectRequestId) {\n return;\n }\n this.effects.clearBlur();\n });\n }\n\n removeBackground() {\n this.background = '';\n if (this.backgroundType === HMSVirtualBackgroundTypes.IMAGE) {\n this.backgroundType = HMSVirtualBackgroundTypes.NONE;\n }\n const requestId = ++this.effectRequestId;\n this.enqueueOperation(() => {\n // Skip if a newer effect request was made\n if (requestId !== this.effectRequestId) {\n return;\n }\n this.effects.clearBackground();\n });\n }\n\n /**\n * @param blur ranges between 0 and 1\n */\n setBlur(blur: number) {\n if (blur < 0 || blur > 1) {\n throw new Error('Blur amount should be between 0 and 1');\n }\n this.blurAmount = blur;\n this.background = '';\n this.backgroundType = HMSVirtualBackgroundTypes.BLUR;\n const requestId = ++this.effectRequestId;\n this.enqueueOperation(() => {\n // Skip if a newer effect request was made\n if (requestId !== this.effectRequestId) {\n return;\n }\n this.effects.clearBackground();\n this.effects.setBlur(this.blurAmount);\n this.effects.run();\n });\n }\n\n /**\n * @param preset can be 'quality' or 'balanced'. The 'quality' preset has better quality but higher CPU usage than 'balanced'\n */\n async setPreset(preset: 'quality' | 'balanced') {\n this.preset = preset;\n return new Promise((resolve, reject) => {\n this.enqueueOperation(() => {\n this.effects.setSegmentationPreset(this.preset).then(resolve).catch(reject);\n });\n });\n }\n\n onResolutionChange(callback: (width: number, height: number) => void) {\n this.onResolutionChangeCallback = callback;\n }\n\n getPreset() {\n return this.preset;\n }\n\n removeEffects() {\n this.backgroundType = HMSVirtualBackgroundTypes.NONE;\n this.background = '';\n this.blurAmount = 0;\n const requestId = ++this.effectRequestId;\n this.enqueueOperation(() => {\n // Skip if a newer effect request was made\n if (requestId !== this.effectRequestId) {\n return;\n }\n this.effects.clearBackground();\n this.effects.clearBlur();\n this.effects.stop();\n });\n }\n\n setBackground(url: HMSEffectsBackground) {\n if (!url) {\n throw new Error('Background url cannot be empty');\n }\n this.background = url;\n this.blurAmount = 0;\n this.backgroundType = HMSVirtualBackgroundTypes.IMAGE;\n const requestId = ++this.effectRequestId;\n this.enqueueOperation(() => {\n // Skip if a newer effect request was made\n if (requestId !== this.effectRequestId) {\n return;\n }\n this.effects.clearBlur();\n this.effects.setBackground(this.background);\n this.effects.run();\n });\n }\n\n getBlurAmount() {\n return this.blurAmount;\n }\n\n getBackground() {\n return this.background || this.backgroundType;\n }\n\n /**\n * Get performance metrics from the effects SDK\n * @returns metrics object with fps, processing time, etc.\n */\n getMetrics() {\n return this.effects.getMetrics?.();\n }\n\n apply(stream: MediaStream): MediaStream {\n this.effects.clear();\n this.applyEffect();\n this.effects.onChangeInputResolution(() => {\n const effectsStream = this.effects.getStream();\n if (effectsStream) {\n const { height, width } = effectsStream.getVideoTracks()[0].getSettings();\n this.onResolutionChangeCallback?.(width!, height!);\n }\n });\n this.effects.useStream(stream);\n return this.effects.getStream() || stream;\n }\n\n stop() {\n this.removeEffects();\n }\n\n private applyEffect() {\n if (this.blurAmount) {\n this.setBlur(this.blurAmount);\n } else if (this.background) {\n this.setBackground(this.background);\n }\n }\n}\n", "export const EFFECTS_SDK_ASSETS = 'https://static.100ms.live/effectsdk/3.6.2/';\n"],
5
+ "mappings": "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",
6
6
  "names": ["HMSEffectsPlugin_exports", "__export", "HMSEffectsPlugin", "__toCommonJS", "import_effects_sdk", "EFFECTS_SDK_ASSETS", "HMSEffectsPlugin", "effectsSDKKey", "onInit", "resolve", "EFFECTS_SDK_ASSETS", "err", "_a", "callback", "requestId", "blur", "preset", "__async", "reject", "url", "_b", "stream", "effectsStream", "height", "width"]
7
7
  }
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["../../src/HMSVBPlugin.ts", "../../src/interfaces.ts"],
4
4
  "sourcesContent": ["/* eslint-disable complexity */\nimport { Results as MediaPipeResults, SelfieSegmentation } from '@mediapipe/selfie_segmentation';\nimport { decompressFrames, parseGIF } from 'gifuct-js';\nimport {\n HMSPluginSupportResult,\n HMSPluginUnsupportedTypes,\n HMSVideoPlugin,\n HMSVideoPluginType,\n} from '@100mslive/hms-video-store';\nimport { HMSBackgroundInput, HMSVirtualBackground, HMSVirtualBackgroundTypes } from './interfaces';\n\nexport class HMSVBPlugin implements HMSVideoPlugin {\n private TAG = '[HMSVBPlugin]';\n private background: HMSVirtualBackground = HMSVirtualBackgroundTypes.NONE;\n private backgroundType: HMSVirtualBackgroundTypes = HMSVirtualBackgroundTypes.NONE;\n private segmentation!: SelfieSegmentation;\n private outputCanvas?: HTMLCanvasElement;\n private outputCtx?: CanvasRenderingContext2D | null;\n\n private gifFrames: any;\n private gifFramesIndex: number;\n private gifFrameImageData: any;\n private tempGifCanvas: HTMLCanvasElement;\n private tempGifContext: CanvasRenderingContext2D | null;\n private prevResults?: MediaPipeResults;\n private input?: HTMLCanvasElement;\n\n constructor(background: HMSVirtualBackground, backgroundType: HMSVirtualBackgroundTypes) {\n this.background = background;\n this.backgroundType = backgroundType;\n this.gifFrames = null;\n this.gifFramesIndex = 0;\n this.gifFrameImageData = null;\n this.tempGifCanvas = document.createElement('canvas');\n this.tempGifContext = this.tempGifCanvas.getContext('2d');\n\n this.setBackground(this.background, this.backgroundType);\n this.log('Virtual background plugin initialised');\n }\n\n isSupported(): boolean {\n return this.checkSupport().isSupported;\n }\n\n isBlurSupported(): boolean {\n return 'filter' in CanvasRenderingContext2D.prototype;\n }\n\n checkSupport(): HMSPluginSupportResult {\n const browserResult = {} as HMSPluginSupportResult;\n if (['Chrome', 'Firefox', 'Edg', 'Edge', 'Safari'].some(value => navigator.userAgent.indexOf(value) !== -1)) {\n browserResult.isSupported = true;\n } else {\n browserResult.isSupported = false;\n browserResult.errType = HMSPluginUnsupportedTypes.PLATFORM_NOT_SUPPORTED;\n browserResult.errMsg = 'browser not supported for plugin, see docs';\n }\n\n return browserResult;\n }\n\n getName(): string {\n return 'HMSVB';\n }\n\n getPluginType(): HMSVideoPluginType {\n return HMSVideoPluginType.TRANSFORM;\n }\n\n async init(): Promise<void> {\n if (!this.segmentation) {\n this.segmentation = new SelfieSegmentation({\n locateFile: (file: string) => {\n return `https://cdn.jsdelivr.net/npm/@mediapipe/selfie_segmentation@0.1/${file}`;\n },\n });\n this.segmentation.setOptions({ selfieMode: false, modelSelection: 1 });\n this.segmentation.onResults(this.handleResults);\n }\n }\n\n /**\n * For bgType HMSVirtualBackgroundTypes.IMAGE pass bg as an image element\n * For bgType HMSVirtualBackgroundTypes.VIDEO pass video\n * For bgType HMSVirtualBackgroundTypes.GIF pass the gif url\n * @param {HMSVirtualBackground} background\n * @param {HMSVirtualBackgroundTypes} backgroundType\n */\n async setBackground(background: HMSVirtualBackground, backgroundType: HMSVirtualBackgroundTypes) {\n if (!background) {\n throw new Error('Invalid background supplied, see the docs to check supported background type');\n }\n this.prevResults = undefined;\n switch (backgroundType) {\n case HMSVirtualBackgroundTypes.NONE:\n case HMSVirtualBackgroundTypes.BLUR:\n this.background = background;\n this.backgroundType = backgroundType;\n break;\n case HMSVirtualBackgroundTypes.IMAGE:\n this.log('setting background to image', background);\n // eslint-disable-next-line no-case-declarations\n const img = await this.setImage(background as HTMLImageElement);\n if (!img || !img.complete || !img.naturalHeight) {\n throw new Error('Invalid image. Provide a valid and successfully loaded HTMLImageElement');\n } else {\n this.background = img;\n this.backgroundType = HMSVirtualBackgroundTypes.IMAGE;\n }\n break;\n case HMSVirtualBackgroundTypes.VIDEO:\n this.log('setting background to video', background);\n this.backgroundType = HMSVirtualBackgroundTypes.NONE;\n this.background = background as HTMLVideoElement;\n this.background.crossOrigin = 'anonymous';\n this.background.muted = true;\n this.background.loop = true;\n this.background.playsInline = true;\n this.background.oncanplaythrough = async () => {\n if (this.background && this.background instanceof HTMLVideoElement) {\n try {\n await this.background.play();\n this.backgroundType = HMSVirtualBackgroundTypes.VIDEO;\n } catch (e) {\n this.log('failed to play background', background);\n }\n }\n };\n break;\n case HMSVirtualBackgroundTypes.CANVAS:\n this.background = background;\n this.backgroundType = HMSVirtualBackgroundTypes.CANVAS;\n break;\n case HMSVirtualBackgroundTypes.GIF:\n this.log('setting gif to background', background);\n this.backgroundType = HMSVirtualBackgroundTypes.NONE;\n this.background = background as string;\n this.gifFrames = await this.loadGIF(this.background);\n if (this.gifFrames != null && this.gifFrames.length > 0) {\n this.backgroundType = HMSVirtualBackgroundTypes.GIF;\n } else {\n throw new Error('Invalid background supplied, see the docs to check supported background type');\n }\n break;\n default:\n this.log(\n `backgroundType did not match with any of the supported background types - ${HMSVirtualBackgroundTypes}`,\n );\n }\n }\n\n getBackground() {\n return this.background;\n }\n\n stop(): void {\n if (this.backgroundType !== HMSVirtualBackgroundTypes.BLUR && this.background !== HMSVirtualBackgroundTypes.NONE) {\n this.segmentation?.reset();\n }\n //gif related\n this.gifFrameImageData = null;\n this.gifFrames = null;\n this.gifFramesIndex = 0;\n this.background = HMSVirtualBackgroundTypes.NONE;\n this.backgroundType = HMSVirtualBackgroundTypes.NONE;\n }\n\n async processVideoFrame(input: HTMLCanvasElement, output: HTMLCanvasElement, skipProcessing?: boolean) {\n if (!input || !output) {\n throw new Error('Plugin invalid input/output');\n }\n this.input = input;\n output.width = input.width;\n output.height = input.height;\n this.outputCanvas = output;\n this.outputCtx = output.getContext('2d');\n if (skipProcessing && this.prevResults) {\n this.handleResults(this.prevResults);\n return;\n }\n if (this.backgroundType === HMSVirtualBackgroundTypes.NONE) {\n this.outputCtx?.drawImage(input, 0, 0, input.width, input.height);\n return;\n }\n await this.segmentation.send({ image: input });\n }\n\n private async setImage(image: HTMLImageElement): Promise<any> {\n image.crossOrigin = 'anonymous';\n return new Promise((resolve, reject) => {\n image.onload = () => resolve(image);\n image.onerror = reject;\n });\n }\n\n private handleResults = (results: MediaPipeResults) => {\n if (!this.outputCanvas || !this.outputCtx) {\n return;\n }\n this.outputCtx.save();\n this.outputCtx.clearRect(0, 0, this.outputCanvas.width, this.outputCanvas.height);\n switch (this.backgroundType) {\n case HMSVirtualBackgroundTypes.IMAGE:\n case HMSVirtualBackgroundTypes.CANVAS:\n case HMSVirtualBackgroundTypes.VIDEO:\n this.renderBackground(results, this.background as HMSBackgroundInput);\n break;\n case HMSVirtualBackgroundTypes.GIF:\n this.renderGIF(results);\n break;\n case HMSVirtualBackgroundTypes.BLUR:\n this.renderBlur(results);\n break;\n }\n this.outputCtx.restore();\n this.prevResults = results;\n };\n\n private loadGIF(url: string): Promise<any> {\n return fetch(url)\n .then(resp => resp.arrayBuffer())\n .then(buff => parseGIF(buff))\n .then(gif => {\n return decompressFrames(gif, true);\n });\n }\n\n private log(...data: any[]) {\n console.debug(this.TAG, ...data);\n }\n\n private renderBackground = (results: MediaPipeResults, background: HMSBackgroundInput) => {\n if (\n !this.input ||\n !this.outputCanvas ||\n !this.outputCtx ||\n this.backgroundType === HMSVirtualBackgroundTypes.NONE ||\n this.backgroundType === HMSVirtualBackgroundTypes.BLUR\n ) {\n return;\n }\n this.outputCtx.filter = 'none';\n this.outputCtx.imageSmoothingEnabled = true;\n this.outputCtx.imageSmoothingQuality = 'high';\n // Only overwrite existing pixels.\n this.outputCtx.globalCompositeOperation = 'source-out';\n const bgWidth = background instanceof HTMLVideoElement ? background.videoWidth : background.width;\n const bgHeight = background instanceof HTMLVideoElement ? background.videoHeight : background.height;\n\n this.outputCtx.drawImage(\n background,\n 0,\n 0,\n bgWidth,\n bgHeight,\n 0,\n 0,\n this.outputCanvas.width,\n this.outputCanvas.height,\n );\n this.outputCtx.globalCompositeOperation = 'destination-out';\n this.outputCtx.drawImage(results.segmentationMask, 0, 0, this.outputCanvas.width, this.outputCanvas.height);\n // Only overwrite missing pixels.\n this.outputCtx.globalCompositeOperation = 'destination-atop';\n this.outputCtx.drawImage(this.input, 0, 0, this.outputCanvas.width, this.outputCanvas.height);\n };\n\n private renderBlur(results: MediaPipeResults) {\n if (!this.outputCanvas || !this.outputCtx || this.backgroundType !== HMSVirtualBackgroundTypes.BLUR) {\n return;\n }\n this.outputCtx!.filter = 'none';\n this.outputCtx!.globalCompositeOperation = 'source-out';\n this.outputCtx?.drawImage(results.image, 0, 0, this.outputCanvas.width, this.outputCanvas.height);\n this.outputCtx!.globalCompositeOperation = 'destination-atop';\n this.outputCtx?.drawImage(results.segmentationMask, 0, 0, this.outputCanvas.width, this.outputCanvas.height);\n this.outputCtx!.filter = `blur(${Math.floor(this.outputCanvas.width / 160) * 5}px)`;\n this.outputCtx?.drawImage(results.image, 0, 0, this.outputCanvas.width, this.outputCanvas.height);\n }\n\n private renderGIF(results: MediaPipeResults) {\n if (\n !this.outputCanvas ||\n !this.outputCtx ||\n !this.tempGifContext ||\n this.backgroundType !== HMSVirtualBackgroundTypes.GIF\n ) {\n return;\n }\n if (this.gifFrameImageData == null) {\n const dims = this.gifFrames[this.gifFramesIndex].dims;\n this.tempGifCanvas.width = dims.width;\n this.tempGifCanvas.height = dims.height;\n this.gifFrameImageData = this.tempGifContext.createImageData(dims.width, dims.height);\n }\n // set the patch data as an override\n this.gifFrameImageData.data.set(this.gifFrames[this.gifFramesIndex].patch);\n this.tempGifContext.putImageData(this.gifFrameImageData, 0, 0);\n this.gifFramesIndex = (this.gifFramesIndex + 1) % this.gifFrames.length;\n this.renderBackground(results, this.tempGifCanvas);\n }\n}\n\nexport { HMSVirtualBackgroundTypes };\n", "export type HMSBackgroundInput = HTMLImageElement | HTMLVideoElement | HTMLCanvasElement;\nexport enum HMSVirtualBackgroundTypes {\n BLUR = 'blur',\n NONE = 'none',\n GIF = 'gif',\n IMAGE = 'image',\n VIDEO = 'video',\n CANVAS = 'canvas',\n}\n\nexport type HMSVirtualBackground =\n | string\n | HMSVirtualBackgroundTypes.BLUR\n | HMSVirtualBackgroundTypes.NONE\n | HMSBackgroundInput;\n"],
5
- "mappings": "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",
5
+ "mappings": "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",
6
6
  "names": ["HMSVBPlugin_exports", "__export", "HMSVBPlugin", "HMSVirtualBackgroundTypes", "__toCommonJS", "import_selfie_segmentation", "import_gifuct_js", "import_hms_video_store", "HMSVirtualBackgroundTypes", "HMSVBPlugin", "background", "backgroundType", "results", "bgWidth", "bgHeight", "browserResult", "value", "__async", "file", "img", "e", "HMSVirtualBackgroundTypes", "_a", "input", "output", "skipProcessing", "image", "resolve", "reject", "url", "resp", "buff", "gif", "data", "_b", "_c", "dims"]
7
7
  }
package/dist/cjs/index.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var V=Object.defineProperty;var Q=Object.getOwnPropertyDescriptor;var K=Object.getOwnPropertyNames;var J=Object.prototype.hasOwnProperty;var Y=(a,t)=>()=>(t||a((t={exports:{}}).exports,t),t.exports),X=(a,t)=>{for(var e in t)V(a,e,{get:t[e],enumerable:!0})},Z=(a,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of K(t))!J.call(a,s)&&s!==e&&V(a,s,{get:()=>t[s],enumerable:!(i=Q(t,s))||i.enumerable});return a};var tt=a=>Z(V({},"__esModule",{value:!0}),a);var o=(a,t,e)=>new Promise((i,s)=>{var r=h=>{try{u(e.next(h))}catch(d){s(d)}},n=h=>{try{u(e.throw(h))}catch(d){s(d)}},u=h=>h.done?i(h.value):Promise.resolve(h.value).then(r,n);u((e=e.apply(a,t)).next())});var L=Y((mt,et)=>{et.exports={version:"1.14.3-alpha.7",license:"MIT",name:"@100mslive/hms-virtual-background",author:"100ms",module:"dist/esm/index.js",main:"dist/cjs/index.js",typings:"dist/index.d.ts",typesVersions:{"*":{hmsvbplugin:["./dist/HMSVBPlugin.d.ts"],hmseffectsplugin:["./dist/HMSEffectsPlugin.d.ts"]}},exports:{".":{import:"./dist/esm/index.js",require:"./dist/cjs/index.js",default:"./dist/esm/index.js",types:"./dist/index.d.ts"},"./hmsvbplugin":{import:"./dist/esm/HMSVBPlugin.js",require:"./dist/cjs/HMSVBPlugin.js",default:"./dist/esm/HMSVBPlugin.js",types:"./dist/HMSVBPlugin.d.ts"},"./hmseffectsplugin":{import:"./dist/esm/HMSEffectsPlugin.js",default:"./dist/esm/HMSEffectsPlugin.js",require:"./dist/cjs/HMSEffectsPlugin.js",types:"./dist/HMSEffectsPlugin.d.ts"}},repository:{type:"git",url:"https://github.com/100mslive/web-sdks.git",directory:"packages/hms-virtual-background"},files:["dist","src/tflite","src/models"],scripts:{start:'concurrently "yarn dev" "yarn types"',dev:"node ../../scripts/dev","build:only":"node ../../scripts/build",build:"yarn build:only && yarn types:build",types:"tsc -w","types:build":"tsc -p tsconfig.json",test:"jest --maxWorkers=1 --passWithNoTests",lint:"eslint -c ../../.eslintrc .","lint:fix":"yarn lint --fix",prepare:"yarn build",size:"size-limit",analyze:"size-limit --why",format:"prettier --write src/**/*.ts"},peerDependencies:{"@100mslive/hms-video-store":"0.13.3-alpha.7"},devDependencies:{"@100mslive/hms-video-store":"0.13.3-alpha.7"},dependencies:{"@mediapipe/selfie_segmentation":"^0.1.1632777926","@tensorflow-models/body-segmentation":"^1.0.1","@tensorflow/tfjs-backend-webgl":"^3.3.0","@tensorflow/tfjs-converter":"^3.19.0","@tensorflow/tfjs-core":"^3.19.0","@webassemblyjs/helper-wasm-bytecode":"1.11.1","@webassemblyjs/wasm-gen":"1.11.1","effects-sdk":"3.6.2","gifuct-js":"^2.1.2","wasm-check":"^2.0.2"},eslintIgnore:["tflite.js","tflite-simd.js","tflite.wasm","tflite-simd.wasm","defineTFLite.ts","importing.test.ts"],gitHead:"d6ee0b945aece0a65a5279792dada3b7eed2cabb"}});var pt={};X(pt,{HMSEffectsPlugin:()=>T,HMSVBPlugin:()=>w,HMSVirtualBackgroundPlugin:()=>O,HMSVirtualBackgroundTypes:()=>p});module.exports=tt(pt);var I=require("gifuct-js"),x=require("@100mslive/hms-video-store"),Mt=require("@tensorflow/tfjs-backend-webgl");var it=L(),R=`https://unpkg.com/${it.name}/src`,C="VBProcessor",st="tflite/tflite.js",at="tflite/tflite-simd.js",nt="models/selfie_segmentation_landscape.tflite",_=a=>new Promise(function(t,e){let i=document.createElement("script");i.src=a,i.onload=t,i.onerror=e,document.head.appendChild(i)}),ot=()=>o(void 0,null,function*(){let a,t=`${R}/${at}`;yield _(t);try{a=yield createTFLiteSIMDModule()}catch(e){console.warn("SIMD not supported. You may experience poor virtual background effect."),t=`${R}/${st}`,yield _(t),a=yield createTFLiteModule()}return a}),q=()=>o(void 0,null,function*(){let a=`${R}/${nt}`,[t,e]=yield Promise.all([ot(),fetch(a)]),i=yield e.arrayBuffer(),s=t._getModelBufferMemoryOffset();return t.HEAPU8.set(new Uint8Array(i),s),t._loadModel(i.byteLength),console.debug(C,"Input memory offset:",t._getInputMemoryOffset()),console.debug(C,"Input height:",t._getInputHeight()),console.debug(C,"Input width:",t._getInputWidth()),console.debug(C,"Input channels:",t._getInputChannelCount()),t});var y="VBProcessor",rt=33,ut=L(),ht=214,dt=855,gt=120,lt=720,O=class{constructor(t,e=!1){this.backgroundType="none";this.background=t,this.enableSharpening=e,this.backgroundImage=null,this.backgroundVideo=null,this.personMaskWidth=256,this.personMaskHeight=144,this.isVirtualBackground=!1,this.blurValue="10px",this.loadModelCalled=!1,this.tfLite=null,this.modelName="landscape-segmentation",this.outputCtx=null,this.input=null,this.output=null,this.timerID=0,this.imageAspectRatio=1,this.personMaskPixelCount=this.personMaskWidth*this.personMaskHeight,this.personMask=new ImageData(this.personMaskWidth,this.personMaskHeight),this.personMaskCanvas=document.createElement("canvas"),this.personMaskCanvas.width=this.personMaskWidth,this.personMaskCanvas.height=this.personMaskHeight,this.personMaskCtx=this.personMaskCanvas.getContext("2d"),this.filters={},this.gifFrames=null,this.gifFramesIndex=0,this.gifFrameImageData=null,this.tempGifCanvas=document.createElement("canvas"),this.tempGifContext=this.tempGifCanvas.getContext("2d"),this.giflocalCount=0,this.enableSharpening=e,this.log(y,"Virtual Background plugin created"),this.setBackground(this.background)}init(){return o(this,null,function*(){this.loadModelCalled?yield this.tfLitePromise:(this.log(y,"PREVIOUS LOADED MODEL IS ",this.tfLite),this.loadModelCalled=!0,this.tfLitePromise=q(),this.tfLite=yield this.tfLitePromise),this.enableSharpening&&this.initSharpenFilter()})}isSupported(){return navigator.userAgent.indexOf("Chrome")!==-1||navigator.userAgent.indexOf("Firefox")!==-1||navigator.userAgent.indexOf("Edg")!==-1||navigator.userAgent.indexOf("Edge")!==-1}checkSupport(){let t={};return["Chrome","Firefox","Edg","Edge"].some(e=>navigator.userAgent.indexOf(e)!==-1)?t.isSupported=!0:(t.isSupported=!1,t.errType=x.HMSPluginUnsupportedTypes.PLATFORM_NOT_SUPPORTED,t.errMsg="browser not supported for plugin, see docs"),t}getName(){return ut.name}getPluginType(){return x.HMSVideoPluginType.TRANSFORM}setBackground(t){return o(this,null,function*(){if(t!=="")if(t==="none")this.log(y,"setting background to :",t),this.background="none",this.backgroundType="none",this.isVirtualBackground=!1;else if(t==="blur")this.log(y,"setting background to :",t),this.background="blur",this.backgroundType="blur",this.isVirtualBackground=!1;else if(t instanceof HTMLImageElement){this.log("setting background to image",t);let e=yield this.setImage(t);if(!e||!e.complete||!e.naturalHeight)throw new Error("Invalid image. Provide a valid and successfully loaded HTMLImageElement");this.isVirtualBackground=!0,this.backgroundImage=e,this.backgroundType="image"}else if(t instanceof HTMLVideoElement)this.log("setting background to video",t),this.backgroundVideo=t,this.backgroundVideo.crossOrigin="anonymous",this.backgroundVideo.muted=!0,this.backgroundVideo.loop=!0,this.backgroundVideo.oncanplaythrough=()=>o(this,null,function*(){this.backgroundVideo!=null&&(yield this.backgroundVideo.play(),this.isVirtualBackground=!0,this.backgroundType="video")});else if(console.log("setting gif to background"),this.gifFrames=yield this.setGiF(t),this.gifFrames!=null&&this.gifFrames.length>0)this.backgroundType="gif",this.isVirtualBackground=!0;else throw new Error("Invalid background supplied, see the docs to check supported background type");else throw new Error("Invalid background supplied, see the docs to check supported background type")})}stop(){var t,e;this.isVirtualBackground&&((t=this.backgroundImage)==null||t.removeAttribute("src"),(e=this.backgroundVideo)==null||e.removeAttribute("src"),this.backgroundType==="video"&&(this.backgroundVideo.loop=!1,this.backgroundVideo=null)),this.outputCtx&&(this.outputCtx.fillStyle="rgb(0, 0, 0)",this.outputCtx.fillRect(0,0,this.output.width,this.output.height)),this.gifFrameImageData=null,this.gifFrames=null,this.giflocalCount=0,this.gifFramesIndex=0}processVideoFrame(t,e,i){if(!t||!e)throw new Error("Plugin invalid input/output");this.input=t,this.output=e;let s=e.getContext("2d");if(s.canvas.width!==t.width&&(s.canvas.width=t.width),s.canvas.height!==t.height&&(s.canvas.height=t.height),this.backgroundType==="video"&&(this.backgroundVideo.width=t.width,this.backgroundVideo.height=t.height),this.outputCtx=s,this.imageAspectRatio=t.width/t.height,this.imageAspectRatio<=0)throw new Error("Invalid input width/height");let r=()=>o(this,null,function*(){yield this.runSegmentation(i)});this.background==="none"&&!this.isVirtualBackground?(this.outputCtx.globalCompositeOperation="copy",this.outputCtx.filter="none",this.outputCtx.drawImage(t,0,0,t.width,t.height)):r()}setImage(t){return o(this,null,function*(){return t.crossOrigin="anonymous",new Promise((e,i)=>{t.onload=()=>e(t),t.onerror=i})})}setGiF(t){return fetch(t).then(e=>e.arrayBuffer()).then(e=>(0,I.parseGIF)(e)).then(e=>(0,I.decompressFrames)(e,!0))}log(t,...e){console.info(t,...e)}resizeInputData(){this.personMaskCtx.drawImage(this.input,0,0,this.input.width,this.input.height,0,0,this.personMaskWidth,this.personMaskHeight);let t=this.personMaskCtx.getImageData(0,0,this.personMaskWidth,this.personMaskHeight),e=this.tfLite._getInputMemoryOffset()/4;for(let i=0;i<this.personMaskPixelCount;i++)this.tfLite.HEAPF32[e+i*3]=t.data[i*4]/255,this.tfLite.HEAPF32[e+i*3+1]=t.data[i*4+1]/255,this.tfLite.HEAPF32[e+i*3+2]=t.data[i*4+2]/255}infer(t){t||this.tfLite._runInference();let e=this.tfLite._getOutputMemoryOffset()/4;for(let i=0;i<this.personMaskPixelCount;i++)if(this.modelName==="meet"){let s=this.tfLite.HEAPF32[e+i*2],r=this.tfLite.HEAPF32[e+i*2+1],n=Math.max(s,r),u=Math.exp(s-n),h=Math.exp(r-n);this.personMask.data[i*4+3]=255*h/(u+h)}else if(this.modelName==="landscape-segmentation"){let s=this.tfLite.HEAPF32[e+i];this.personMask.data[i*4+3]=255*s}this.personMaskCtx.putImageData(this.personMask,0,0)}postProcessing(){this.outputCtx.globalCompositeOperation="copy",this.outputCtx.filter="none",this.isVirtualBackground?this.outputCtx.filter="blur(4px)":this.outputCtx.filter="blur(8px)",this.drawPersonMask(),this.outputCtx.globalCompositeOperation="source-in",this.outputCtx.filter="none",this.outputCtx.drawImage(this.input,0,0),this.enableSharpening&&this.output.width>ht&&this.output.height>gt&&this.output.width<dt&&this.output.height<lt&&this.sharpenFilter(),this.drawSegmentedBackground()}sharpenFilter(){let t=this.outputCtx.getImageData(0,0,this.output.width,this.output.height),e=this.filters.convolute(t);this.outputCtx.putImageData(e,0,0)}drawPersonMask(){this.outputCtx.drawImage(this.personMaskCanvas,0,0,this.personMaskWidth,this.personMaskHeight,0,0,this.output.width,this.output.height)}drawSegmentedBackground(){this.outputCtx.globalCompositeOperation="destination-over",this.outputCtx.imageSmoothingEnabled=!0,this.outputCtx.imageSmoothingQuality="high",this.isVirtualBackground?this.backgroundType==="video"&&this.backgroundVideo!=null&&this.backgroundVideo.readyState>=4?this.fitVideoToBackground():this.backgroundType==="image"?this.fitImageToBackground():this.backgroundType==="gif"&&(this.giflocalCount>this.gifFrames[this.gifFramesIndex].delay/rt?(this.gifFramesIndex++,this.gifFramesIndex>=this.gifFrames.length&&(this.gifFramesIndex=0),this.giflocalCount=0):this.giflocalCount++,this.fitGifToBackground()):this.addBlurToBackground()}runSegmentation(t){return o(this,null,function*(){this.tfLite&&(this.resizeInputData(),yield this.infer(t),this.postProcessing())})}fitVideoToBackground(){this.fitData(this.backgroundVideo,this.backgroundVideo.videoWidth,this.backgroundVideo.videoHeight)}fitImageToBackground(){this.fitData(this.backgroundImage,this.backgroundImage.width,this.backgroundImage.height)}fitGifToBackground(){if(this.gifFrameImageData==null){let t=this.gifFrames[this.gifFramesIndex].dims;this.tempGifCanvas.width=t.width,this.tempGifCanvas.height=t.height,this.gifFrameImageData=this.tempGifContext.createImageData(t.width,t.height)}this.gifFrameImageData.data.set(this.gifFrames[this.gifFramesIndex].patch),this.tempGifContext.putImageData(this.gifFrameImageData,0,0),this.fitData(this.tempGifCanvas,this.gifFrameImageData.width,this.gifFrameImageData.height)}fitData(t,e,i){let s,r,n,u;e/i<this.imageAspectRatio?(s=e,r=e/this.imageAspectRatio,n=0,u=(i-r)/2):(r=i,s=i*this.imageAspectRatio,u=0,n=(e-s)/2),this.outputCtx.drawImage(t,n,u,s,r,0,0,this.output.width,this.output.height)}addBlurToBackground(){return o(this,null,function*(){let t="15px";this.input.width<=160?t="5px":this.input.width<=320?t="10px":this.input.width<=640?t="15px":this.input.width<=960?t="20px":this.input.width<=1280?t="25px":this.input.width<=1920&&(t="30px"),this.outputCtx.filter=`blur(${t})`,this.outputCtx.drawImage(this.input,0,0,this.output.width,this.output.height)})}initSharpenFilter(){this.filters.tmpCanvas=document.createElement("canvas"),this.filters.tmpCtx=this.filters.tmpCanvas.getContext("2d"),this.filters.createImageData=(t,e)=>this.filters.tmpCtx.createImageData(t,e),this.filters.convolute=(t,e=[0,-1,0,-1,5,-1,0,-1,0],i)=>{let s=Math.round(Math.sqrt(e.length)),r=Math.floor(s/2),n=t.data,u=t.width,h=t.height,d=u,F=h,A=this.filters.createImageData(d,F),f=A.data,W=i?1:0;for(let g=0;g<F;g=g+1)for(let l=0;l<d;l=l+1){let c=(g*d+l)*4;if(n[c+3]!==0&&l<d&&g<F){let $=g,z=l,D=0,G=0,N=0,H=0;for(let k=0;k<s;k++)for(let b=0;b<s;b++){let P=$+k-r,B=z+b-r;if(P>=0&&P<h&&B>=0&&B<u){let v=(P*u+B)*4,M=e[k*s+b];D+=n[v]*M,G+=n[v+1]*M,N+=n[v+2]*M,H+=n[v+3]*M}}f[c]=D,f[c+1]=G,f[c+2]=N,f[c+3]=H+W*(255-H)}}return A}}};var j=require("@mediapipe/selfie_segmentation"),S=require("gifuct-js"),E=require("@100mslive/hms-video-store");var p=(n=>(n.BLUR="blur",n.NONE="none",n.GIF="gif",n.IMAGE="image",n.VIDEO="video",n.CANVAS="canvas",n))(p||{});var w=class{constructor(t,e){this.TAG="[HMSVBPlugin]";this.background="none";this.backgroundType="none";this.handleResults=t=>{if(!(!this.outputCanvas||!this.outputCtx)){switch(this.outputCtx.save(),this.outputCtx.clearRect(0,0,this.outputCanvas.width,this.outputCanvas.height),this.backgroundType){case"image":case"canvas":case"video":this.renderBackground(t,this.background);break;case"gif":this.renderGIF(t);break;case"blur":this.renderBlur(t);break}this.outputCtx.restore(),this.prevResults=t}};this.renderBackground=(t,e)=>{if(!this.input||!this.outputCanvas||!this.outputCtx||this.backgroundType==="none"||this.backgroundType==="blur")return;this.outputCtx.filter="none",this.outputCtx.imageSmoothingEnabled=!0,this.outputCtx.imageSmoothingQuality="high",this.outputCtx.globalCompositeOperation="source-out";let i=e instanceof HTMLVideoElement?e.videoWidth:e.width,s=e instanceof HTMLVideoElement?e.videoHeight:e.height;this.outputCtx.drawImage(e,0,0,i,s,0,0,this.outputCanvas.width,this.outputCanvas.height),this.outputCtx.globalCompositeOperation="destination-out",this.outputCtx.drawImage(t.segmentationMask,0,0,this.outputCanvas.width,this.outputCanvas.height),this.outputCtx.globalCompositeOperation="destination-atop",this.outputCtx.drawImage(this.input,0,0,this.outputCanvas.width,this.outputCanvas.height)};this.background=t,this.backgroundType=e,this.gifFrames=null,this.gifFramesIndex=0,this.gifFrameImageData=null,this.tempGifCanvas=document.createElement("canvas"),this.tempGifContext=this.tempGifCanvas.getContext("2d"),this.setBackground(this.background,this.backgroundType),this.log("Virtual background plugin initialised")}isSupported(){return this.checkSupport().isSupported}isBlurSupported(){return"filter"in CanvasRenderingContext2D.prototype}checkSupport(){let t={};return["Chrome","Firefox","Edg","Edge","Safari"].some(e=>navigator.userAgent.indexOf(e)!==-1)?t.isSupported=!0:(t.isSupported=!1,t.errType=E.HMSPluginUnsupportedTypes.PLATFORM_NOT_SUPPORTED,t.errMsg="browser not supported for plugin, see docs"),t}getName(){return"HMSVB"}getPluginType(){return E.HMSVideoPluginType.TRANSFORM}init(){return o(this,null,function*(){this.segmentation||(this.segmentation=new j.SelfieSegmentation({locateFile:t=>`https://cdn.jsdelivr.net/npm/@mediapipe/selfie_segmentation@0.1/${t}`}),this.segmentation.setOptions({selfieMode:!1,modelSelection:1}),this.segmentation.onResults(this.handleResults))})}setBackground(t,e){return o(this,null,function*(){if(!t)throw new Error("Invalid background supplied, see the docs to check supported background type");switch(this.prevResults=void 0,e){case"none":case"blur":this.background=t,this.backgroundType=e;break;case"image":this.log("setting background to image",t);let i=yield this.setImage(t);if(!i||!i.complete||!i.naturalHeight)throw new Error("Invalid image. Provide a valid and successfully loaded HTMLImageElement");this.background=i,this.backgroundType="image";break;case"video":this.log("setting background to video",t),this.backgroundType="none",this.background=t,this.background.crossOrigin="anonymous",this.background.muted=!0,this.background.loop=!0,this.background.playsInline=!0,this.background.oncanplaythrough=()=>o(this,null,function*(){if(this.background&&this.background instanceof HTMLVideoElement)try{yield this.background.play(),this.backgroundType="video"}catch(s){this.log("failed to play background",t)}});break;case"canvas":this.background=t,this.backgroundType="canvas";break;case"gif":if(this.log("setting gif to background",t),this.backgroundType="none",this.background=t,this.gifFrames=yield this.loadGIF(this.background),this.gifFrames!=null&&this.gifFrames.length>0)this.backgroundType="gif";else throw new Error("Invalid background supplied, see the docs to check supported background type");break;default:this.log(`backgroundType did not match with any of the supported background types - ${p}`)}})}getBackground(){return this.background}stop(){var t;this.backgroundType!=="blur"&&this.background!=="none"&&((t=this.segmentation)==null||t.reset()),this.gifFrameImageData=null,this.gifFrames=null,this.gifFramesIndex=0,this.background="none",this.backgroundType="none"}processVideoFrame(t,e,i){return o(this,null,function*(){var s;if(!t||!e)throw new Error("Plugin invalid input/output");if(this.input=t,e.width=t.width,e.height=t.height,this.outputCanvas=e,this.outputCtx=e.getContext("2d"),i&&this.prevResults){this.handleResults(this.prevResults);return}if(this.backgroundType==="none"){(s=this.outputCtx)==null||s.drawImage(t,0,0,t.width,t.height);return}yield this.segmentation.send({image:t})})}setImage(t){return o(this,null,function*(){return t.crossOrigin="anonymous",new Promise((e,i)=>{t.onload=()=>e(t),t.onerror=i})})}loadGIF(t){return fetch(t).then(e=>e.arrayBuffer()).then(e=>(0,S.parseGIF)(e)).then(e=>(0,S.decompressFrames)(e,!0))}log(...t){console.debug(this.TAG,...t)}renderBlur(t){var e,i,s;!this.outputCanvas||!this.outputCtx||this.backgroundType!=="blur"||(this.outputCtx.filter="none",this.outputCtx.globalCompositeOperation="source-out",(e=this.outputCtx)==null||e.drawImage(t.image,0,0,this.outputCanvas.width,this.outputCanvas.height),this.outputCtx.globalCompositeOperation="destination-atop",(i=this.outputCtx)==null||i.drawImage(t.segmentationMask,0,0,this.outputCanvas.width,this.outputCanvas.height),this.outputCtx.filter=`blur(${Math.floor(this.outputCanvas.width/160)*5}px)`,(s=this.outputCtx)==null||s.drawImage(t.image,0,0,this.outputCanvas.width,this.outputCanvas.height))}renderGIF(t){if(!(!this.outputCanvas||!this.outputCtx||!this.tempGifContext||this.backgroundType!=="gif")){if(this.gifFrameImageData==null){let e=this.gifFrames[this.gifFramesIndex].dims;this.tempGifCanvas.width=e.width,this.tempGifCanvas.height=e.height,this.gifFrameImageData=this.tempGifContext.createImageData(e.width,e.height)}this.gifFrameImageData.data.set(this.gifFrames[this.gifFramesIndex].patch),this.tempGifContext.putImageData(this.gifFrameImageData,0,0),this.gifFramesIndex=(this.gifFramesIndex+1)%this.gifFrames.length,this.renderBackground(t,this.tempGifCanvas)}}};var U=require("effects-sdk");var m="https://assets.100ms.live/effectsdk/3.6.2/";var T=class{constructor(t,e){this.blurAmount=0;this.backgroundType="none";this.preset="balanced";this.TAG="[HMSEffectsPlugin]";this.operationQueue=Promise.resolve();this.effectRequestId=0;this.effects=new U.tsvb(t),this.onInit=e,this.initPromise=new Promise(i=>{this.resolveInit=i}),this.effects.config({sdk_url:m,models:{colorcorrector:"",facedetector:"",lowlighter:""},test_inference:!0,wasmPaths:{"ort-wasm.wasm":`${m}ort-wasm.wasm`,"ort-wasm-simd.wasm":`${m}ort-wasm-simd.wasm`,"ort-wasm-simd.jsep.wasm":`${m}ort-wasm-simd.jsep.wasm`}}),this.effects.onError(i=>{i.type==="error"&&i.message&&console.error(this.TAG,"Effects SDK error:",i.message)}),this.effects.cache(),this.effects.onReady=()=>{var i;this.effects&&(this.resolveInit(),(i=this.onInit)==null||i.call(this),this.effects.setBackgroundFitMode("fill"),this.effects.setSegmentationPreset(this.preset))}}getName(){return"HMSEffects"}isSupported(){return this.effects.isSupported()}enqueueOperation(t){return this.operationQueue=this.operationQueue.then(()=>this.initPromise).then(()=>t()).catch(e=>{console.error(this.TAG,"Operation failed:",e)}),this.operationQueue}removeBlur(){this.blurAmount=0,this.backgroundType==="blur"&&(this.backgroundType="none");let t=++this.effectRequestId;this.enqueueOperation(()=>{t===this.effectRequestId&&this.effects.clearBlur()})}removeBackground(){this.background="",this.backgroundType==="image"&&(this.backgroundType="none");let t=++this.effectRequestId;this.enqueueOperation(()=>{t===this.effectRequestId&&this.effects.clearBackground()})}setBlur(t){if(t<0||t>1)throw new Error("Blur amount should be between 0 and 1");this.blurAmount=t,this.background="",this.backgroundType="blur";let e=++this.effectRequestId;this.enqueueOperation(()=>{e===this.effectRequestId&&(this.effects.clearBackground(),this.effects.setBlur(this.blurAmount),this.effects.run())})}setPreset(t){return o(this,null,function*(){return this.preset=t,new Promise((e,i)=>{this.enqueueOperation(()=>{this.effects.setSegmentationPreset(this.preset).then(e).catch(i)})})})}onResolutionChange(t){this.onResolutionChangeCallback=t}getPreset(){return this.preset}removeEffects(){this.backgroundType="none",this.background="",this.blurAmount=0;let t=++this.effectRequestId;this.enqueueOperation(()=>{t===this.effectRequestId&&(this.effects.clearBackground(),this.effects.clearBlur(),this.effects.stop())})}setBackground(t){if(!t)throw new Error("Background url cannot be empty");this.background=t,this.blurAmount=0,this.backgroundType="image";let e=++this.effectRequestId;this.enqueueOperation(()=>{e===this.effectRequestId&&(this.effects.clearBlur(),this.effects.setBackground(this.background),this.effects.run())})}getBlurAmount(){return this.blurAmount}getBackground(){return this.background||this.backgroundType}getMetrics(){var t,e;return(e=(t=this.effects).getMetrics)==null?void 0:e.call(t)}apply(t){return this.effects.clear(),this.applyEffect(),this.effects.onChangeInputResolution(()=>{var i;let e=this.effects.getStream();if(e){let{height:s,width:r}=e.getVideoTracks()[0].getSettings();(i=this.onResolutionChangeCallback)==null||i.call(this,r,s)}}),this.effects.useStream(t),this.effects.getStream()||t}stop(){this.removeEffects()}applyEffect(){this.blurAmount?this.setBlur(this.blurAmount):this.background&&this.setBackground(this.background)}};
1
+ "use strict";var V=Object.defineProperty;var Q=Object.getOwnPropertyDescriptor;var K=Object.getOwnPropertyNames;var J=Object.prototype.hasOwnProperty;var Y=(a,t)=>()=>(t||a((t={exports:{}}).exports,t),t.exports),X=(a,t)=>{for(var e in t)V(a,e,{get:t[e],enumerable:!0})},Z=(a,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of K(t))!J.call(a,s)&&s!==e&&V(a,s,{get:()=>t[s],enumerable:!(i=Q(t,s))||i.enumerable});return a};var tt=a=>Z(V({},"__esModule",{value:!0}),a);var o=(a,t,e)=>new Promise((i,s)=>{var r=h=>{try{u(e.next(h))}catch(d){s(d)}},n=h=>{try{u(e.throw(h))}catch(d){s(d)}},u=h=>h.done?i(h.value):Promise.resolve(h.value).then(r,n);u((e=e.apply(a,t)).next())});var L=Y((ft,et)=>{et.exports={version:"1.14.3-alpha.9",license:"MIT",name:"@100mslive/hms-virtual-background",author:"100ms",module:"dist/esm/index.js",main:"dist/cjs/index.js",typings:"dist/index.d.ts",typesVersions:{"*":{hmsvbplugin:["./dist/HMSVBPlugin.d.ts"],hmseffectsplugin:["./dist/HMSEffectsPlugin.d.ts"]}},exports:{".":{import:"./dist/esm/index.js",require:"./dist/cjs/index.js",default:"./dist/esm/index.js",types:"./dist/index.d.ts"},"./hmsvbplugin":{import:"./dist/esm/HMSVBPlugin.js",require:"./dist/cjs/HMSVBPlugin.js",default:"./dist/esm/HMSVBPlugin.js",types:"./dist/HMSVBPlugin.d.ts"},"./hmseffectsplugin":{import:"./dist/esm/HMSEffectsPlugin.js",default:"./dist/esm/HMSEffectsPlugin.js",require:"./dist/cjs/HMSEffectsPlugin.js",types:"./dist/HMSEffectsPlugin.d.ts"}},repository:{type:"git",url:"https://github.com/100mslive/web-sdks.git",directory:"packages/hms-virtual-background"},files:["dist","src/tflite","src/models"],scripts:{start:'concurrently "yarn dev" "yarn types"',dev:"node ../../scripts/dev","build:only":"node ../../scripts/build",build:"yarn build:only && yarn types:build",types:"tsc -w","types:build":"tsc -p tsconfig.json",test:"jest --maxWorkers=1 --passWithNoTests",lint:"eslint -c ../../.eslintrc .","lint:fix":"yarn lint --fix",prepare:"yarn build",size:"size-limit",analyze:"size-limit --why",format:"prettier --write src/**/*.ts"},peerDependencies:{"@100mslive/hms-video-store":"0.13.3-alpha.9"},devDependencies:{"@100mslive/hms-video-store":"0.13.3-alpha.9"},dependencies:{"@mediapipe/selfie_segmentation":"^0.1.1632777926","@tensorflow-models/body-segmentation":"^1.0.1","@tensorflow/tfjs-backend-webgl":"^3.3.0","@tensorflow/tfjs-converter":"^3.19.0","@tensorflow/tfjs-core":"^3.19.0","@webassemblyjs/helper-wasm-bytecode":"1.11.1","@webassemblyjs/wasm-gen":"1.11.1","effects-sdk":"3.6.2","gifuct-js":"^2.1.2","wasm-check":"^2.0.2"},eslintIgnore:["tflite.js","tflite-simd.js","tflite.wasm","tflite-simd.wasm","defineTFLite.ts","importing.test.ts"],gitHead:"3cb258416edd3118cc49bf3db3f8f3e64776ac78"}});var pt={};X(pt,{HMSEffectsPlugin:()=>T,HMSVBPlugin:()=>w,HMSVirtualBackgroundPlugin:()=>O,HMSVirtualBackgroundTypes:()=>p});module.exports=tt(pt);var I=require("gifuct-js"),x=require("@100mslive/hms-video-store"),Mt=require("@tensorflow/tfjs-backend-webgl");var it=L(),R=`https://unpkg.com/${it.name}/src`,C="VBProcessor",st="tflite/tflite.js",at="tflite/tflite-simd.js",nt="models/selfie_segmentation_landscape.tflite",_=a=>new Promise(function(t,e){let i=document.createElement("script");i.src=a,i.onload=t,i.onerror=e,document.head.appendChild(i)}),ot=()=>o(null,null,function*(){let a,t=`${R}/${at}`;yield _(t);try{a=yield createTFLiteSIMDModule()}catch(e){console.warn("SIMD not supported. You may experience poor virtual background effect."),t=`${R}/${st}`,yield _(t),a=yield createTFLiteModule()}return a}),q=()=>o(null,null,function*(){let a=`${R}/${nt}`,[t,e]=yield Promise.all([ot(),fetch(a)]),i=yield e.arrayBuffer(),s=t._getModelBufferMemoryOffset();return t.HEAPU8.set(new Uint8Array(i),s),t._loadModel(i.byteLength),console.debug(C,"Input memory offset:",t._getInputMemoryOffset()),console.debug(C,"Input height:",t._getInputHeight()),console.debug(C,"Input width:",t._getInputWidth()),console.debug(C,"Input channels:",t._getInputChannelCount()),t});var y="VBProcessor",rt=33,ut=L(),ht=214,dt=855,gt=120,lt=720,O=class{constructor(t,e=!1){this.backgroundType="none";this.background=t,this.enableSharpening=e,this.backgroundImage=null,this.backgroundVideo=null,this.personMaskWidth=256,this.personMaskHeight=144,this.isVirtualBackground=!1,this.blurValue="10px",this.loadModelCalled=!1,this.tfLite=null,this.modelName="landscape-segmentation",this.outputCtx=null,this.input=null,this.output=null,this.timerID=0,this.imageAspectRatio=1,this.personMaskPixelCount=this.personMaskWidth*this.personMaskHeight,this.personMask=new ImageData(this.personMaskWidth,this.personMaskHeight),this.personMaskCanvas=document.createElement("canvas"),this.personMaskCanvas.width=this.personMaskWidth,this.personMaskCanvas.height=this.personMaskHeight,this.personMaskCtx=this.personMaskCanvas.getContext("2d"),this.filters={},this.gifFrames=null,this.gifFramesIndex=0,this.gifFrameImageData=null,this.tempGifCanvas=document.createElement("canvas"),this.tempGifContext=this.tempGifCanvas.getContext("2d"),this.giflocalCount=0,this.enableSharpening=e,this.log(y,"Virtual Background plugin created"),this.setBackground(this.background)}init(){return o(this,null,function*(){this.loadModelCalled?yield this.tfLitePromise:(this.log(y,"PREVIOUS LOADED MODEL IS ",this.tfLite),this.loadModelCalled=!0,this.tfLitePromise=q(),this.tfLite=yield this.tfLitePromise),this.enableSharpening&&this.initSharpenFilter()})}isSupported(){return navigator.userAgent.indexOf("Chrome")!==-1||navigator.userAgent.indexOf("Firefox")!==-1||navigator.userAgent.indexOf("Edg")!==-1||navigator.userAgent.indexOf("Edge")!==-1}checkSupport(){let t={};return["Chrome","Firefox","Edg","Edge"].some(e=>navigator.userAgent.indexOf(e)!==-1)?t.isSupported=!0:(t.isSupported=!1,t.errType=x.HMSPluginUnsupportedTypes.PLATFORM_NOT_SUPPORTED,t.errMsg="browser not supported for plugin, see docs"),t}getName(){return ut.name}getPluginType(){return x.HMSVideoPluginType.TRANSFORM}setBackground(t){return o(this,null,function*(){if(t!=="")if(t==="none")this.log(y,"setting background to :",t),this.background="none",this.backgroundType="none",this.isVirtualBackground=!1;else if(t==="blur")this.log(y,"setting background to :",t),this.background="blur",this.backgroundType="blur",this.isVirtualBackground=!1;else if(t instanceof HTMLImageElement){this.log("setting background to image",t);let e=yield this.setImage(t);if(!e||!e.complete||!e.naturalHeight)throw new Error("Invalid image. Provide a valid and successfully loaded HTMLImageElement");this.isVirtualBackground=!0,this.backgroundImage=e,this.backgroundType="image"}else if(t instanceof HTMLVideoElement)this.log("setting background to video",t),this.backgroundVideo=t,this.backgroundVideo.crossOrigin="anonymous",this.backgroundVideo.muted=!0,this.backgroundVideo.loop=!0,this.backgroundVideo.oncanplaythrough=()=>o(this,null,function*(){this.backgroundVideo!=null&&(yield this.backgroundVideo.play(),this.isVirtualBackground=!0,this.backgroundType="video")});else if(console.log("setting gif to background"),this.gifFrames=yield this.setGiF(t),this.gifFrames!=null&&this.gifFrames.length>0)this.backgroundType="gif",this.isVirtualBackground=!0;else throw new Error("Invalid background supplied, see the docs to check supported background type");else throw new Error("Invalid background supplied, see the docs to check supported background type")})}stop(){var t,e;this.isVirtualBackground&&((t=this.backgroundImage)==null||t.removeAttribute("src"),(e=this.backgroundVideo)==null||e.removeAttribute("src"),this.backgroundType==="video"&&(this.backgroundVideo.loop=!1,this.backgroundVideo=null)),this.outputCtx&&(this.outputCtx.fillStyle="rgb(0, 0, 0)",this.outputCtx.fillRect(0,0,this.output.width,this.output.height)),this.gifFrameImageData=null,this.gifFrames=null,this.giflocalCount=0,this.gifFramesIndex=0}processVideoFrame(t,e,i){if(!t||!e)throw new Error("Plugin invalid input/output");this.input=t,this.output=e;let s=e.getContext("2d");if(s.canvas.width!==t.width&&(s.canvas.width=t.width),s.canvas.height!==t.height&&(s.canvas.height=t.height),this.backgroundType==="video"&&(this.backgroundVideo.width=t.width,this.backgroundVideo.height=t.height),this.outputCtx=s,this.imageAspectRatio=t.width/t.height,this.imageAspectRatio<=0)throw new Error("Invalid input width/height");let r=()=>o(this,null,function*(){yield this.runSegmentation(i)});this.background==="none"&&!this.isVirtualBackground?(this.outputCtx.globalCompositeOperation="copy",this.outputCtx.filter="none",this.outputCtx.drawImage(t,0,0,t.width,t.height)):r()}setImage(t){return o(this,null,function*(){return t.crossOrigin="anonymous",new Promise((e,i)=>{t.onload=()=>e(t),t.onerror=i})})}setGiF(t){return fetch(t).then(e=>e.arrayBuffer()).then(e=>(0,I.parseGIF)(e)).then(e=>(0,I.decompressFrames)(e,!0))}log(t,...e){console.info(t,...e)}resizeInputData(){this.personMaskCtx.drawImage(this.input,0,0,this.input.width,this.input.height,0,0,this.personMaskWidth,this.personMaskHeight);let t=this.personMaskCtx.getImageData(0,0,this.personMaskWidth,this.personMaskHeight),e=this.tfLite._getInputMemoryOffset()/4;for(let i=0;i<this.personMaskPixelCount;i++)this.tfLite.HEAPF32[e+i*3]=t.data[i*4]/255,this.tfLite.HEAPF32[e+i*3+1]=t.data[i*4+1]/255,this.tfLite.HEAPF32[e+i*3+2]=t.data[i*4+2]/255}infer(t){t||this.tfLite._runInference();let e=this.tfLite._getOutputMemoryOffset()/4;for(let i=0;i<this.personMaskPixelCount;i++)if(this.modelName==="meet"){let s=this.tfLite.HEAPF32[e+i*2],r=this.tfLite.HEAPF32[e+i*2+1],n=Math.max(s,r),u=Math.exp(s-n),h=Math.exp(r-n);this.personMask.data[i*4+3]=255*h/(u+h)}else if(this.modelName==="landscape-segmentation"){let s=this.tfLite.HEAPF32[e+i];this.personMask.data[i*4+3]=255*s}this.personMaskCtx.putImageData(this.personMask,0,0)}postProcessing(){this.outputCtx.globalCompositeOperation="copy",this.outputCtx.filter="none",this.isVirtualBackground?this.outputCtx.filter="blur(4px)":this.outputCtx.filter="blur(8px)",this.drawPersonMask(),this.outputCtx.globalCompositeOperation="source-in",this.outputCtx.filter="none",this.outputCtx.drawImage(this.input,0,0),this.enableSharpening&&this.output.width>ht&&this.output.height>gt&&this.output.width<dt&&this.output.height<lt&&this.sharpenFilter(),this.drawSegmentedBackground()}sharpenFilter(){let t=this.outputCtx.getImageData(0,0,this.output.width,this.output.height),e=this.filters.convolute(t);this.outputCtx.putImageData(e,0,0)}drawPersonMask(){this.outputCtx.drawImage(this.personMaskCanvas,0,0,this.personMaskWidth,this.personMaskHeight,0,0,this.output.width,this.output.height)}drawSegmentedBackground(){this.outputCtx.globalCompositeOperation="destination-over",this.outputCtx.imageSmoothingEnabled=!0,this.outputCtx.imageSmoothingQuality="high",this.isVirtualBackground?this.backgroundType==="video"&&this.backgroundVideo!=null&&this.backgroundVideo.readyState>=4?this.fitVideoToBackground():this.backgroundType==="image"?this.fitImageToBackground():this.backgroundType==="gif"&&(this.giflocalCount>this.gifFrames[this.gifFramesIndex].delay/rt?(this.gifFramesIndex++,this.gifFramesIndex>=this.gifFrames.length&&(this.gifFramesIndex=0),this.giflocalCount=0):this.giflocalCount++,this.fitGifToBackground()):this.addBlurToBackground()}runSegmentation(t){return o(this,null,function*(){this.tfLite&&(this.resizeInputData(),yield this.infer(t),this.postProcessing())})}fitVideoToBackground(){this.fitData(this.backgroundVideo,this.backgroundVideo.videoWidth,this.backgroundVideo.videoHeight)}fitImageToBackground(){this.fitData(this.backgroundImage,this.backgroundImage.width,this.backgroundImage.height)}fitGifToBackground(){if(this.gifFrameImageData==null){let t=this.gifFrames[this.gifFramesIndex].dims;this.tempGifCanvas.width=t.width,this.tempGifCanvas.height=t.height,this.gifFrameImageData=this.tempGifContext.createImageData(t.width,t.height)}this.gifFrameImageData.data.set(this.gifFrames[this.gifFramesIndex].patch),this.tempGifContext.putImageData(this.gifFrameImageData,0,0),this.fitData(this.tempGifCanvas,this.gifFrameImageData.width,this.gifFrameImageData.height)}fitData(t,e,i){let s,r,n,u;e/i<this.imageAspectRatio?(s=e,r=e/this.imageAspectRatio,n=0,u=(i-r)/2):(r=i,s=i*this.imageAspectRatio,u=0,n=(e-s)/2),this.outputCtx.drawImage(t,n,u,s,r,0,0,this.output.width,this.output.height)}addBlurToBackground(){return o(this,null,function*(){let t="15px";this.input.width<=160?t="5px":this.input.width<=320?t="10px":this.input.width<=640?t="15px":this.input.width<=960?t="20px":this.input.width<=1280?t="25px":this.input.width<=1920&&(t="30px"),this.outputCtx.filter=`blur(${t})`,this.outputCtx.drawImage(this.input,0,0,this.output.width,this.output.height)})}initSharpenFilter(){this.filters.tmpCanvas=document.createElement("canvas"),this.filters.tmpCtx=this.filters.tmpCanvas.getContext("2d"),this.filters.createImageData=(t,e)=>this.filters.tmpCtx.createImageData(t,e),this.filters.convolute=(t,e=[0,-1,0,-1,5,-1,0,-1,0],i)=>{let s=Math.round(Math.sqrt(e.length)),r=Math.floor(s/2),n=t.data,u=t.width,h=t.height,d=u,F=h,A=this.filters.createImageData(d,F),m=A.data,W=i?1:0;for(let g=0;g<F;g=g+1)for(let l=0;l<d;l=l+1){let c=(g*d+l)*4;if(n[c+3]!==0&&l<d&&g<F){let $=g,z=l,D=0,G=0,N=0,H=0;for(let k=0;k<s;k++)for(let b=0;b<s;b++){let P=$+k-r,B=z+b-r;if(P>=0&&P<h&&B>=0&&B<u){let v=(P*u+B)*4,M=e[k*s+b];D+=n[v]*M,G+=n[v+1]*M,N+=n[v+2]*M,H+=n[v+3]*M}}m[c]=D,m[c+1]=G,m[c+2]=N,m[c+3]=H+W*(255-H)}}return A}}};var j=require("@mediapipe/selfie_segmentation"),S=require("gifuct-js"),E=require("@100mslive/hms-video-store");var p=(n=>(n.BLUR="blur",n.NONE="none",n.GIF="gif",n.IMAGE="image",n.VIDEO="video",n.CANVAS="canvas",n))(p||{});var w=class{constructor(t,e){this.TAG="[HMSVBPlugin]";this.background="none";this.backgroundType="none";this.handleResults=t=>{if(!(!this.outputCanvas||!this.outputCtx)){switch(this.outputCtx.save(),this.outputCtx.clearRect(0,0,this.outputCanvas.width,this.outputCanvas.height),this.backgroundType){case"image":case"canvas":case"video":this.renderBackground(t,this.background);break;case"gif":this.renderGIF(t);break;case"blur":this.renderBlur(t);break}this.outputCtx.restore(),this.prevResults=t}};this.renderBackground=(t,e)=>{if(!this.input||!this.outputCanvas||!this.outputCtx||this.backgroundType==="none"||this.backgroundType==="blur")return;this.outputCtx.filter="none",this.outputCtx.imageSmoothingEnabled=!0,this.outputCtx.imageSmoothingQuality="high",this.outputCtx.globalCompositeOperation="source-out";let i=e instanceof HTMLVideoElement?e.videoWidth:e.width,s=e instanceof HTMLVideoElement?e.videoHeight:e.height;this.outputCtx.drawImage(e,0,0,i,s,0,0,this.outputCanvas.width,this.outputCanvas.height),this.outputCtx.globalCompositeOperation="destination-out",this.outputCtx.drawImage(t.segmentationMask,0,0,this.outputCanvas.width,this.outputCanvas.height),this.outputCtx.globalCompositeOperation="destination-atop",this.outputCtx.drawImage(this.input,0,0,this.outputCanvas.width,this.outputCanvas.height)};this.background=t,this.backgroundType=e,this.gifFrames=null,this.gifFramesIndex=0,this.gifFrameImageData=null,this.tempGifCanvas=document.createElement("canvas"),this.tempGifContext=this.tempGifCanvas.getContext("2d"),this.setBackground(this.background,this.backgroundType),this.log("Virtual background plugin initialised")}isSupported(){return this.checkSupport().isSupported}isBlurSupported(){return"filter"in CanvasRenderingContext2D.prototype}checkSupport(){let t={};return["Chrome","Firefox","Edg","Edge","Safari"].some(e=>navigator.userAgent.indexOf(e)!==-1)?t.isSupported=!0:(t.isSupported=!1,t.errType=E.HMSPluginUnsupportedTypes.PLATFORM_NOT_SUPPORTED,t.errMsg="browser not supported for plugin, see docs"),t}getName(){return"HMSVB"}getPluginType(){return E.HMSVideoPluginType.TRANSFORM}init(){return o(this,null,function*(){this.segmentation||(this.segmentation=new j.SelfieSegmentation({locateFile:t=>`https://cdn.jsdelivr.net/npm/@mediapipe/selfie_segmentation@0.1/${t}`}),this.segmentation.setOptions({selfieMode:!1,modelSelection:1}),this.segmentation.onResults(this.handleResults))})}setBackground(t,e){return o(this,null,function*(){if(!t)throw new Error("Invalid background supplied, see the docs to check supported background type");switch(this.prevResults=void 0,e){case"none":case"blur":this.background=t,this.backgroundType=e;break;case"image":this.log("setting background to image",t);let i=yield this.setImage(t);if(!i||!i.complete||!i.naturalHeight)throw new Error("Invalid image. Provide a valid and successfully loaded HTMLImageElement");this.background=i,this.backgroundType="image";break;case"video":this.log("setting background to video",t),this.backgroundType="none",this.background=t,this.background.crossOrigin="anonymous",this.background.muted=!0,this.background.loop=!0,this.background.playsInline=!0,this.background.oncanplaythrough=()=>o(this,null,function*(){if(this.background&&this.background instanceof HTMLVideoElement)try{yield this.background.play(),this.backgroundType="video"}catch(s){this.log("failed to play background",t)}});break;case"canvas":this.background=t,this.backgroundType="canvas";break;case"gif":if(this.log("setting gif to background",t),this.backgroundType="none",this.background=t,this.gifFrames=yield this.loadGIF(this.background),this.gifFrames!=null&&this.gifFrames.length>0)this.backgroundType="gif";else throw new Error("Invalid background supplied, see the docs to check supported background type");break;default:this.log(`backgroundType did not match with any of the supported background types - ${p}`)}})}getBackground(){return this.background}stop(){var t;this.backgroundType!=="blur"&&this.background!=="none"&&((t=this.segmentation)==null||t.reset()),this.gifFrameImageData=null,this.gifFrames=null,this.gifFramesIndex=0,this.background="none",this.backgroundType="none"}processVideoFrame(t,e,i){return o(this,null,function*(){var s;if(!t||!e)throw new Error("Plugin invalid input/output");if(this.input=t,e.width=t.width,e.height=t.height,this.outputCanvas=e,this.outputCtx=e.getContext("2d"),i&&this.prevResults){this.handleResults(this.prevResults);return}if(this.backgroundType==="none"){(s=this.outputCtx)==null||s.drawImage(t,0,0,t.width,t.height);return}yield this.segmentation.send({image:t})})}setImage(t){return o(this,null,function*(){return t.crossOrigin="anonymous",new Promise((e,i)=>{t.onload=()=>e(t),t.onerror=i})})}loadGIF(t){return fetch(t).then(e=>e.arrayBuffer()).then(e=>(0,S.parseGIF)(e)).then(e=>(0,S.decompressFrames)(e,!0))}log(...t){console.debug(this.TAG,...t)}renderBlur(t){var e,i,s;!this.outputCanvas||!this.outputCtx||this.backgroundType!=="blur"||(this.outputCtx.filter="none",this.outputCtx.globalCompositeOperation="source-out",(e=this.outputCtx)==null||e.drawImage(t.image,0,0,this.outputCanvas.width,this.outputCanvas.height),this.outputCtx.globalCompositeOperation="destination-atop",(i=this.outputCtx)==null||i.drawImage(t.segmentationMask,0,0,this.outputCanvas.width,this.outputCanvas.height),this.outputCtx.filter=`blur(${Math.floor(this.outputCanvas.width/160)*5}px)`,(s=this.outputCtx)==null||s.drawImage(t.image,0,0,this.outputCanvas.width,this.outputCanvas.height))}renderGIF(t){if(!(!this.outputCanvas||!this.outputCtx||!this.tempGifContext||this.backgroundType!=="gif")){if(this.gifFrameImageData==null){let e=this.gifFrames[this.gifFramesIndex].dims;this.tempGifCanvas.width=e.width,this.tempGifCanvas.height=e.height,this.gifFrameImageData=this.tempGifContext.createImageData(e.width,e.height)}this.gifFrameImageData.data.set(this.gifFrames[this.gifFramesIndex].patch),this.tempGifContext.putImageData(this.gifFrameImageData,0,0),this.gifFramesIndex=(this.gifFramesIndex+1)%this.gifFrames.length,this.renderBackground(t,this.tempGifCanvas)}}};var U=require("effects-sdk");var f="https://static.100ms.live/effectsdk/3.6.2/";var T=class{constructor(t,e){this.blurAmount=0;this.backgroundType="none";this.preset="balanced";this.TAG="[HMSEffectsPlugin]";this.operationQueue=Promise.resolve();this.effectRequestId=0;this.effects=new U.tsvb(t),this.onInit=e,this.initPromise=new Promise(i=>{this.resolveInit=i}),this.effects.config({sdk_url:f,models:{colorcorrector:"",facedetector:"",lowlighter:""},test_inference:!0,wasmPaths:{"ort-wasm.wasm":`${f}ort-wasm.wasm`,"ort-wasm-simd.wasm":`${f}ort-wasm-simd.wasm`,"ort-wasm-simd.jsep.wasm":`${f}ort-wasm-simd.jsep.wasm`}}),this.effects.onError(i=>{i.type==="error"&&i.message&&console.error(this.TAG,"Effects SDK error:",i.message)}),this.effects.cache(),this.effects.onReady=()=>{var i;this.effects&&(this.resolveInit(),(i=this.onInit)==null||i.call(this),this.effects.setBackgroundFitMode("fill"),this.effects.setSegmentationPreset(this.preset))}}getName(){return"HMSEffects"}isSupported(){return this.effects.isSupported()}enqueueOperation(t){return this.operationQueue=this.operationQueue.then(()=>this.initPromise).then(()=>t()).catch(e=>{console.error(this.TAG,"Operation failed:",e)}),this.operationQueue}removeBlur(){this.blurAmount=0,this.backgroundType==="blur"&&(this.backgroundType="none");let t=++this.effectRequestId;this.enqueueOperation(()=>{t===this.effectRequestId&&this.effects.clearBlur()})}removeBackground(){this.background="",this.backgroundType==="image"&&(this.backgroundType="none");let t=++this.effectRequestId;this.enqueueOperation(()=>{t===this.effectRequestId&&this.effects.clearBackground()})}setBlur(t){if(t<0||t>1)throw new Error("Blur amount should be between 0 and 1");this.blurAmount=t,this.background="",this.backgroundType="blur";let e=++this.effectRequestId;this.enqueueOperation(()=>{e===this.effectRequestId&&(this.effects.clearBackground(),this.effects.setBlur(this.blurAmount),this.effects.run())})}setPreset(t){return o(this,null,function*(){return this.preset=t,new Promise((e,i)=>{this.enqueueOperation(()=>{this.effects.setSegmentationPreset(this.preset).then(e).catch(i)})})})}onResolutionChange(t){this.onResolutionChangeCallback=t}getPreset(){return this.preset}removeEffects(){this.backgroundType="none",this.background="",this.blurAmount=0;let t=++this.effectRequestId;this.enqueueOperation(()=>{t===this.effectRequestId&&(this.effects.clearBackground(),this.effects.clearBlur(),this.effects.stop())})}setBackground(t){if(!t)throw new Error("Background url cannot be empty");this.background=t,this.blurAmount=0,this.backgroundType="image";let e=++this.effectRequestId;this.enqueueOperation(()=>{e===this.effectRequestId&&(this.effects.clearBlur(),this.effects.setBackground(this.background),this.effects.run())})}getBlurAmount(){return this.blurAmount}getBackground(){return this.background||this.backgroundType}getMetrics(){var t,e;return(e=(t=this.effects).getMetrics)==null?void 0:e.call(t)}apply(t){return this.effects.clear(),this.applyEffect(),this.effects.onChangeInputResolution(()=>{var i;let e=this.effects.getStream();if(e){let{height:s,width:r}=e.getVideoTracks()[0].getSettings();(i=this.onResolutionChangeCallback)==null||i.call(this,r,s)}}),this.effects.useStream(t),this.effects.getStream()||t}stop(){this.removeEffects()}applyEffect(){this.blurAmount?this.setBlur(this.blurAmount):this.background&&this.setBackground(this.background)}};
2
2
  //# sourceMappingURL=index.js.map