@livekit/track-processors 0.1.0 → 0.1.2

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.
Files changed (55) hide show
  1. package/dist/ProcessorPipeline.d.ts +8 -7
  2. package/dist/ProcessorPipeline.js +6 -4
  3. package/dist/ProcessorPipeline.js.map +1 -1
  4. package/dist/index.d.ts +1 -1
  5. package/dist/index.js +4 -4
  6. package/dist/index.js.map +1 -1
  7. package/dist/package.json +56 -0
  8. package/dist/src/ProcessorPipeline.d.ts +19 -0
  9. package/dist/src/ProcessorPipeline.js +41 -0
  10. package/dist/src/ProcessorPipeline.js.map +1 -0
  11. package/dist/src/index.d.ts +4 -0
  12. package/dist/src/index.js +28 -0
  13. package/dist/src/index.js.map +1 -0
  14. package/dist/src/transformers/BackgroundTransformer.d.ts +23 -0
  15. package/dist/src/transformers/BackgroundTransformer.js +142 -0
  16. package/dist/src/transformers/BackgroundTransformer.js.map +1 -0
  17. package/dist/src/transformers/DummyTransformer.d.ts +6 -0
  18. package/dist/src/transformers/DummyTransformer.js +10 -0
  19. package/dist/src/transformers/DummyTransformer.js.map +1 -0
  20. package/dist/src/transformers/MediaPipeHolisticTrackerTransformer.d.ts +18 -0
  21. package/dist/src/transformers/MediaPipeHolisticTrackerTransformer.js +44 -0
  22. package/dist/src/transformers/MediaPipeHolisticTrackerTransformer.js.map +1 -0
  23. package/dist/src/transformers/VideoTransformer.d.ts +12 -0
  24. package/dist/src/transformers/VideoTransformer.js +26 -0
  25. package/dist/src/transformers/VideoTransformer.js.map +1 -0
  26. package/dist/src/transformers/index.d.ts +2 -0
  27. package/dist/src/transformers/index.js +3 -0
  28. package/dist/src/transformers/index.js.map +1 -0
  29. package/dist/src/transformers/types.d.ts +14 -0
  30. package/dist/src/transformers/types.js +2 -0
  31. package/dist/src/transformers/types.js.map +1 -0
  32. package/dist/src/utils.d.ts +2 -0
  33. package/dist/src/utils.js +3 -0
  34. package/dist/src/utils.js.map +1 -0
  35. package/dist/transformers/BackgroundTransformer.d.ts +3 -3
  36. package/dist/transformers/BackgroundTransformer.js +26 -22
  37. package/dist/transformers/BackgroundTransformer.js.map +1 -1
  38. package/dist/transformers/MediaPipeHolisticTrackerTransformer.d.ts +2 -2
  39. package/dist/transformers/MediaPipeHolisticTrackerTransformer.js +2 -2
  40. package/dist/transformers/MediaPipeHolisticTrackerTransformer.js.map +1 -1
  41. package/dist/transformers/VideoTransformer.d.ts +3 -3
  42. package/dist/transformers/VideoTransformer.js +4 -1
  43. package/dist/transformers/VideoTransformer.js.map +1 -1
  44. package/dist/transformers/types.d.ts +8 -5
  45. package/package.json +3 -3
  46. package/src/transformers/BackgroundTransformer.ts +2 -3
  47. package/dist/BackgroundProcessor.d.ts +0 -23
  48. package/dist/BackgroundProcessor.js +0 -114
  49. package/dist/BackgroundProcessor.js.map +0 -1
  50. package/dist/BaseVideoProcessor.d.ts +0 -28
  51. package/dist/BaseVideoProcessor.js +0 -110
  52. package/dist/BaseVideoProcessor.js.map +0 -1
  53. package/dist/transformers/Untitled-1.d.ts +0 -1
  54. package/dist/transformers/Untitled-1.js +0 -219
  55. package/dist/transformers/Untitled-1.js.map +0 -1
@@ -1,18 +1,19 @@
1
1
  /// <reference types="dom-mediacapture-transform" />
2
2
  /// <reference types="dom-webcodecs" />
