@livekit/track-processors 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/LICENSE +175 -0
  2. package/README.md +39 -0
  3. package/dist/BackgroundProcessor.d.ts +23 -0
  4. package/dist/BackgroundProcessor.js +114 -0
  5. package/dist/BackgroundProcessor.js.map +1 -0
  6. package/dist/BaseVideoProcessor.d.ts +28 -0
  7. package/dist/BaseVideoProcessor.js +110 -0
  8. package/dist/BaseVideoProcessor.js.map +1 -0
  9. package/dist/ProcessorPipeline.d.ts +18 -0
  10. package/dist/ProcessorPipeline.js +39 -0
  11. package/dist/ProcessorPipeline.js.map +1 -0
  12. package/dist/index.d.ts +4 -0
  13. package/dist/index.js +28 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/transformers/BackgroundTransformer.d.ts +23 -0
  16. package/dist/transformers/BackgroundTransformer.js +139 -0
  17. package/dist/transformers/BackgroundTransformer.js.map +1 -0
  18. package/dist/transformers/DummyTransformer.d.ts +6 -0
  19. package/dist/transformers/DummyTransformer.js +10 -0
  20. package/dist/transformers/DummyTransformer.js.map +1 -0
  21. package/dist/transformers/MediaPipeHolisticTrackerTransformer.d.ts +18 -0
  22. package/dist/transformers/MediaPipeHolisticTrackerTransformer.js +44 -0
  23. package/dist/transformers/MediaPipeHolisticTrackerTransformer.js.map +1 -0
  24. package/dist/transformers/Untitled-1.d.ts +1 -0
  25. package/dist/transformers/Untitled-1.js +219 -0
  26. package/dist/transformers/Untitled-1.js.map +1 -0
  27. package/dist/transformers/VideoTransformer.d.ts +12 -0
  28. package/dist/transformers/VideoTransformer.js +23 -0
  29. package/dist/transformers/VideoTransformer.js.map +1 -0
  30. package/dist/transformers/index.d.ts +2 -0
  31. package/dist/transformers/index.js +3 -0
  32. package/dist/transformers/index.js.map +1 -0
  33. package/dist/transformers/types.d.ts +11 -0
  34. package/dist/transformers/types.js +2 -0
  35. package/dist/transformers/types.js.map +1 -0
  36. package/dist/utils.d.ts +2 -0
  37. package/dist/utils.js +3 -0
  38. package/dist/utils.js.map +1 -0
  39. package/package.json +56 -0
  40. package/src/ProcessorPipeline.ts +69 -0
  41. package/src/index.ts +36 -0
  42. package/src/transformers/BackgroundTransformer.ts +195 -0
  43. package/src/transformers/DummyTransformer.ts +11 -0
  44. package/src/transformers/MediaPipeHolisticTrackerTransformer.ts +60 -0
  45. package/src/transformers/VideoTransformer.ts +39 -0
  46. package/src/transformers/index.ts +2 -0
  47. package/src/transformers/types.ts +17 -0
  48. package/src/utils.ts +2 -0
