@livekit/track-processors 0.1.0 → 0.1.1
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.
- package/dist/ProcessorPipeline.d.ts +8 -7
- package/dist/ProcessorPipeline.js +6 -4
- package/dist/ProcessorPipeline.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/transformers/BackgroundTransformer.d.ts +3 -3
- package/dist/transformers/BackgroundTransformer.js +26 -22
- package/dist/transformers/BackgroundTransformer.js.map +1 -1
- package/dist/transformers/MediaPipeHolisticTrackerTransformer.d.ts +2 -2
- package/dist/transformers/MediaPipeHolisticTrackerTransformer.js +2 -2
- package/dist/transformers/MediaPipeHolisticTrackerTransformer.js.map +1 -1
- package/dist/transformers/VideoTransformer.d.ts +3 -3
- package/dist/transformers/VideoTransformer.js +4 -1
- package/dist/transformers/VideoTransformer.js.map +1 -1
- package/dist/transformers/types.d.ts +8 -5
- package/package.json +1 -1
- package/dist/BackgroundProcessor.d.ts +0 -23
- package/dist/BackgroundProcessor.js +0 -114
- package/dist/BackgroundProcessor.js.map +0 -1
- package/dist/BaseVideoProcessor.d.ts +0 -28
- package/dist/BaseVideoProcessor.js +0 -110
- package/dist/BaseVideoProcessor.js.map +0 -1
- package/dist/transformers/Untitled-1.d.ts +0 -1
- package/dist/transformers/Untitled-1.js +0 -219
- 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,
|
|
4
|
-
import {
|
|
5
|
-
export default class ProcessorPipeline implements
|
|
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?:
|
|
13
|
+
sourceDummy?: HTMLMediaElement;
|
|
13
14
|
processedTrack?: MediaStreamTrack;
|
|
14
|
-
transformers: Array<
|
|
15
|
-
constructor(transformers: Array<
|
|
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
|
-
|
|
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;
|
|
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
|
|
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
|
|
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,
|
|
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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference types="dom-webcodecs" />
|
|
2
2
|
import * as vision from '@mediapipe/tasks-vision';
|
|
3
3
|
import VideoTransformer from './VideoTransformer';
|
|
4
|
-
import {
|
|
4
|
+
import { VideoTransformerInitOptions } from './types';
|
|
5
5
|
export type BackgroundOptions = {
|
|
6
6
|
blurRadius?: number;
|
|
7
7
|
imagePath?: string;
|
|
@@ -13,11 +13,11 @@ export default class BackgroundProcessor extends VideoTransformer {
|
|
|
13
13
|
backgroundImage: ImageBitmap | null;
|
|
14
14
|
blurRadius?: number;
|
|
15
15
|
constructor(opts: BackgroundOptions);
|
|
16
|
-
init({ outputCanvas, inputVideo }:
|
|
16
|
+
init({ outputCanvas, inputElement: inputVideo }: VideoTransformerInitOptions): Promise<void>;
|
|
17
17
|
destroy(): Promise<void>;
|
|
18
18
|
sendFramesContinuouslyForSegmentation(videoEl: HTMLVideoElement): Promise<void>;
|
|
19
19
|
loadBackground(path: string): Promise<void>;
|
|
20
20
|
transform(frame: VideoFrame, controller: TransformStreamDefaultController<VideoFrame>): Promise<void>;
|
|
21
|
-
drawVirtualBackground(frame: VideoFrame): void
|
|
21
|
+
drawVirtualBackground(frame: VideoFrame): Promise<void>;
|
|
22
22
|
blurBackground(frame: VideoFrame): Promise<void>;
|
|
23
23
|
}
|
|
@@ -6,7 +6,6 @@ export default class BackgroundProcessor extends VideoTransformer {
|
|
|
6
6
|
}
|
|
7
7
|
constructor(opts) {
|
|
8
8
|
super();
|
|
9
|
-
// backgroundImagePattern: CanvasPattern | null = null;
|
|
10
9
|
this.backgroundImage = null;
|
|
11
10
|
if (opts.blurRadius) {
|
|
12
11
|
this.blurRadius = opts.blurRadius;
|
|
@@ -15,8 +14,8 @@ export default class BackgroundProcessor extends VideoTransformer {
|
|
|
15
14
|
this.loadBackground(opts.imagePath);
|
|
16
15
|
}
|
|
17
16
|
}
|
|
18
|
-
async init({ outputCanvas, inputVideo }) {
|
|
19
|
-
super.init({ outputCanvas, inputVideo });
|
|
17
|
+
async init({ outputCanvas, inputElement: inputVideo }) {
|
|
18
|
+
super.init({ outputCanvas, inputElement: inputVideo });
|
|
20
19
|
const fileSet = await vision.FilesetResolver.forVisionTasks('https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.0/wasm');
|
|
21
20
|
this.imageSegmenter = await vision.ImageSegmenter.createFromOptions(fileSet, {
|
|
22
21
|
baseOptions: {
|
|
@@ -71,7 +70,7 @@ export default class BackgroundProcessor extends VideoTransformer {
|
|
|
71
70
|
await this.blurBackground(frame);
|
|
72
71
|
}
|
|
73
72
|
else {
|
|
74
|
-
this.drawVirtualBackground(frame);
|
|
73
|
+
await this.drawVirtualBackground(frame);
|
|
75
74
|
}
|
|
76
75
|
const newFrame = new VideoFrame(this.canvas, {
|
|
77
76
|
timestamp: frame.timestamp || Date.now(),
|
|
@@ -79,17 +78,17 @@ export default class BackgroundProcessor extends VideoTransformer {
|
|
|
79
78
|
frame.close();
|
|
80
79
|
controller.enqueue(newFrame);
|
|
81
80
|
}
|
|
82
|
-
drawVirtualBackground(frame) {
|
|
83
|
-
var _a
|
|
84
|
-
if (!this.canvas || !this.ctx)
|
|
81
|
+
async drawVirtualBackground(frame) {
|
|
82
|
+
var _a;
|
|
83
|
+
if (!this.canvas || !this.ctx || !this.segmentationResults || !this.inputVideo)
|
|
85
84
|
return;
|
|
86
85
|
// this.ctx.save();
|
|
87
86
|
// this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
|
88
87
|
if ((_a = this.segmentationResults) === null || _a === void 0 ? void 0 : _a.categoryMask) {
|
|
89
88
|
this.ctx.filter = 'blur(3px)';
|
|
90
89
|
this.ctx.globalCompositeOperation = 'copy';
|
|
91
|
-
const
|
|
92
|
-
this.ctx.
|
|
90
|
+
const bitmap = await maskToBitmap(this.segmentationResults.categoryMask, this.inputVideo.videoWidth, this.inputVideo.videoHeight);
|
|
91
|
+
this.ctx.drawImage(bitmap, 0, 0);
|
|
93
92
|
this.ctx.filter = 'none';
|
|
94
93
|
this.ctx.globalCompositeOperation = 'source-in';
|
|
95
94
|
if (this.backgroundImage) {
|
|
@@ -110,23 +109,16 @@ export default class BackgroundProcessor extends VideoTransformer {
|
|
|
110
109
|
if (!this.ctx ||
|
|
111
110
|
!this.canvas ||
|
|
112
111
|
!((_b = (_a = this.segmentationResults) === null || _a === void 0 ? void 0 : _a.categoryMask) === null || _b === void 0 ? void 0 : _b.canvas) ||
|
|
113
|
-
!this.inputVideo)
|
|
112
|
+
!this.inputVideo) {
|
|
114
113
|
return;
|
|
114
|
+
}
|
|
115
115
|
this.ctx.save();
|
|
116
116
|
this.ctx.globalCompositeOperation = 'copy';
|
|
117
|
-
const
|
|
118
|
-
|
|
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)';
|
|
117
|
+
const bitmap = await maskToBitmap(this.segmentationResults.categoryMask, this.inputVideo.videoWidth, this.inputVideo.videoHeight);
|
|
118
|
+
this.ctx.filter = 'blur(3px)';
|
|
127
119
|
this.ctx.globalCompositeOperation = 'copy';
|
|
128
|
-
this.ctx.drawImage(
|
|
129
|
-
|
|
120
|
+
this.ctx.drawImage(bitmap, 0, 0);
|
|
121
|
+
this.ctx.filter = 'none';
|
|
130
122
|
this.ctx.globalCompositeOperation = 'source-out';
|
|
131
123
|
this.ctx.drawImage(frame, 0, 0, this.canvas.width, this.canvas.height);
|
|
132
124
|
this.ctx.globalCompositeOperation = 'destination-over';
|
|
@@ -136,4 +128,16 @@ export default class BackgroundProcessor extends VideoTransformer {
|
|
|
136
128
|
console.log('draw time', performance.now() - start);
|
|
137
129
|
}
|
|
138
130
|
}
|
|
131
|
+
function maskToBitmap(mask, videoWidth, videoHeight) {
|
|
132
|
+
const dataArray = new Uint8ClampedArray(videoWidth * videoHeight * 4);
|
|
133
|
+
const result = mask.getAsUint8Array();
|
|
134
|
+
for (let i = 0; i < result.length; i += 1) {
|
|
135
|
+
dataArray[i * 4] = result[i];
|
|
136
|
+
dataArray[i * 4 + 1] = result[i];
|
|
137
|
+
dataArray[i * 4 + 2] = result[i];
|
|
138
|
+
dataArray[i * 4 + 3] = result[i];
|
|
139
|
+
}
|
|
140
|
+
const dataNew = new ImageData(dataArray, videoWidth, videoHeight);
|
|
141
|
+
return createImageBitmap(dataNew);
|
|
142
|
+
}
|
|
139
143
|
//# sourceMappingURL=BackgroundTransformer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackgroundTransformer.js","sourceRoot":"","sources":["../../src/transformers/BackgroundTransformer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,yBAAyB,CAAC;AAClD,OAAO,gBAAgB,MAAM,oBAAoB,CAAC;AAQlD,MAAM,CAAC,OAAO,OAAO,mBAAoB,SAAQ,gBAAgB;IAC/D,MAAM,KAAK,WAAW;QACpB,OAAO,OAAO,eAAe,KAAK,WAAW,CAAC;IAChD,CAAC;
|
|
1
|
+
{"version":3,"file":"BackgroundTransformer.js","sourceRoot":"","sources":["../../src/transformers/BackgroundTransformer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Holistic, Options, Results } from '@mediapipe/holistic';
|
|
2
2
|
import VideoTransformer from './VideoTransformer';
|
|
3
|
-
import {
|
|
3
|
+
import { VideoTransformerInitOptions } from './types';
|
|
4
4
|
export type MediaPipeHolisticTrackerTransformerOptions = {
|
|
5
5
|
holisticOptions?: Options;
|
|
6
6
|
callback?: (results: Results) => void;
|
|
@@ -11,7 +11,7 @@ export default class MediaPipeHolisticTrackerTransformer extends VideoTransforme
|
|
|
11
11
|
callback: (results: Results) => void;
|
|
12
12
|
static get isSupported(): boolean;
|
|
13
13
|
constructor({ holisticOptions, callback }: MediaPipeHolisticTrackerTransformerOptions);
|
|
14
|
-
init({ inputVideo, outputCanvas }:
|
|
14
|
+
init({ inputElement: inputVideo, outputCanvas }: VideoTransformerInitOptions): void;
|
|
15
15
|
destroy(): Promise<void>;
|
|
16
16
|
transform(): Promise<void>;
|
|
17
17
|
sendFramesContinuouslyForTracking(videoEl: HTMLVideoElement): Promise<void>;
|
|
@@ -9,8 +9,8 @@ export default class MediaPipeHolisticTrackerTransformer extends VideoTransforme
|
|
|
9
9
|
this.callback = callback || (() => null);
|
|
10
10
|
this.holisticOptions = holisticOptions || {};
|
|
11
11
|
}
|
|
12
|
-
init({ inputVideo, outputCanvas }) {
|
|
13
|
-
super.init({ outputCanvas, inputVideo });
|
|
12
|
+
init({ inputElement: inputVideo, outputCanvas }) {
|
|
13
|
+
super.init({ outputCanvas, inputElement: inputVideo });
|
|
14
14
|
this.holistic = new Holistic({
|
|
15
15
|
locateFile: (file) => `https://cdn.jsdelivr.net/npm/@mediapipe/holistic/${file}`,
|
|
16
16
|
});
|
|
@@ -1 +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,
|
|
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"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/// <reference types="dom-webcodecs" />
|
|
2
|
-
import {
|
|
3
|
-
export default abstract class VideoTransformer implements
|
|
2
|
+
import { VideoTrackTransformer, VideoTransformerInitOptions } from './types';
|
|
3
|
+
export default abstract class VideoTransformer implements VideoTrackTransformer {
|
|
4
4
|
transformer?: TransformStream;
|
|
5
5
|
canvas?: OffscreenCanvas;
|
|
6
6
|
ctx?: OffscreenCanvasRenderingContext2D;
|
|
7
7
|
inputVideo?: HTMLVideoElement;
|
|
8
8
|
protected isDisabled?: Boolean;
|
|
9
|
-
init({ outputCanvas, inputVideo }:
|
|
9
|
+
init({ outputCanvas, inputElement: inputVideo }: VideoTransformerInitOptions): void;
|
|
10
10
|
destroy(): Promise<void>;
|
|
11
11
|
abstract transform(frame: VideoFrame, controller: TransformStreamDefaultController<VideoFrame>): void;
|
|
12
12
|
}
|
|
@@ -2,8 +2,11 @@ export default class VideoTransformer {
|
|
|
2
2
|
constructor() {
|
|
3
3
|
this.isDisabled = false;
|
|
4
4
|
}
|
|
5
|
-
init({ outputCanvas, inputVideo }) {
|
|
5
|
+
init({ outputCanvas, inputElement: inputVideo }) {
|
|
6
6
|
var _a;
|
|
7
|
+
if (!(inputVideo instanceof HTMLVideoElement)) {
|
|
8
|
+
throw TypeError('Video transformer needs a HTMLVideoElement as input');
|
|
9
|
+
}
|
|
7
10
|
this.transformer = new TransformStream({
|
|
8
11
|
transform: (frame, controller) => this.transform(frame, controller),
|
|
9
12
|
});
|
|
@@ -1 +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;
|
|
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"}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
/// <reference types="dom-webcodecs" />
|
|
2
|
-
export type
|
|
3
|
-
|
|
4
|
-
inputVideo: HTMLVideoElement;
|
|
2
|
+
export type TrackTransformerInitOptions = {
|
|
3
|
+
inputElement: HTMLMediaElement;
|
|
5
4
|
};
|
|
6
|
-
export interface
|
|
7
|
-
|
|
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;
|
|
8
11
|
destroy: () => void;
|
|
9
12
|
transform: (frame: VideoFrame, controller: TransformStreamDefaultController) => void;
|
|
10
13
|
transformer?: TransformStream;
|
package/package.json
CHANGED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/// <reference types="dom-webcodecs" />
|
|
2
|
-
import { SelfieSegmentation, Results } from '@mediapipe/selfie_segmentation';
|
|
3
|
-
export declare type BlurOptions = {
|
|
4
|
-
blurRadius?: number;
|
|
5
|
-
backgroundImage?: string;
|
|
6
|
-
};
|
|
7
|
-
export default class BackgroundProcessor {
|
|
8
|
-
transformer: TransformStream;
|
|
9
|
-
selfieSegmentation?: SelfieSegmentation;
|
|
10
|
-
segmentationResults: Results | undefined;
|
|
11
|
-
canvas?: OffscreenCanvas;
|
|
12
|
-
ctx?: OffscreenCanvasRenderingContext2D;
|
|
13
|
-
backgroundImage: ImageBitmap | null;
|
|
14
|
-
inputVideo?: HTMLVideoElement;
|
|
15
|
-
blurRadius?: number;
|
|
16
|
-
constructor(opts: BlurOptions);
|
|
17
|
-
init(outputCanvas: OffscreenCanvas, inputVideo: HTMLVideoElement): void;
|
|
18
|
-
sendFramesContinuouslyForSegmentation(videoEl: HTMLVideoElement): void;
|
|
19
|
-
loadBackground(path: string): Promise<void>;
|
|
20
|
-
transform(frame: VideoFrame, controller: TransformStreamDefaultController<VideoFrame>): Promise<void>;
|
|
21
|
-
drawVirtualBackground(frame: VideoFrame): void;
|
|
22
|
-
blurBackground(frame: VideoFrame): void;
|
|
23
|
-
}
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
const selfie_segmentation_1 = require("@mediapipe/selfie_segmentation");
|
|
13
|
-
class BackgroundProcessor {
|
|
14
|
-
constructor(opts) {
|
|
15
|
-
// backgroundImagePattern: CanvasPattern | null = null;
|
|
16
|
-
this.backgroundImage = null;
|
|
17
|
-
this.transformer = new TransformStream({
|
|
18
|
-
transform: (frame, controller) => this.transform(frame, controller),
|
|
19
|
-
});
|
|
20
|
-
if (opts.blurRadius) {
|
|
21
|
-
this.blurRadius = opts.blurRadius;
|
|
22
|
-
}
|
|
23
|
-
else if (opts.backgroundImage) {
|
|
24
|
-
this.loadBackground(opts.backgroundImage);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
init(outputCanvas, inputVideo) {
|
|
28
|
-
this.canvas = outputCanvas;
|
|
29
|
-
this.ctx = this.canvas.getContext('2d');
|
|
30
|
-
this.inputVideo = inputVideo;
|
|
31
|
-
this.selfieSegmentation = new selfie_segmentation_1.SelfieSegmentation({ locateFile: (file) => `https://cdn.jsdelivr.net/npm/@mediapipe/selfie_segmentation/${file}` });
|
|
32
|
-
this.selfieSegmentation.setOptions({
|
|
33
|
-
modelSelection: 1,
|
|
34
|
-
selfieMode: false,
|
|
35
|
-
});
|
|
36
|
-
this.selfieSegmentation.onResults((results) => { this.segmentationResults = results; });
|
|
37
|
-
// this.loadBackground(opts.backgroundUrl).catch((e) => console.error(e));
|
|
38
|
-
this.sendFramesContinuouslyForSegmentation(this.inputVideo);
|
|
39
|
-
}
|
|
40
|
-
sendFramesContinuouslyForSegmentation(videoEl) {
|
|
41
|
-
var _a;
|
|
42
|
-
// @ts-ignore
|
|
43
|
-
videoEl.requestVideoFrameCallback(() => this.sendFramesContinuouslyForSegmentation(videoEl));
|
|
44
|
-
(_a = this.selfieSegmentation) === null || _a === void 0 ? void 0 : _a.send({ image: videoEl });
|
|
45
|
-
}
|
|
46
|
-
loadBackground(path) {
|
|
47
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
48
|
-
const img = new Image();
|
|
49
|
-
yield new Promise((resolve, reject) => {
|
|
50
|
-
img.crossOrigin = 'Anonymous';
|
|
51
|
-
img.onload = () => resolve(img);
|
|
52
|
-
img.onerror = (err) => reject(err);
|
|
53
|
-
img.src = path;
|
|
54
|
-
});
|
|
55
|
-
const imageData = yield createImageBitmap(img);
|
|
56
|
-
this.backgroundImage = imageData;
|
|
57
|
-
// this.backgroundImagePattern = this.ctx?.createPattern(imageData, 'repeat') ?? null;
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
transform(frame, controller) {
|
|
61
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
62
|
-
if (this.blurRadius) {
|
|
63
|
-
this.blurBackground(frame);
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
this.drawVirtualBackground(frame);
|
|
67
|
-
}
|
|
68
|
-
// @ts-ignore
|
|
69
|
-
const newFrame = new VideoFrame(this.canvas, { timestamp: performance.now() });
|
|
70
|
-
frame.close();
|
|
71
|
-
controller.enqueue(newFrame);
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
drawVirtualBackground(frame) {
|
|
75
|
-
if (!this.canvas || !this.ctx)
|
|
76
|
-
return;
|
|
77
|
-
// this.ctx.save();
|
|
78
|
-
// this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
|
79
|
-
if (this.segmentationResults) {
|
|
80
|
-
this.ctx.filter = 'blur(3px)';
|
|
81
|
-
this.ctx.globalCompositeOperation = 'copy';
|
|
82
|
-
this.ctx.drawImage(this.segmentationResults.segmentationMask, 0, 0);
|
|
83
|
-
this.ctx.filter = 'none';
|
|
84
|
-
this.ctx.globalCompositeOperation = 'source-out';
|
|
85
|
-
if (this.backgroundImage) {
|
|
86
|
-
this.ctx.drawImage(this.backgroundImage, 0, 0, this.backgroundImage.width, this.backgroundImage.height, 0, 0, this.canvas.width, this.canvas.height);
|
|
87
|
-
}
|
|
88
|
-
else {
|
|
89
|
-
this.ctx.fillStyle = '#00FF00';
|
|
90
|
-
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
|
|
91
|
-
}
|
|
92
|
-
this.ctx.globalCompositeOperation = 'destination-over';
|
|
93
|
-
}
|
|
94
|
-
this.ctx.drawImage(frame, 0, 0, this.canvas.width, this.canvas.height);
|
|
95
|
-
// this.ctx.restore();
|
|
96
|
-
}
|
|
97
|
-
blurBackground(frame) {
|
|
98
|
-
if (!this.ctx || !this.canvas || !this.segmentationResults)
|
|
99
|
-
return;
|
|
100
|
-
this.ctx.save();
|
|
101
|
-
this.ctx.filter = `blur(${this.blurRadius}px)`;
|
|
102
|
-
this.ctx.globalCompositeOperation = 'copy';
|
|
103
|
-
this.ctx.drawImage(this.segmentationResults.segmentationMask, 0, 0, this.canvas.width, this.canvas.height);
|
|
104
|
-
this.ctx.filter = 'none';
|
|
105
|
-
this.ctx.globalCompositeOperation = 'source-in';
|
|
106
|
-
this.ctx.drawImage(frame, 0, 0, this.canvas.width, this.canvas.height);
|
|
107
|
-
this.ctx.globalCompositeOperation = 'destination-over';
|
|
108
|
-
this.ctx.filter = 'blur(10px)';
|
|
109
|
-
this.ctx.drawImage(frame, 0, 0);
|
|
110
|
-
this.ctx.restore();
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
exports.default = BackgroundProcessor;
|
|
114
|
-
//# sourceMappingURL=BackgroundProcessor.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"BackgroundProcessor.js","sourceRoot":"","sources":["../src/BackgroundProcessor.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/// <reference types="dom-mediacapture-transform" />
|
|
2
|
-
/// <reference types="dom-webcodecs" />
|
|
3
|
-
import { SelfieSegmentation, Results } from '@mediapipe/selfie_segmentation';
|
|
4
|
-
import type { ProcessorOptions, VideoProcessor } from 'livekit-client';
|
|
5
|
-
export declare type VirtualBackgroundOptions = ProcessorOptions & {
|
|
6
|
-
backgroundUrl: string;
|
|
7
|
-
};
|
|
8
|
-
export declare class VirtualBackgroundProcessor implements VideoProcessor<VirtualBackgroundOptions> {
|
|
9
|
-
source?: MediaStreamVideoTrack;
|
|
10
|
-
sourceSettings?: MediaTrackSettings;
|
|
11
|
-
processor?: MediaStreamTrackProcessor<VideoFrame>;
|
|
12
|
-
trackGenerator?: MediaStreamTrackGenerator<VideoFrame>;
|
|
13
|
-
canvas?: OffscreenCanvas;
|
|
14
|
-
ctx?: OffscreenCanvasRenderingContext2D;
|
|
15
|
-
sourceDummy?: HTMLVideoElement;
|
|
16
|
-
transformer?: TransformStream;
|
|
17
|
-
selfieSegmentation?: SelfieSegmentation;
|
|
18
|
-
backgroundImagePattern: CanvasPattern | null;
|
|
19
|
-
processedTrack?: MediaStreamTrack;
|
|
20
|
-
init(opts: VirtualBackgroundOptions): void;
|
|
21
|
-
destroy(): void;
|
|
22
|
-
sendFramesContinuouslyForSegmentation(videoEl: HTMLVideoElement): void;
|
|
23
|
-
loadBackground(path: string): Promise<void>;
|
|
24
|
-
segmentationResults: Results | undefined;
|
|
25
|
-
drawResults(frame: VideoFrame): void;
|
|
26
|
-
blurBackground(frame: VideoFrame): void;
|
|
27
|
-
transform(frame: VideoFrame, controller: TransformStreamDefaultController<VideoFrame>): Promise<void>;
|
|
28
|
-
}
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.VirtualBackgroundProcessor = void 0;
|
|
13
|
-
const selfie_segmentation_1 = require("@mediapipe/selfie_segmentation");
|
|
14
|
-
class VirtualBackgroundProcessor {
|
|
15
|
-
constructor() {
|
|
16
|
-
this.backgroundImagePattern = null;
|
|
17
|
-
}
|
|
18
|
-
init(opts) {
|
|
19
|
-
this.source = opts.track;
|
|
20
|
-
this.sourceSettings = this.source.getSettings();
|
|
21
|
-
this.sourceDummy = opts.element;
|
|
22
|
-
// TODO explore if we can do all the processing work in a webworker
|
|
23
|
-
this.processor = new MediaStreamTrackProcessor({ track: this.source });
|
|
24
|
-
this.trackGenerator = new MediaStreamTrackGenerator({ kind: 'video' });
|
|
25
|
-
this.transformer = new TransformStream({
|
|
26
|
-
transform: (frame, controller) => this.transform(frame, controller),
|
|
27
|
-
});
|
|
28
|
-
this.processor.readable.pipeThrough(this.transformer).pipeTo(this.trackGenerator.writable);
|
|
29
|
-
this.processedTrack = this.trackGenerator;
|
|
30
|
-
this.canvas = new OffscreenCanvas(this.sourceSettings.width, this.sourceSettings.height);
|
|
31
|
-
this.ctx = this.canvas.getContext('2d');
|
|
32
|
-
this.selfieSegmentation = new selfie_segmentation_1.SelfieSegmentation({ locateFile: (file) => `https://cdn.jsdelivr.net/npm/@mediapipe/selfie_segmentation/${file}` });
|
|
33
|
-
this.selfieSegmentation.setOptions({
|
|
34
|
-
modelSelection: 1,
|
|
35
|
-
selfieMode: false,
|
|
36
|
-
});
|
|
37
|
-
this.selfieSegmentation.onResults((results) => { this.segmentationResults = results; });
|
|
38
|
-
this.loadBackground(opts.backgroundUrl).catch((e) => console.error(e));
|
|
39
|
-
this.sendFramesContinuouslyForSegmentation(this.sourceDummy);
|
|
40
|
-
}
|
|
41
|
-
destroy() {
|
|
42
|
-
// TODO
|
|
43
|
-
}
|
|
44
|
-
sendFramesContinuouslyForSegmentation(videoEl) {
|
|
45
|
-
var _a;
|
|
46
|
-
// @ts-ignore
|
|
47
|
-
videoEl.requestVideoFrameCallback(() => this.sendFramesContinuouslyForSegmentation(videoEl));
|
|
48
|
-
(_a = this.selfieSegmentation) === null || _a === void 0 ? void 0 : _a.send({ image: videoEl });
|
|
49
|
-
}
|
|
50
|
-
loadBackground(path) {
|
|
51
|
-
var _a, _b;
|
|
52
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
53
|
-
const img = new Image();
|
|
54
|
-
yield new Promise((resolve, reject) => {
|
|
55
|
-
img.crossOrigin = 'Anonymous';
|
|
56
|
-
img.onload = () => resolve(img);
|
|
57
|
-
img.onerror = (err) => reject(err);
|
|
58
|
-
img.src = path;
|
|
59
|
-
});
|
|
60
|
-
const imageData = yield createImageBitmap(img);
|
|
61
|
-
this.backgroundImagePattern = (_b = (_a = this.ctx) === null || _a === void 0 ? void 0 : _a.createPattern(imageData, 'repeat')) !== null && _b !== void 0 ? _b : null;
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
drawResults(frame) {
|
|
65
|
-
var _a;
|
|
66
|
-
if (!this.canvas || !this.ctx)
|
|
67
|
-
return;
|
|
68
|
-
// this.ctx.save();
|
|
69
|
-
// this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
|
70
|
-
if (this.segmentationResults) {
|
|
71
|
-
this.ctx.filter = 'blur(3px)';
|
|
72
|
-
this.ctx.globalCompositeOperation = 'copy';
|
|
73
|
-
this.ctx.drawImage(this.segmentationResults.segmentationMask, 0, 0);
|
|
74
|
-
this.ctx.filter = 'none';
|
|
75
|
-
this.ctx.globalCompositeOperation = 'source-out';
|
|
76
|
-
this.ctx.fillStyle = (_a = this.backgroundImagePattern) !== null && _a !== void 0 ? _a : '#00FF00';
|
|
77
|
-
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
|
|
78
|
-
this.ctx.globalCompositeOperation = 'destination-over';
|
|
79
|
-
}
|
|
80
|
-
this.ctx.drawImage(frame, 0, 0, this.canvas.width, this.canvas.height);
|
|
81
|
-
// this.ctx.restore();
|
|
82
|
-
}
|
|
83
|
-
blurBackground(frame) {
|
|
84
|
-
if (!this.ctx || !this.canvas || !this.segmentationResults)
|
|
85
|
-
return;
|
|
86
|
-
this.ctx.save();
|
|
87
|
-
this.ctx.filter = 'blur(3px)';
|
|
88
|
-
this.ctx.globalCompositeOperation = 'copy';
|
|
89
|
-
this.ctx.drawImage(this.segmentationResults.segmentationMask, 0, 0, this.canvas.width, this.canvas.height);
|
|
90
|
-
this.ctx.filter = 'none';
|
|
91
|
-
this.ctx.globalCompositeOperation = 'source-in';
|
|
92
|
-
this.ctx.drawImage(frame, 0, 0, this.canvas.width, this.canvas.height);
|
|
93
|
-
this.ctx.globalCompositeOperation = 'destination-over';
|
|
94
|
-
this.ctx.filter = 'blur(10px)';
|
|
95
|
-
this.ctx.drawImage(frame, 0, 0);
|
|
96
|
-
this.ctx.restore();
|
|
97
|
-
}
|
|
98
|
-
transform(frame, controller) {
|
|
99
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
100
|
-
this.drawResults(frame);
|
|
101
|
-
// this.blurBackground(frame);
|
|
102
|
-
// @ts-ignore
|
|
103
|
-
const newFrame = new VideoFrame(this.canvas, { timestamp: performance.now() });
|
|
104
|
-
frame.close();
|
|
105
|
-
controller.enqueue(newFrame);
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
exports.VirtualBackgroundProcessor = VirtualBackgroundProcessor;
|
|
110
|
-
//# sourceMappingURL=BaseVideoProcessor.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"BaseVideoProcessor.js","sourceRoot":"","sources":["../src/BaseVideoProcessor.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,219 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Untitled-1.js","sourceRoot":"","sources":["../../src/transformers/Untitled-1.ts"],"names":[],"mappings":"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"}
|