3
- import type { ProcessorOptions, VideoProcessor } from 'livekit-client';
4
- import { StreamTransformer } from './transformers';
5
- export default class ProcessorPipeline implements VideoProcessor<ProcessorOptions> {
3
+ import type { ProcessorOptions, Track, TrackProcessor } from 'livekit-client';
4
+ import { VideoTrackTransformer } from './transformers';
5
+ export default class ProcessorPipeline implements TrackProcessor<Track.Kind> {
6
6
  static get isSupported(): boolean;
7
+ name: string;
7
8
  source?: MediaStreamVideoTrack;
8
9
  sourceSettings?: MediaTrackSettings;
9
10
  processor?: MediaStreamTrackProcessor<VideoFrame>;
10
11
  trackGenerator?: MediaStreamTrackGenerator<VideoFrame>;
11
12
  canvas?: OffscreenCanvas;
12
- sourceDummy?: HTMLVideoElement;
13
+ sourceDummy?: HTMLMediaElement;
13
14
  processedTrack?: MediaStreamTrack;
14
- transformers: Array<StreamTransformer>;
15
- constructor(transformers: Array<StreamTransformer>);
16
- init(opts: ProcessorOptions): Promise<void>;
15
+ transformers: Array<VideoTrackTransformer>;
16
+ constructor(transformers: Array<VideoTrackTransformer>, name: string);
17
+ init(opts: ProcessorOptions<Track.Kind>): Promise<void>;
17
18
  destroy(): Promise<void>;
18
19
  }
@@ -3,7 +3,8 @@ export default class ProcessorPipeline {
3
3
  return (typeof MediaStreamTrackGenerator !== 'undefined' &&
4
4
  typeof MediaStreamTrackProcessor !== 'undefined');
5
5
  }
6
- constructor(transformers) {
6
+ constructor(transformers, name) {
7
+ this.name = name;
7
8
  this.transformers = transformers;
8
9
  }
9
10
  async init(opts) {
@@ -11,6 +12,9 @@ export default class ProcessorPipeline {
11
12
  this.source = opts.track;
12
13
  this.sourceSettings = this.source.getSettings();
13
14
  this.sourceDummy = opts.element;
15
+ if (!(this.sourceDummy instanceof HTMLVideoElement)) {
16
+ throw TypeError('Currently only video transformers are supported');
17
+ }
14
18
  // TODO explore if we can do all the processing work in a webworker
15
19
  this.processor = new MediaStreamTrackProcessor({ track: this.source });
16
20
  this.trackGenerator = new MediaStreamTrackGenerator({ kind: 'video' });
@@ -19,14 +23,12 @@ export default class ProcessorPipeline {
19
23
  for (const transformer of this.transformers) {
20
24
  transformer.init({
21
25
  outputCanvas: this.canvas,
22
- inputVideo: this.sourceDummy,
26
+ inputElement: this.sourceDummy,
23
27
  });
24
28
  readableStream = readableStream.pipeThrough(transformer.transformer);
25
29
  }
26
- console.log('before pipe to');
27
30
  readableStream.pipeTo(this.trackGenerator.writable);
28
31
  this.processedTrack = this.trackGenerator;
29
- console.log('processed internal', this.source, this.processedTrack, this.processor, this.trackGenerator);
30
32
  }
31
33
  async destroy() {
32
34
  var _a;
@@ -1 +1 @@
1
- {"version":3,"file":"ProcessorPipeline.js","sourceRoot":"","sources":["../src/ProcessorPipeline.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,OAAO,OAAO,iBAAiB;IACpC,MAAM,KAAK,WAAW;QACpB,OAAO,CACL,OAAO,yBAAyB,KAAK,WAAW;YAChD,OAAO,yBAAyB,KAAK,WAAW,CACjD,CAAC;IACJ,CAAC;IAkBD,YAAY,YAAsC;QAChD,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAsB;;QAC/B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAA8B,CAAC;QAClD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QAChD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC;QAChC,mEAAmE;QACnE,IAAI,CAAC,SAAS,GAAG,IAAI,yBAAyB,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QACvE,IAAI,CAAC,cAAc,GAAG,IAAI,yBAAyB,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QAEvE,IAAI,CAAC,MAAM,GAAG,IAAI,eAAe,CAC/B,MAAA,IAAI,CAAC,cAAc,CAAC,KAAK,mCAAI,GAAG,EAChC,MAAA,IAAI,CAAC,cAAc,CAAC,MAAM,mCAAI,GAAG,CAClC,CAAC;QAEF,IAAI,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;QAC7C,KAAK,MAAM,WAAW,IAAI,IAAI,CAAC,YAAY,EAAE;YAC3C,WAAW,CAAC,IAAI,CAAC;gBACf,YAAY,EAAE,IAAI,CAAC,MAAM;gBACzB,UAAU,EAAE,IAAI,CAAC,WAAY;aAC9B,CAAC,CAAC;YACH,cAAc,GAAG,cAAc,CAAC,WAAW,CAAC,WAAY,CAAC,WAAY,CAAC,CAAC;SACxE;QACD,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAE9B,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QACpD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAuC,CAAC;QACnE,OAAO,CAAC,GAAG,CACT,oBAAoB,EACpB,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,cAAc,EACnB,IAAI,CAAC,SAAS,EACd,IAAI,CAAC,cAAc,CACpB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,OAAO;;QACX,KAAK,MAAM,WAAW,IAAI,IAAI,CAAC,YAAY,EAAE;YAC3C,MAAM,WAAW,CAAC,OAAO,EAAE,CAAC;SAC7B;QACD,MAAA,IAAI,CAAC,cAAc,0CAAE,IAAI,EAAE,CAAC;IAC9B,CAAC;CACF"}
1
+ {"version":3,"file":"ProcessorPipeline.js","sourceRoot":"","sources":["../src/ProcessorPipeline.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,OAAO,OAAO,iBAAiB;IACpC,MAAM,KAAK,WAAW;QACpB,OAAO,CACL,OAAO,yBAAyB,KAAK,WAAW;YAChD,OAAO,yBAAyB,KAAK,WAAW,CACjD,CAAC;IACJ,CAAC;IAoBD,YAAY,YAA0C,EAAE,IAAY;QAClE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAkC;;QAC3C,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAA8B,CAAC;QAClD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QAChD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC;QAChC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,YAAY,gBAAgB,CAAC,EAAE;YACnD,MAAM,SAAS,CAAC,iDAAiD,CAAC,CAAC;SACpE;QACD,mEAAmE;QACnE,IAAI,CAAC,SAAS,GAAG,IAAI,yBAAyB,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QACvE,IAAI,CAAC,cAAc,GAAG,IAAI,yBAAyB,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QAEvE,IAAI,CAAC,MAAM,GAAG,IAAI,eAAe,CAC/B,MAAA,IAAI,CAAC,cAAc,CAAC,KAAK,mCAAI,GAAG,EAChC,MAAA,IAAI,CAAC,cAAc,CAAC,MAAM,mCAAI,GAAG,CAClC,CAAC;QAEF,IAAI,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;QAC7C,KAAK,MAAM,WAAW,IAAI,IAAI,CAAC,YAAY,EAAE;YAC3C,WAAW,CAAC,IAAI,CAAC;gBACf,YAAY,EAAE,IAAI,CAAC,MAAM;gBACzB,YAAY,EAAE,IAAI,CAAC,WAAY;aAChC,CAAC,CAAC;YACH,cAAc,GAAG,cAAc,CAAC,WAAW,CAAC,WAAY,CAAC,WAAY,CAAC,CAAC;SACxE;QACD,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QACpD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAuC,CAAC;IACrE,CAAC;IAED,KAAK,CAAC,OAAO;;QACX,KAAK,MAAM,WAAW,IAAI,IAAI,CAAC,YAAY,EAAE;YAC3C,MAAM,WAAW,CAAC,OAAO,EAAE,CAAC;SAC7B;QACD,MAAA,IAAI,CAAC,cAAc,0CAAE,IAAI,EAAE,CAAC;IAC9B,CAAC;CACF"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  import ProcessorPipeline from './ProcessorPipeline';
2
- export declare const BlurBackground: (blurRadius?: number) => ProcessorPipeline;
2
+ export declare const BackgroundBlur: (blurRadius?: number) => ProcessorPipeline;
3
3
  export declare const VirtualBackground: (imagePath: string) => ProcessorPipeline;
4
4
  export declare const Dummy: () => ProcessorPipeline;
package/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import ProcessorPipeline from './ProcessorPipeline';
2
2
  import BackgroundTransformer from './transformers/BackgroundTransformer';
3
3
  import DummyTransformer from './transformers/DummyTransformer';
4
- export const BlurBackground = (blurRadius = 10) => {
4
+ export const BackgroundBlur = (blurRadius = 10) => {
5
5
  const isPipelineSupported = ProcessorPipeline.isSupported && BackgroundTransformer.isSupported;
6
6
  if (!isPipelineSupported) {
7
7
  throw new Error('pipeline is not supported in this browser');
8
8
  }
9
- const pipeline = new ProcessorPipeline([new BackgroundTransformer({ blurRadius })]);
9
+ const pipeline = new ProcessorPipeline([new BackgroundTransformer({ blurRadius })], 'background-blur');
10
10
  return pipeline;
11
11
  };
12
12
  export const VirtualBackground = (imagePath) => {
@@ -14,7 +14,7 @@ export const VirtualBackground = (imagePath) => {
14
14
  if (!isPipelineSupported) {
15
15
  throw new Error('pipeline is not supported in this browser');
16
16
  }
17
- const pipeline = new ProcessorPipeline([new BackgroundTransformer({ imagePath })]);
17
+ const pipeline = new ProcessorPipeline([new BackgroundTransformer({ imagePath })], 'virtual-background');
18
18
  return pipeline;
19
19
  };
20
20
  export const Dummy = () => {
@@ -22,7 +22,7 @@ export const Dummy = () => {
22
22
  if (!isPipelineSupported) {
23
23
  throw new Error('pipeline is not supported in this browser');
24
24
  }
25
- const pipeline = new ProcessorPipeline([new DummyTransformer()]);
25
+ const pipeline = new ProcessorPipeline([new DummyTransformer()], 'dummy');
26
26
  return pipeline;
27
27
  };
28
28
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,iBAAiB,MAAM,qBAAqB,CAAC;AACpD,OAAO,qBAAqB,MAAM,sCAAsC,CAAC;AACzE,OAAO,gBAAgB,MAAM,iCAAiC,CAAC;AAE/D,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,aAAqB,EAAE,EAAE,EAAE;IACxD,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,WAAW,IAAI,qBAAqB,CAAC,WAAW,CAAC;IAC/F,IAAI,CAAC,mBAAmB,EAAE;QACxB,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;KAC9D;IACD,MAAM,QAAQ,GAAG,IAAI,iBAAiB,CAAC,CAAC,IAAI,qBAAqB,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;IACpF,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,SAAiB,EAAE,EAAE;IACrD,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,WAAW,IAAI,qBAAqB,CAAC,WAAW,CAAC;IAC/F,IAAI,CAAC,mBAAmB,EAAE;QACxB,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;KAC9D;IACD,MAAM,QAAQ,GAAG,IAAI,iBAAiB,CAAC,CAAC,IAAI,qBAAqB,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC;IACnF,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,KAAK,GAAG,GAAG,EAAE;IACxB,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,WAAW,IAAI,qBAAqB,CAAC,WAAW,CAAC;IAC/F,IAAI,CAAC,mBAAmB,EAAE;QACxB,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;KAC9D;IACD,MAAM,QAAQ,GAAG,IAAI,iBAAiB,CAAC,CAAC,IAAI,gBAAgB,EAAE,CAAC,CAAC,CAAC;IACjE,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,iBAAiB,MAAM,qBAAqB,CAAC;AACpD,OAAO,qBAAqB,MAAM,sCAAsC,CAAC;AACzE,OAAO,gBAAgB,MAAM,iCAAiC,CAAC;AAE/D,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,aAAqB,EAAE,EAAE,EAAE;IACxD,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,WAAW,IAAI,qBAAqB,CAAC,WAAW,CAAC;IAC/F,IAAI,CAAC,mBAAmB,EAAE;QACxB,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;KAC9D;IACD,MAAM,QAAQ,GAAG,IAAI,iBAAiB,CACpC,CAAC,IAAI,qBAAqB,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,EAC3C,iBAAiB,CAClB,CAAC;IACF,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,SAAiB,EAAE,EAAE;IACrD,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,WAAW,IAAI,qBAAqB,CAAC,WAAW,CAAC;IAC/F,IAAI,CAAC,mBAAmB,EAAE;QACxB,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;KAC9D;IACD,MAAM,QAAQ,GAAG,IAAI,iBAAiB,CACpC,CAAC,IAAI,qBAAqB,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,EAC1C,oBAAoB,CACrB,CAAC;IACF,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,KAAK,GAAG,GAAG,EAAE;IACxB,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,WAAW,IAAI,qBAAqB,CAAC,WAAW,CAAC;IAC/F,IAAI,CAAC,mBAAmB,EAAE;QACxB,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;KAC9D;IACD,MAAM,QAAQ,GAAG,IAAI,iBAAiB,CAAC,CAAC,IAAI,gBAAgB,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;IAC1E,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC"}
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@livekit/track-processors",
3
+ "version": "0.1.2",
4
+ "description": "LiveKit track processors",
5
+ "main": "dist/index.js",
6
+ "source": "src/index.ts",
7
+ "types": "dist/index.d.ts",
8
+ "repository": "git@github.com:livekit/livekit-track-processors.git",
9
+ "author": "Lukas Seiler",
10
+ "license": "Apache-2.0",
11
+ "scripts": {
12
+ "build": "yarn exec tsc",
13
+ "build-docs": "yarn exec typedoc",
14
+ "build-sample": "cd example && webpack && cp styles.css index.html dist/",
15
+ "lint": "eslint src",
16
+ "test": "jest",
17
+ "sample": "vite serve example --port 8080 --open"
18
+ },
19
+ "files": [
20
+ "dist",
21
+ "src"
22
+ ],
23
+ "dependencies": {
24
+ "@mediapipe/holistic": "0.5.1675471629",
25
+ "@mediapipe/tasks-vision": "0.10.1"
26
+ },
27
+ "peerDependencies": {
28
+ "livekit-client": "^1.10.0"
29
+ },
30
+ "devDependencies": {
31
+ "@trivago/prettier-plugin-sort-imports": "^4.1.1",
32
+ "@types/dom-mediacapture-transform": "^0.1.5",
33
+ "@types/jest": "^27.0.3",
34
+ "@types/offscreencanvas": "^2019.7.0",
35
+ "@typescript-eslint/eslint-plugin": "^4.31.2",
36
+ "@webpack-cli/serve": "^1.5.2",
37
+ "eslint": "8.39.0",
38
+ "eslint-config-airbnb-typescript": "17.0.0",
39
+ "eslint-config-prettier": "8.8.0",
40
+ "eslint-plugin-ecmascript-compat": "^3.0.0",
41
+ "eslint-plugin-import": "2.27.5",
42
+ "jest": "^27.4.3",
43
+ "livekit-client": "^0.16.6",
44
+ "prettier": "^2.8.8",
45
+ "ts-jest": "^27.0.7",
46
+ "ts-loader": "^8.1.0",
47
+ "ts-proto": "^1.85.0",
48
+ "typedoc": "^0.20.35",
49
+ "typedoc-plugin-no-inherit": "1.3.0",
50
+ "typescript": "^5.0.4",
51
+ "vite": "^4.3.8",
52
+ "webpack": "^5.53.0",
53
+ "webpack-cli": "^4.8.0",
54
+ "webpack-dev-server": "^4.2.1"
55
+ }
56
+ }
@@ -0,0 +1,19 @@
1
+ /// <reference types="dom-mediacapture-transform" />
2
+ /// <reference types="dom-webcodecs" />
3
+ import type { ProcessorOptions, Track, TrackProcessor } from 'livekit-client';
4
+ import { VideoTrackTransformer } from './transformers';
5
+ export default class ProcessorPipeline implements TrackProcessor<Track.Kind> {
6
+ static get isSupported(): boolean;
7
+ name: string;
8
+ source?: MediaStreamVideoTrack;
9
+ sourceSettings?: MediaTrackSettings;
10
+ processor?: MediaStreamTrackProcessor<VideoFrame>;
11
+ trackGenerator?: MediaStreamTrackGenerator<VideoFrame>;
12
+ canvas?: OffscreenCanvas;
13
+ sourceDummy?: HTMLMediaElement;
14
+ processedTrack?: MediaStreamTrack;
15
+ transformers: Array<VideoTrackTransformer>;
16
+ constructor(transformers: Array<VideoTrackTransformer>, name: string);
17
+ init(opts: ProcessorOptions<Track.Kind>): Promise<void>;
18
+ destroy(): Promise<void>;
19
+ }
@@ -0,0 +1,41 @@
1
+ export default class ProcessorPipeline {
2
+ static get isSupported() {
3
+ return (typeof MediaStreamTrackGenerator !== 'undefined' &&
4
+ typeof MediaStreamTrackProcessor !== 'undefined');
5
+ }
6
+ constructor(transformers, name) {
7
+ this.name = name;
8
+ this.transformers = transformers;
9
+ }
10
+ async init(opts) {
11
+ var _a, _b;
12
+ this.source = opts.track;
13
+ this.sourceSettings = this.source.getSettings();
14
+ this.sourceDummy = opts.element;
15
+ if (!(this.sourceDummy instanceof HTMLVideoElement)) {
16
+ throw TypeError('Currently only video transformers are supported');
17
+ }
18
+ // TODO explore if we can do all the processing work in a webworker
19
+ this.processor = new MediaStreamTrackProcessor({ track: this.source });
20
+ this.trackGenerator = new MediaStreamTrackGenerator({ kind: 'video' });
21
+ this.canvas = new OffscreenCanvas((_a = this.sourceSettings.width) !== null && _a !== void 0 ? _a : 300, (_b = this.sourceSettings.height) !== null && _b !== void 0 ? _b : 300);
22
+ let readableStream = this.processor.readable;
23
+ for (const transformer of this.transformers) {
24
+ transformer.init({
25
+ outputCanvas: this.canvas,
26
+ inputElement: this.sourceDummy,
27
+ });
28
+ readableStream = readableStream.pipeThrough(transformer.transformer);
29
+ }
30
+ readableStream.pipeTo(this.trackGenerator.writable);
31
+ this.processedTrack = this.trackGenerator;
32
+ }
33
+ async destroy() {
34
+ var _a;
35
+ for (const transformer of this.transformers) {
36
+ await transformer.destroy();
37
+ }
38
+ (_a = this.trackGenerator) === null || _a === void 0 ? void 0 : _a.stop();
39
+ }
40
+ }
41
+ //# sourceMappingURL=ProcessorPipeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProcessorPipeline.js","sourceRoot":"","sources":["../../src/ProcessorPipeline.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,OAAO,OAAO,iBAAiB;IACpC,MAAM,KAAK,WAAW;QACpB,OAAO,CACL,OAAO,yBAAyB,KAAK,WAAW;YAChD,OAAO,yBAAyB,KAAK,WAAW,CACjD,CAAC;IACJ,CAAC;IAoBD,YAAY,YAA0C,EAAE,IAAY;QAClE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAkC;;QAC3C,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAA8B,CAAC;QAClD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QAChD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC;QAChC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,YAAY,gBAAgB,CAAC,EAAE;YACnD,MAAM,SAAS,CAAC,iDAAiD,CAAC,CAAC;SACpE;QACD,mEAAmE;QACnE,IAAI,CAAC,SAAS,GAAG,IAAI,yBAAyB,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QACvE,IAAI,CAAC,cAAc,GAAG,IAAI,yBAAyB,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QAEvE,IAAI,CAAC,MAAM,GAAG,IAAI,eAAe,CAC/B,MAAA,IAAI,CAAC,cAAc,CAAC,KAAK,mCAAI,GAAG,EAChC,MAAA,IAAI,CAAC,cAAc,CAAC,MAAM,mCAAI,GAAG,CAClC,CAAC;QAEF,IAAI,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;QAC7C,KAAK,MAAM,WAAW,IAAI,IAAI,CAAC,YAAY,EAAE;YAC3C,WAAW,CAAC,IAAI,CAAC;gBACf,YAAY,EAAE,IAAI,CAAC,MAAM;gBACzB,YAAY,EAAE,IAAI,CAAC,WAAY;aAChC,CAAC,CAAC;YACH,cAAc,GAAG,cAAc,CAAC,WAAW,CAAC,WAAY,CAAC,WAAY,CAAC,CAAC;SACxE;QACD,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QACpD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAuC,CAAC;IACrE,CAAC;IAED,KAAK,CAAC,OAAO;;QACX,KAAK,MAAM,WAAW,IAAI,IAAI,CAAC,YAAY,EAAE;YAC3C,MAAM,WAAW,CAAC,OAAO,EAAE,CAAC;SAC7B;QACD,MAAA,IAAI,CAAC,cAAc,0CAAE,IAAI,EAAE,CAAC;IAC9B,CAAC;CACF"}
@@ -0,0 +1,4 @@
1
+ import ProcessorPipeline from './ProcessorPipeline';
2
+ export declare const BackgroundBlur: (blurRadius?: number) => ProcessorPipeline;
3
+ export declare const VirtualBackground: (imagePath: string) => ProcessorPipeline;
4
+ export declare const Dummy: () => ProcessorPipeline;
@@ -0,0 +1,28 @@
1
+ import ProcessorPipeline from './ProcessorPipeline';
2
+ import BackgroundTransformer from './transformers/BackgroundTransformer';
3
+ import DummyTransformer from './transformers/DummyTransformer';
4
+ export const BackgroundBlur = (blurRadius = 10) => {
5
+ const isPipelineSupported = ProcessorPipeline.isSupported && BackgroundTransformer.isSupported;
6
+ if (!isPipelineSupported) {
7
+ throw new Error('pipeline is not supported in this browser');
8
+ }
9
+ const pipeline = new ProcessorPipeline([new BackgroundTransformer({ blurRadius })], 'background-blur');
10
+ return pipeline;
11
+ };
12
+ export const VirtualBackground = (imagePath) => {
13
+ const isPipelineSupported = ProcessorPipeline.isSupported && BackgroundTransformer.isSupported;
14
+ if (!isPipelineSupported) {
15
+ throw new Error('pipeline is not supported in this browser');
16
+ }
17
+ const pipeline = new ProcessorPipeline([new BackgroundTransformer({ imagePath })], 'virtual-background');
18
+ return pipeline;
19
+ };
20
+ export const Dummy = () => {
21
+ const isPipelineSupported = ProcessorPipeline.isSupported && BackgroundTransformer.isSupported;
22
+ if (!isPipelineSupported) {
23
+ throw new Error('pipeline is not supported in this browser');
24
+ }
25
+ const pipeline = new ProcessorPipeline([new DummyTransformer()], 'dummy');
26
+ return pipeline;
27
+ };
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,iBAAiB,MAAM,qBAAqB,CAAC;AACpD,OAAO,qBAAqB,MAAM,sCAAsC,CAAC;AACzE,OAAO,gBAAgB,MAAM,iCAAiC,CAAC;AAE/D,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,aAAqB,EAAE,EAAE,EAAE;IACxD,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,WAAW,IAAI,qBAAqB,CAAC,WAAW,CAAC;IAC/F,IAAI,CAAC,mBAAmB,EAAE;QACxB,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;KAC9D;IACD,MAAM,QAAQ,GAAG,IAAI,iBAAiB,CACpC,CAAC,IAAI,qBAAqB,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,EAC3C,iBAAiB,CAClB,CAAC;IACF,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,SAAiB,EAAE,EAAE;IACrD,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,WAAW,IAAI,qBAAqB,CAAC,WAAW,CAAC;IAC/F,IAAI,CAAC,mBAAmB,EAAE;QACxB,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;KAC9D;IACD,MAAM,QAAQ,GAAG,IAAI,iBAAiB,CACpC,CAAC,IAAI,qBAAqB,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,EAC1C,oBAAoB,CACrB,CAAC;IACF,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,KAAK,GAAG,GAAG,EAAE;IACxB,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,WAAW,IAAI,qBAAqB,CAAC,WAAW,CAAC;IAC/F,IAAI,CAAC,mBAAmB,EAAE;QACxB,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;KAC9D;IACD,MAAM,QAAQ,GAAG,IAAI,iBAAiB,CAAC,CAAC,IAAI,gBAAgB,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;IAC1E,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC"}
@@ -0,0 +1,23 @@
1
+ /// <reference types="dom-webcodecs" />
2
+ import * as vision from '@mediapipe/tasks-vision';
3
+ import VideoTransformer from './VideoTransformer';
4
+ import { VideoTransformerInitOptions } from './types';
5
+ export type BackgroundOptions = {
6
+ blurRadius?: number;
7
+ imagePath?: string;
8
+ };
9
+ export default class BackgroundProcessor extends VideoTransformer {
10
+ static get isSupported(): boolean;
11
+ imageSegmenter?: vision.ImageSegmenter;
12
+ segmentationResults: vision.ImageSegmenterResult | undefined;
13
+ backgroundImage: ImageBitmap | null;
14
+ blurRadius?: number;
15
+ constructor(opts: BackgroundOptions);
16
+ init({ outputCanvas, inputElement: inputVideo }: VideoTransformerInitOptions): Promise<void>;
17
+ destroy(): Promise<void>;
18
+ sendFramesContinuouslyForSegmentation(videoEl: HTMLVideoElement): Promise<void>;
19
+ loadBackground(path: string): Promise<void>;
20
+ transform(frame: VideoFrame, controller: TransformStreamDefaultController<VideoFrame>): Promise<void>;
21
+ drawVirtualBackground(frame: VideoFrame): Promise<void>;
22
+ blurBackground(frame: VideoFrame): Promise<void>;
23
+ }
@@ -0,0 +1,142 @@
1
+ import * as vision from '@mediapipe/tasks-vision';
2
+ import { dependencies } from '../../package.json';
3
+ import VideoTransformer from './VideoTransformer';
4
+ export default class BackgroundProcessor extends VideoTransformer {
5
+ static get isSupported() {
6
+ return typeof OffscreenCanvas !== 'undefined';
7
+ }
8
+ constructor(opts) {
9
+ super();
10
+ this.backgroundImage = null;
11
+ if (opts.blurRadius) {
12
+ this.blurRadius = opts.blurRadius;
13
+ }
14
+ else if (opts.imagePath) {
15
+ this.loadBackground(opts.imagePath);
16
+ }
17
+ }
18
+ async init({ outputCanvas, inputElement: inputVideo }) {
19
+ super.init({ outputCanvas, inputElement: inputVideo });
20
+ const fileSet = await vision.FilesetResolver.forVisionTasks(`https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@${dependencies['@mediapipe/tasks-vision']}/wasm`);
21
+ this.imageSegmenter = await vision.ImageSegmenter.createFromOptions(fileSet, {
22
+ baseOptions: {
23
+ modelAssetPath: 'https://storage.googleapis.com/mediapipe-models/image_segmenter/selfie_segmenter/float16/latest/selfie_segmenter.tflite',
24
+ delegate: 'CPU',
25
+ },
26
+ runningMode: 'VIDEO',
27
+ outputCategoryMask: true,
28
+ outputConfidenceMasks: false,
29
+ });
30
+ // this.loadBackground(opts.backgroundUrl).catch((e) => console.error(e));
31
+ this.sendFramesContinuouslyForSegmentation(this.inputVideo);
32
+ }
33
+ async destroy() {
34
+ var _a;
35
+ await super.destroy();
36
+ await ((_a = this.imageSegmenter) === null || _a === void 0 ? void 0 : _a.close());
37
+ this.backgroundImage = null;
38
+ }
39
+ async sendFramesContinuouslyForSegmentation(videoEl) {
40
+ var _a;
41
+ if (!this.isDisabled) {
42
+ if (videoEl.videoWidth > 0 && videoEl.videoHeight > 0) {
43
+ let startTimeMs = performance.now();
44
+ (_a = this.imageSegmenter) === null || _a === void 0 ? void 0 : _a.segmentForVideo(videoEl, startTimeMs, (result) => (this.segmentationResults = result));
45
+ }
46
+ videoEl.requestVideoFrameCallback(() => {
47
+ this.sendFramesContinuouslyForSegmentation(videoEl);
48
+ });
49
+ }
50
+ }
51
+ async loadBackground(path) {
52
+ const img = new Image();
53
+ await new Promise((resolve, reject) => {
54
+ img.crossOrigin = 'Anonymous';
55
+ img.onload = () => resolve(img);
56
+ img.onerror = (err) => reject(err);
57
+ img.src = path;
58
+ });
59
+ const imageData = await createImageBitmap(img);
60
+ this.backgroundImage = imageData;
61
+ }
62
+ async transform(frame, controller) {
63
+ if (this.isDisabled) {
64
+ controller.enqueue(frame);
65
+ return;
66
+ }
67
+ if (!this.canvas) {
68
+ throw TypeError('Canvas needs to be initialized first');
69
+ }
70
+ if (this.blurRadius) {
71
+ await this.blurBackground(frame);
72
+ }
73
+ else {
74
+ await this.drawVirtualBackground(frame);
75
+ }
76
+ const newFrame = new VideoFrame(this.canvas, {
77
+ timestamp: frame.timestamp || Date.now(),
78
+ });
79
+ frame.close();
80
+ controller.enqueue(newFrame);
81
+ }
82
+ async drawVirtualBackground(frame) {
83
+ var _a;
84
+ if (!this.canvas || !this.ctx || !this.segmentationResults || !this.inputVideo)
85
+ return;
86
+ // this.ctx.save();
87
+ // this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
88
+ if ((_a = this.segmentationResults) === null || _a === void 0 ? void 0 : _a.categoryMask) {
89
+ this.ctx.filter = 'blur(3px)';
90
+ this.ctx.globalCompositeOperation = 'copy';
91
+ const bitmap = await maskToBitmap(this.segmentationResults.categoryMask, this.inputVideo.videoWidth, this.inputVideo.videoHeight);
92
+ this.ctx.drawImage(bitmap, 0, 0);
93
+ this.ctx.filter = 'none';
94
+ this.ctx.globalCompositeOperation = 'source-in';
95
+ if (this.backgroundImage) {
96
+ this.ctx.drawImage(this.backgroundImage, 0, 0, this.backgroundImage.width, this.backgroundImage.height, 0, 0, this.canvas.width, this.canvas.height);
97
+ }
98
+ else {
99
+ this.ctx.fillStyle = '#00FF00';
100
+ this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
101
+ }
102
+ this.ctx.globalCompositeOperation = 'destination-over';
103
+ }
104
+ this.ctx.drawImage(frame, 0, 0, this.canvas.width, this.canvas.height);
105
+ // this.ctx.restore();
106
+ }
107
+ async blurBackground(frame) {
108
+ var _a, _b;
109
+ if (!this.ctx ||
110
+ !this.canvas ||
111
+ !((_b = (_a = this.segmentationResults) === null || _a === void 0 ? void 0 : _a.categoryMask) === null || _b === void 0 ? void 0 : _b.canvas) ||
112
+ !this.inputVideo) {
113
+ return;
114
+ }
115
+ this.ctx.save();
116
+ this.ctx.globalCompositeOperation = 'copy';
117
+ const bitmap = await maskToBitmap(this.segmentationResults.categoryMask, this.inputVideo.videoWidth, this.inputVideo.videoHeight);
118
+ this.ctx.filter = 'blur(3px)';
119
+ this.ctx.globalCompositeOperation = 'copy';
120
+ this.ctx.drawImage(bitmap, 0, 0);
121
+ this.ctx.filter = 'none';
122
+ this.ctx.globalCompositeOperation = 'source-out';
123
+ this.ctx.drawImage(frame, 0, 0, this.canvas.width, this.canvas.height);
124
+ this.ctx.globalCompositeOperation = 'destination-over';
125
+ this.ctx.filter = `blur(${this.blurRadius}px)`;
126
+ this.ctx.drawImage(frame, 0, 0);
127
+ this.ctx.restore();
128
+ }
129
+ }
130
+ function maskToBitmap(mask, videoWidth, videoHeight) {
131
+ const dataArray = new Uint8ClampedArray(videoWidth * videoHeight * 4);
132
+ const result = mask.getAsUint8Array();
133
+ for (let i = 0; i < result.length; i += 1) {
134
+ dataArray[i * 4] = result[i];
135
+ dataArray[i * 4 + 1] = result[i];
136
+ dataArray[i * 4 + 2] = result[i];
137
+ dataArray[i * 4 + 3] = result[i];
138
+ }
139
+ const dataNew = new ImageData(dataArray, videoWidth, videoHeight);
140
+ return createImageBitmap(dataNew);
141
+ }
142
+ //# sourceMappingURL=BackgroundTransformer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BackgroundTransformer.js","sourceRoot":"","sources":["../../../src/transformers/BackgroundTransformer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /// <reference types="dom-webcodecs" />
2
+ import VideoTransformer from './VideoTransformer';
3
+ export default class DummyTransformer extends VideoTransformer {
4
+ transform(frame: VideoFrame, controller: TransformStreamDefaultController<VideoFrame>): Promise<void>;
5
+ destroy(): Promise<void>;
6
+ }
@@ -0,0 +1,10 @@
1
+ import VideoTransformer from './VideoTransformer';
2
+ export default class DummyTransformer extends VideoTransformer {
3
+ async transform(frame, controller) {
4
+ controller.enqueue(frame);
5
+ }
6
+ async destroy() {
7
+ // nothing to do
8
+ }
9
+ }
10
+ //# sourceMappingURL=DummyTransformer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DummyTransformer.js","sourceRoot":"","sources":["../../../src/transformers/DummyTransformer.ts"],"names":[],"mappings":"AAAA,OAAO,gBAAgB,MAAM,oBAAoB,CAAC;AAElD,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,gBAAgB;IAC5D,KAAK,CAAC,SAAS,CAAC,KAAiB,EAAE,UAAwD;QACzF,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,OAAO;QACX,gBAAgB;IAClB,CAAC;CACF"}
@@ -0,0 +1,18 @@
1
+ import { Holistic, Options, Results } from '@mediapipe/holistic';
2
+ import VideoTransformer from './VideoTransformer';
3
+ import { VideoTransformerInitOptions } from './types';
4
+ export type MediaPipeHolisticTrackerTransformerOptions = {
5
+ holisticOptions?: Options;
6
+ callback?: (results: Results) => void;
7
+ };
8
+ export default class MediaPipeHolisticTrackerTransformer extends VideoTransformer {
9
+ holistic?: Holistic;
10
+ holisticOptions: Options;
11
+ callback: (results: Results) => void;
12
+ static get isSupported(): boolean;
13
+ constructor({ holisticOptions, callback }: MediaPipeHolisticTrackerTransformerOptions);
14
+ init({ inputElement: inputVideo, outputCanvas }: VideoTransformerInitOptions): void;
15
+ destroy(): Promise<void>;
16
+ transform(): Promise<void>;
17
+ sendFramesContinuouslyForTracking(videoEl: HTMLVideoElement): Promise<void>;
18
+ }
@@ -0,0 +1,44 @@
1
+ import { Holistic } from '@mediapipe/holistic';
2
+ import VideoTransformer from './VideoTransformer';
3
+ export default class MediaPipeHolisticTrackerTransformer extends VideoTransformer {
4
+ static get isSupported() {
5
+ return true;
6
+ }
7
+ constructor({ holisticOptions, callback }) {
8
+ super();
9
+ this.callback = callback || (() => null);
10
+ this.holisticOptions = holisticOptions || {};
11
+ }
12
+ init({ inputElement: inputVideo, outputCanvas }) {
13
+ super.init({ outputCanvas, inputElement: inputVideo });
14
+ this.holistic = new Holistic({
15
+ locateFile: (file) => `https://cdn.jsdelivr.net/npm/@mediapipe/holistic/${file}`,
16
+ });
17
+ this.holistic.setOptions(this.holisticOptions);
18
+ this.holistic.onResults((r) => {
19
+ this.callback(r);
20
+ });
21
+ this.sendFramesContinuouslyForTracking(this.inputVideo);
22
+ }
23
+ async destroy() {
24
+ var _a;
25
+ this.callback = () => null;
26
+ await super.destroy();
27
+ await ((_a = this.holistic) === null || _a === void 0 ? void 0 : _a.close());
28
+ }
29
+ async transform() {
30
+ return;
31
+ }
32
+ async sendFramesContinuouslyForTracking(videoEl) {
33
+ var _a;
34
+ if (!this.isDisabled) {
35
+ if (videoEl.videoWidth > 0 && videoEl.videoHeight > 0) {
36
+ await ((_a = this.holistic) === null || _a === void 0 ? void 0 : _a.send({ image: videoEl }));
37
+ }
38
+ videoEl.requestVideoFrameCallback(() => {
39
+ this.sendFramesContinuouslyForTracking(videoEl);
40
+ });
41
+ }
42
+ }
43
+ }
44
+ //# sourceMappingURL=MediaPipeHolisticTrackerTransformer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MediaPipeHolisticTrackerTransformer.js","sourceRoot":"","sources":["../../../src/transformers/MediaPipeHolisticTrackerTransformer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAoB,MAAM,qBAAqB,CAAC;AACjE,OAAO,gBAAgB,MAAM,oBAAoB,CAAC;AAQlD,MAAM,CAAC,OAAO,OAAO,mCAAoC,SAAQ,gBAAgB;IAKxE,MAAM,KAAK,WAAW;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,YAAY,EAAE,eAAe,EAAE,QAAQ,EAA8C;QACnF,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,QAAQ,GAAG,QAAQ,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,eAAe,GAAG,eAAe,IAAI,EAAE,CAAC;IAC/C,CAAC;IAED,IAAI,CAAC,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAA+B;QAC1E,KAAK,CAAC,IAAI,CAAC,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC,CAAC;QAEvD,IAAI,CAAC,QAAQ,GAAG,IAAI,QAAQ,CAAC;YAC3B,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,oDAAoD,IAAI,EAAE;SACjF,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC/C,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE;YAC5B,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QACnB,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,iCAAiC,CAAC,IAAI,CAAC,UAAW,CAAC,CAAC;IAC3D,CAAC;IAED,KAAK,CAAC,OAAO;;QACX,IAAI,CAAC,QAAQ,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC;QAC3B,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;QACtB,MAAM,CAAA,MAAA,IAAI,CAAC,QAAQ,0CAAE,KAAK,EAAE,CAAA,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,SAAS;QACb,OAAO;IACT,CAAC;IAED,KAAK,CAAC,iCAAiC,CAAC,OAAyB;;QAC/D,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;YACpB,IAAI,OAAO,CAAC,UAAU,GAAG,CAAC,IAAI,OAAO,CAAC,WAAW,GAAG,CAAC,EAAE;gBACrD,MAAM,CAAA,MAAA,IAAI,CAAC,QAAQ,0CAAE,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAA,CAAC;aAC/C;YAED,OAAO,CAAC,yBAAyB,CAAC,GAAG,EAAE;gBACrC,IAAI,CAAC,iCAAiC,CAAC,OAAO,CAAC,CAAC;YAClD,CAAC,CAAC,CAAC;SACJ;IACH,CAAC;CACF"}
@@ -0,0 +1,12 @@
1
+ /// <reference types="dom-webcodecs" />
2
+ import { VideoTrackTransformer, VideoTransformerInitOptions } from './types';
3
+ export default abstract class VideoTransformer implements VideoTrackTransformer {
4
+ transformer?: TransformStream;
5
+ canvas?: OffscreenCanvas;
6
+ ctx?: OffscreenCanvasRenderingContext2D;
7
+ inputVideo?: HTMLVideoElement;
8
+ protected isDisabled?: Boolean;
9
+ init({ outputCanvas, inputElement: inputVideo }: VideoTransformerInitOptions): void;
10
+ destroy(): Promise<void>;
11
+ abstract transform(frame: VideoFrame, controller: TransformStreamDefaultController<VideoFrame>): void;
12
+ }
@@ -0,0 +1,26 @@
1
+ export default class VideoTransformer {
2
+ constructor() {
3
+ this.isDisabled = false;
4
+ }
5
+ init({ outputCanvas, inputElement: inputVideo }) {
6
+ var _a;
7
+ if (!(inputVideo instanceof HTMLVideoElement)) {
8
+ throw TypeError('Video transformer needs a HTMLVideoElement as input');
9
+ }
10
+ this.transformer = new TransformStream({
11
+ transform: (frame, controller) => this.transform(frame, controller),
12
+ });
13
+ this.canvas = outputCanvas || null;
14
+ if (outputCanvas) {
15
+ this.ctx = ((_a = this.canvas) === null || _a === void 0 ? void 0 : _a.getContext('2d', { readFrequently: true })) || undefined;
16
+ }
17
+ this.inputVideo = inputVideo;
18
+ this.isDisabled = false;
19
+ }
20
+ async destroy() {
21
+ this.isDisabled = true;
22
+ this.canvas = undefined;
23
+ this.ctx = undefined;
24
+ }
25
+ }
26
+ //# sourceMappingURL=VideoTransformer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VideoTransformer.js","sourceRoot":"","sources":["../../../src/transformers/VideoTransformer.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,OAAO,OAAgB,gBAAgB;IAA9C;QASY,eAAU,GAAa,KAAK,CAAC;IA2BzC,CAAC;IAzBC,IAAI,CAAC,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAA+B;;QAC1E,IAAI,CAAC,CAAC,UAAU,YAAY,gBAAgB,CAAC,EAAE;YAC7C,MAAM,SAAS,CAAC,qDAAqD,CAAC,CAAC;SACxE;QACD,IAAI,CAAC,WAAW,GAAG,IAAI,eAAe,CAAC;YACrC,SAAS,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC;SACpE,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,GAAG,YAAY,IAAI,IAAI,CAAC;QACnC,IAAI,YAAY,EAAE;YAChB,IAAI,CAAC,GAAG,GAAG,CAAA,MAAA,IAAI,CAAC,MAAM,0CAAE,UAAU,CAAC,IAAI,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,KAAI,SAAS,CAAC;SACjF;QACD,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;QACxB,IAAI,CAAC,GAAG,GAAG,SAAS,CAAC;IACvB,CAAC;CAMF"}
@@ -0,0 +1,2 @@
1
+ export * from './BackgroundTransformer';
2
+ export * from './types';
@@ -0,0 +1,3 @@
1
+ export * from './BackgroundTransformer';
2
+ export * from './types';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/transformers/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,cAAc,SAAS,CAAC"}
@@ -0,0 +1,14 @@
1
+ /// <reference types="dom-webcodecs" />
2
+ export type TrackTransformerInitOptions = {
3
+ inputElement: HTMLMediaElement;
4
+ };
5
+ export interface VideoTransformerInitOptions extends TrackTransformerInitOptions {
6
+ outputCanvas: OffscreenCanvas;
7
+ inputElement: HTMLVideoElement;
8
+ }
9
+ export interface VideoTrackTransformer<T extends TrackTransformerInitOptions = VideoTransformerInitOptions> {
10
+ init: (options: T) => void;
11
+ destroy: () => void;
12
+ transform: (frame: VideoFrame, controller: TransformStreamDefaultController) => void;
13
+ transformer?: TransformStream;
14
+ }