@@ -0,0 +1,139 @@
1
+ import * as vision from '@mediapipe/tasks-vision';
2
+ import VideoTransformer from './VideoTransformer';
3
+ export default class BackgroundProcessor extends VideoTransformer {
4
+ static get isSupported() {
5
+ return typeof OffscreenCanvas !== 'undefined';
6
+ }
7
+ constructor(opts) {
8
+ super();
9
+ // backgroundImagePattern: CanvasPattern | null = null;
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, inputVideo }) {
19
+ super.init({ outputCanvas, inputVideo });
20
+ const fileSet = await vision.FilesetResolver.forVisionTasks('https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.0/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
+ 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
+ drawVirtualBackground(frame) {
83
+ var _a, _b, _c;
84
+ if (!this.canvas || !this.ctx)
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 dataNew = new ImageData(Uint8ClampedArray.from(this.segmentationResults.categoryMask.getAsUint8Array()), ((_b = this.inputVideo) === null || _b === void 0 ? void 0 : _b.videoWidth) || 0, ((_c = this.inputVideo) === null || _c === void 0 ? void 0 : _c.videoHeight) || 0);
92
+ this.ctx.putImageData(dataNew, 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
+ const start = performance.now();
110
+ if (!this.ctx ||
111
+ !this.canvas ||
112
+ !((_b = (_a = this.segmentationResults) === null || _a === void 0 ? void 0 : _a.categoryMask) === null || _b === void 0 ? void 0 : _b.canvas) ||
113
+ !this.inputVideo)
114
+ return;
115
+ this.ctx.save();
116
+ this.ctx.globalCompositeOperation = 'copy';
117
+ const dataArray = new Uint8ClampedArray(this.inputVideo.videoWidth * this.inputVideo.videoHeight * 4);
118
+ const result = this.segmentationResults.categoryMask.getAsUint8Array();
119
+ for (let i = 0; i < result.length; i += 1) {
120
+ dataArray[i * 4] = result[i];
121
+ dataArray[i * 4 + 1] = result[i];
122
+ dataArray[i * 4 + 2] = result[i];
123
+ dataArray[i * 4 + 3] = result[i];
124
+ }
125
+ const dataNew = new ImageData(dataArray, this.inputVideo.videoWidth, this.inputVideo.videoHeight);
126
+ // this.ctx.filter = 'blur(3px)';
127
+ this.ctx.globalCompositeOperation = 'copy';
128
+ this.ctx.drawImage(await createImageBitmap(dataNew), 0, 0);
129
+ // this.ctx.filter = 'none';
130
+ this.ctx.globalCompositeOperation = 'source-out';
131
+ this.ctx.drawImage(frame, 0, 0, this.canvas.width, this.canvas.height);
132
+ this.ctx.globalCompositeOperation = 'destination-over';
133
+ this.ctx.filter = `blur(${this.blurRadius}px)`;
134
+ this.ctx.drawImage(frame, 0, 0);
135
+ this.ctx.restore();
136
+ console.log('draw time', performance.now() - start);
137
+ }
138
+ }
139
+ //# 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 { StreamTransformerInitOptions } 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({ inputVideo, outputCanvas }: StreamTransformerInitOptions): 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({ inputVideo, outputCanvas }) {
13
+ super.init({ outputCanvas, 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,UAAU,EAAE,YAAY,EAAgC;QAC7D,KAAK,CAAC,IAAI,CAAC,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC,CAAC;QAEzC,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 @@
1
+ export {};
@@ -0,0 +1,219 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ // Copyright 2023 The MediaPipe Authors.
11
+ // Licensed under the Apache License, Version 2.0 (the "License");
12
+ // you may not use this file except in compliance with the License.
13
+ // You may obtain a copy of the License at
14
+ // http://www.apache.org/licenses/LICENSE-2.0
15
+ // Unless required by applicable law or agreed to in writing, software
16
+ // distributed under the License is distributed on an "AS IS" BASIS,
17
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ // See the License for the specific language governing permissions and
19
+ // limitations under the License.
20
+ import vision from 'https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.0';
21
+ const { ImageSegmenter, SegmentationMask, FilesetResolver } = vision;
22
+ // Get DOM elements
23
+ const video = document.getElementById('webcam');
24
+ const canvasElement = document.getElementById('canvas');
25
+ const canvasCtx = canvasElement.getContext('2d');
26
+ const webcamPredictions = document.getElementById('webcamPredictions');
27
+ const demosSection = document.getElementById('demos');
28
+ let enableWebcamButton;
29
+ let webcamRunning = false;
30
+ const videoHeight = '360px';
31
+ const videoWidth = '480px';
32
+ let runningMode = 'IMAGE';
33
+ const resultWidthHeigth = 256;
34
+ let imageSegmenter;
35
+ let labels;
36
+ const legendColors = [
37
+ [255, 197, 0, 255],
38
+ [128, 62, 117, 255],
39
+ [255, 104, 0, 255],
40
+ [166, 189, 215, 255],
41
+ [193, 0, 32, 255],
42
+ [206, 162, 98, 255],
43
+ [129, 112, 102, 255],
44
+ [0, 125, 52, 255],
45
+ [246, 118, 142, 255],
46
+ [0, 83, 138, 255],
47
+ [255, 112, 92, 255],
48
+ [83, 55, 112, 255],
49
+ [255, 142, 0, 255],
50
+ [179, 40, 81, 255],
51
+ [244, 200, 0, 255],
52
+ [127, 24, 13, 255],
53
+ [147, 170, 0, 255],
54
+ [89, 51, 21, 255],
55
+ [241, 58, 19, 255],
56
+ [35, 44, 22, 255],
57
+ [0, 161, 194, 255], // Vivid Blue
58
+ ];
59
+ const createImageSegmenter = () => __awaiter(void 0, void 0, void 0, function* () {
60
+ const audio = yield FilesetResolver.forVisionTasks('https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.0/wasm');
61
+ imageSegmenter = yield ImageSegmenter.createFromOptions(audio, {
62
+ baseOptions: {
63
+ modelAssetPath: 'https://storage.googleapis.com/mediapipe-models/image_segmenter/deeplab_v3/float32/1/deeplab_v3.tflite',
64
+ delegate: 'GPU',
65
+ },
66
+ runningMode: runningMode,
67
+ outputCategoryMask: true,
68
+ outputConfidenceMasks: false,
69
+ });
70
+ labels = imageSegmenter.getLabels();
71
+ demosSection.classList.remove('invisible');
72
+ });
73
+ createImageSegmenter();
74
+ const imageContainers = document.getElementsByClassName('segmentOnClick');
75
+ // Add click event listeners for the img elements.
76
+ for (let i = 0; i < imageContainers.length; i++) {
77
+ imageContainers[i].getElementsByTagName('img')[0].addEventListener('click', handleClick);
78
+ }
79
+ /**
80
+ * Demo 1: Segmented images on click and display results.
81
+ */
82
+ let canvasClick;
83
+ function handleClick(event) {
84
+ return __awaiter(this, void 0, void 0, function* () {
85
+ // Do not segmented if imageSegmenter hasn't loaded
86
+ if (imageSegmenter === undefined) {
87
+ return;
88
+ }
89
+ canvasClick = event.target.parentElement.getElementsByTagName('canvas')[0];
90
+ canvasClick.classList.remove('removed');
91
+ canvasClick.width = event.target.naturalWidth;
92
+ canvasClick.height = event.target.naturalHeight;
93
+ const cxt = canvasClick.getContext('2d');
94
+ cxt.clearRect(0, 0, canvasClick.width, canvasClick.height);
95
+ cxt.drawImage(event.target, 0, 0, canvasClick.width, canvasClick.height);
96
+ event.target.style.opacity = 0;
97
+ // if VIDEO mode is initialized, set runningMode to IMAGE
98
+ if (runningMode === 'VIDEO') {
99
+ runningMode = 'IMAGE';
100
+ yield imageSegmenter.setOptions({
101
+ runningMode: runningMode,
102
+ });
103
+ }
104
+ // imageSegmenter.segment() when resolved will call the callback function.
105
+ imageSegmenter.segment(event.target, callback);
106
+ });
107
+ }
108
+ function callback(result) {
109
+ const cxt = canvasClick.getContext('2d');
110
+ const { width, height } = result.categoryMask;
111
+ let imageData = cxt.getImageData(0, 0, width, height).data;
112
+ canvasClick.width = width;
113
+ canvasClick.height = height;
114
+ let category = '';
115
+ const mask = result.categoryMask.getAsUint8Array();
116
+ for (let i in mask) {
117
+ if (mask[i] > 0) {
118
+ category = labels[mask[i]];
119
+ }
120
+ const legendColor = legendColors[mask[i] % legendColors.length];
121
+ imageData[i * 4] = (legendColor[0] + imageData[i * 4]) / 2;
122
+ imageData[i * 4 + 1] = (legendColor[1] + imageData[i * 4 + 1]) / 2;
123
+ imageData[i * 4 + 2] = (legendColor[2] + imageData[i * 4 + 2]) / 2;
124
+ imageData[i * 4 + 3] = (legendColor[3] + imageData[i * 4 + 3]) / 2;
125
+ }
126
+ const uint8Array = new Uint8ClampedArray(imageData.buffer);
127
+ const dataNew = new ImageData(uint8Array, width, height);
128
+ cxt.putImageData(dataNew, 0, 0);
129
+ const p = event.target.parentNode.getElementsByClassName('classification')[0];
130
+ p.classList.remove('removed');
131
+ p.innerText = 'Category: ' + category;
132
+ }
133
+ function callbackForVideo(result) {
134
+ let imageData = canvasCtx.getImageData(0, 0, video.videoWidth, video.videoHeight).data;
135
+ const mask = result.categoryMask.getAsFloat32Array();
136
+ let j = 0;
137
+ for (let i = 0; i < mask.length; ++i) {
138
+ const maskVal = Math.round(mask[i] * 255.0);
139
+ const legendColor = legendColors[maskVal % legendColors.length];
140
+ imageData[j] = (legendColor[0] + imageData[j]) / 2;
141
+ imageData[j + 1] = (legendColor[1] + imageData[j + 1]) / 2;
142
+ imageData[j + 2] = (legendColor[2] + imageData[j + 2]) / 2;
143
+ imageData[j + 3] = (legendColor[3] + imageData[j + 3]) / 2;
144
+ j += 4;
145
+ }
146
+ const uint8Array = new Uint8ClampedArray(imageData.buffer);
147
+ const dataNew = new ImageData(uint8Array, video.videoWidth, video.videoHeight);
148
+ canvasCtx.putImageData(dataNew, 0, 0);
149
+ if (webcamRunning === true) {
150
+ window.requestAnimationFrame(predictWebcam);
151
+ }
152
+ }
153
+ /********************************************************************
154
+ // Demo 2: Continuously grab image from webcam stream and segmented it.
155
+ ********************************************************************/
156
+ // Check if webcam access is supported.
157
+ function hasGetUserMedia() {
158
+ return !!(navigator.mediaDevices && navigator.mediaDevices.getUserMedia);
159
+ }
160
+ // Get segmentation from the webcam
161
+ let lastWebcamTime = -1;
162
+ function predictWebcam() {
163
+ return __awaiter(this, void 0, void 0, function* () {
164
+ if (video.currentTime === lastWebcamTime) {
165
+ if (webcamRunning === true) {
166
+ window.requestAnimationFrame(predictWebcam);
167
+ }
168
+ return;
169
+ }
170
+ lastWebcamTime = video.currentTime;
171
+ canvasCtx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
172
+ // Do not segmented if imageSegmenter hasn't loaded
173
+ if (imageSegmenter === undefined) {
174
+ return;
175
+ }
176
+ // if image mode is initialized, create a new segmented with video runningMode
177
+ if (runningMode === 'IMAGE') {
178
+ runningMode = 'VIDEO';
179
+ yield imageSegmenter.setOptions({
180
+ runningMode: runningMode,
181
+ });
182
+ }
183
+ let startTimeMs = performance.now();
184
+ // Start segmenting the stream.
185
+ imageSegmenter.segmentForVideo(video, startTimeMs, callbackForVideo);
186
+ });
187
+ }
188
+ // Enable the live webcam view and start imageSegmentation.
189
+ function enableCam(event) {
190
+ return __awaiter(this, void 0, void 0, function* () {
191
+ if (imageSegmenter === undefined) {
192
+ return;
193
+ }
194
+ if (webcamRunning === true) {
195
+ webcamRunning = false;
196
+ enableWebcamButton.innerText = 'ENABLE SEGMENTATION';
197
+ }
198
+ else {
199
+ webcamRunning = true;
200
+ enableWebcamButton.innerText = 'DISABLE SEGMENTATION';
201
+ }
202
+ // getUsermedia parameters.
203
+ const constraints = {
204
+ video: true,
205
+ };
206
+ // Activate the webcam stream.
207
+ video.srcObject = yield navigator.mediaDevices.getUserMedia(constraints);
208
+ video.addEventListener('loadeddata', predictWebcam);
209
+ });
210
+ }
211
+ // If webcam supported, add event listener to button.
212
+ if (hasGetUserMedia()) {
213
+ enableWebcamButton = document.getElementById('webcamButton');
214
+ enableWebcamButton.addEventListener('click', enableCam);
215
+ }
216
+ else {
217
+ console.warn('getUserMedia() is not supported by your browser');
218
+ }
219
+ //# sourceMappingURL=Untitled-1.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Untitled-1.js","sourceRoot":"","sources":["../../src/transformers/Untitled-1.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /// <reference types="dom-webcodecs" />
2
+ import { StreamTransformer, StreamTransformerInitOptions } from './types';
3
+ export default abstract class VideoTransformer implements StreamTransformer {
4
+ transformer?: TransformStream;
5
+ canvas?: OffscreenCanvas;
6
+ ctx?: OffscreenCanvasRenderingContext2D;
7
+ inputVideo?: HTMLVideoElement;
8
+ protected isDisabled?: Boolean;
9
+ init({ outputCanvas, inputVideo }: StreamTransformerInitOptions): void;
10
+ destroy(): Promise<void>;
11
+ abstract transform(frame: VideoFrame, controller: TransformStreamDefaultController<VideoFrame>): void;
12
+ }
@@ -0,0 +1,23 @@
1
+ export default class VideoTransformer {
2
+ constructor() {
3
+ this.isDisabled = false;
4
+ }
5
+ init({ outputCanvas, inputVideo }) {
6
+ var _a;
7
+ this.transformer = new TransformStream({
8
+ transform: (frame, controller) => this.transform(frame, controller),
9
+ });
10
+ this.canvas = outputCanvas || null;
11
+ if (outputCanvas) {
12
+ this.ctx = ((_a = this.canvas) === null || _a === void 0 ? void 0 : _a.getContext('2d', { readFrequently: true })) || undefined;
13
+ }
14
+ this.inputVideo = inputVideo;
15
+ this.isDisabled = false;
16
+ }
17
+ async destroy() {
18
+ this.isDisabled = true;
19
+ this.canvas = undefined;
20
+ this.ctx = undefined;
21
+ }
22
+ }
23
+ //# 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;IAwBzC,CAAC;IAtBC,IAAI,CAAC,EAAE,YAAY,EAAE,UAAU,EAAgC;;QAC7D,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,11 @@
1
+ /// <reference types="dom-webcodecs" />
2
+ export type StreamTransformerInitOptions = {
3
+ outputCanvas: OffscreenCanvas;
4
+ inputVideo: HTMLVideoElement;
5
+ };
6
+ export interface StreamTransformer {
7
+ init: (options: StreamTransformerInitOptions) => void;
8
+ destroy: () => void;
9
+ transform: (frame: VideoFrame, controller: TransformStreamDefaultController) => void;
10
+ transformer?: TransformStream;
11
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/transformers/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export declare const supportsProcessor: boolean;
2
+ export declare const supportsOffscreenCanvas: boolean;
package/dist/utils.js ADDED
@@ -0,0 +1,3 @@
1
+ export const supportsProcessor = typeof MediaStreamTrackGenerator !== 'undefined';
2
+ export const supportsOffscreenCanvas = typeof OffscreenCanvas !== 'undefined';
3
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,yBAAyB,KAAK,WAAW,CAAC;AAClF,MAAM,CAAC,MAAM,uBAAuB,GAAG,OAAO,eAAe,KAAK,WAAW,CAAC"}
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@livekit/track-processors",
3
+ "version": "0.1.0",
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.0"
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
+ }