@kubohiroya/turbowarp-teachable-machine 3.3.0 → 3.4.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.
- package/README.md +19 -4
- package/dist/backend-wasm.js +1 -1
- package/dist/backend-webgpu.js +1 -1
- package/dist/composition.js +54 -4
- package/dist/posenet.js +2 -1
- package/dist/runtime.js +2 -2
- package/dist/tm.js +54 -4
- package/dist/types/extension.d.ts +13 -0
- package/package.json +2 -1
package/dist/tm.js
CHANGED
|
@@ -553,7 +553,7 @@
|
|
|
553
553
|
}
|
|
554
554
|
var package_default = {
|
|
555
555
|
name: "@kubohiroya/turbowarp-teachable-machine",
|
|
556
|
-
version: "3.
|
|
556
|
+
version: "3.4.0",
|
|
557
557
|
description: "A TurboWarp extension for recognition using Teachable Machine pose, image, and audio models.",
|
|
558
558
|
author: "Hiroya Kubo <hiroya@cuc.ac.jp>",
|
|
559
559
|
license: "MPL-2.0",
|
|
@@ -621,6 +621,7 @@
|
|
|
621
621
|
"prepack": "npm run build && npm run release:consistency:check"
|
|
622
622
|
},
|
|
623
623
|
devDependencies: {
|
|
624
|
+
"@kubohiroya/turbowarp-camera-source": "0.13.0",
|
|
624
625
|
"@kubohiroya/vite-plugin-turbowarp-extension": "0.4.0",
|
|
625
626
|
"@teachablemachine/image": "0.8.5",
|
|
626
627
|
"@teachablemachine/pose": "0.8.6",
|
|
@@ -647,6 +648,23 @@
|
|
|
647
648
|
};
|
|
648
649
|
//#endregion
|
|
649
650
|
//#region src/extension.ts
|
|
651
|
+
/**
|
|
652
|
+
* Where Camera Source puts itself on the VM runtime.
|
|
653
|
+
*
|
|
654
|
+
* Declared here rather than imported as a value, because this file is bundled into a single-file
|
|
655
|
+
* extension and no dependency's code has ever been inlined into it. The key and the member read
|
|
656
|
+
* below are pinned against Camera Source's own published constant and narrowing function in the
|
|
657
|
+
* tests, which import both and are not shipped, so a rename upstream fails here rather than
|
|
658
|
+
* silently reading an absent extension as "not loaded".
|
|
659
|
+
*/
|
|
660
|
+
var CAMERA_SOURCE_RUNTIME_KEY = "ext_kubohiroyacamerasource";
|
|
661
|
+
function readCameraSource(runtime) {
|
|
662
|
+
if (typeof runtime !== "object" || runtime === null) return void 0;
|
|
663
|
+
const candidate = runtime[CAMERA_SOURCE_RUNTIME_KEY];
|
|
664
|
+
if (typeof candidate !== "object" || candidate === null) return void 0;
|
|
665
|
+
const { acquireCamera } = candidate;
|
|
666
|
+
return typeof acquireCamera === "function" ? candidate : void 0;
|
|
667
|
+
}
|
|
650
668
|
var EXTENSION_ID = "kubohiroyatm";
|
|
651
669
|
var VERSION = `${package_default.version}-typescript`;
|
|
652
670
|
var DOCS_URI = "https://kubohiroya.github.io/turbowarp-teachable-machine/";
|
|
@@ -929,6 +947,7 @@
|
|
|
929
947
|
this.modelURL = "";
|
|
930
948
|
this.model = null;
|
|
931
949
|
this.webcam = null;
|
|
950
|
+
this.cameraLease = null;
|
|
932
951
|
this.cameraRunning = false;
|
|
933
952
|
this.cameraSelection = "default";
|
|
934
953
|
this.cameraSelectionIsDeviceId = false;
|
|
@@ -1150,8 +1169,11 @@
|
|
|
1150
1169
|
await this.ensureComputeBackend();
|
|
1151
1170
|
}
|
|
1152
1171
|
cleanupCameraResources() {
|
|
1172
|
+
const lease = this.cameraLease;
|
|
1173
|
+
this.cameraLease = null;
|
|
1153
1174
|
const video = this.webcam?.webcam;
|
|
1154
|
-
if (
|
|
1175
|
+
if (lease) lease.release();
|
|
1176
|
+
else if (video?.srcObject) {
|
|
1155
1177
|
video.srcObject.getTracks().forEach((track) => track.stop());
|
|
1156
1178
|
video.srcObject = null;
|
|
1157
1179
|
}
|
|
@@ -1184,11 +1206,16 @@
|
|
|
1184
1206
|
if (!runtime) throw new Error("Teachable Machine: Runtime is unavailable.");
|
|
1185
1207
|
if (!("Webcam" in runtime)) throw new Error("Teachable Machine: Camera runtime is unavailable in the current mode.");
|
|
1186
1208
|
this.webcam = new runtime.Webcam(320, 240, true);
|
|
1187
|
-
const
|
|
1209
|
+
const lease = await this.acquireSharedCamera();
|
|
1210
|
+
if (lease) {
|
|
1211
|
+
this.cameraLease = lease;
|
|
1212
|
+
this.webcam.webcam = lease.getFrameSource().element;
|
|
1213
|
+
}
|
|
1214
|
+
const constraints = lease ? void 0 : cameraConstraints(this.resolvedCameraSelection());
|
|
1188
1215
|
if (constraints) await this.webcam.setup(constraints);
|
|
1189
1216
|
else await this.webcam.setup();
|
|
1190
1217
|
initializeCameraReadbackContext(this.webcam.canvas);
|
|
1191
|
-
await this.webcam.play();
|
|
1218
|
+
if (!lease) await this.webcam.play();
|
|
1192
1219
|
this.attachPreviewToStage();
|
|
1193
1220
|
this.cameraRunning = true;
|
|
1194
1221
|
try {
|
|
@@ -1203,6 +1230,29 @@
|
|
|
1203
1230
|
throw error;
|
|
1204
1231
|
}
|
|
1205
1232
|
}
|
|
1233
|
+
/**
|
|
1234
|
+
* A lease on the shared camera, or null when Camera Source is not loaded.
|
|
1235
|
+
*
|
|
1236
|
+
* Camera Source owns the device and decides when a stream stops, which is what lets one camera
|
|
1237
|
+
* serve pose recognition and anything else reading frames at the same time. It is a separate
|
|
1238
|
+
* TurboWarp extension, and this one is also distributed for standalone URL loading, so its
|
|
1239
|
+
* absence is ordinary rather than a failure: the self-acquired path stays for it.
|
|
1240
|
+
*
|
|
1241
|
+
* One camera id for every visual recognition mode. Opening a second device for a work that
|
|
1242
|
+
* recognises both poses and images is not what sharing is for, and `pose` is the role name
|
|
1243
|
+
* Camera Source's own documentation uses for this consumer.
|
|
1244
|
+
*/
|
|
1245
|
+
async acquireSharedCamera() {
|
|
1246
|
+
const cameraSource = readCameraSource(Scratch.vm?.runtime);
|
|
1247
|
+
if (!cameraSource) return null;
|
|
1248
|
+
const selection = this.resolvedCameraSelection();
|
|
1249
|
+
const options = {
|
|
1250
|
+
owner: package_default.name,
|
|
1251
|
+
cameraId: "pose"
|
|
1252
|
+
};
|
|
1253
|
+
if (selection.kind === "device") options.deviceId = selection.value;
|
|
1254
|
+
return cameraSource.acquireCamera(options);
|
|
1255
|
+
}
|
|
1206
1256
|
stopCamera() {
|
|
1207
1257
|
try {
|
|
1208
1258
|
this.stopRecognition();
|
|
@@ -152,6 +152,19 @@ export declare class TMExtension {
|
|
|
152
152
|
ensureLibrariesLoaded(): Promise<void>;
|
|
153
153
|
cleanupCameraResources(): void;
|
|
154
154
|
startCamera(): Promise<void>;
|
|
155
|
+
/**
|
|
156
|
+
* A lease on the shared camera, or null when Camera Source is not loaded.
|
|
157
|
+
*
|
|
158
|
+
* Camera Source owns the device and decides when a stream stops, which is what lets one camera
|
|
159
|
+
* serve pose recognition and anything else reading frames at the same time. It is a separate
|
|
160
|
+
* TurboWarp extension, and this one is also distributed for standalone URL loading, so its
|
|
161
|
+
* absence is ordinary rather than a failure: the self-acquired path stays for it.
|
|
162
|
+
*
|
|
163
|
+
* One camera id for every visual recognition mode. Opening a second device for a work that
|
|
164
|
+
* recognises both poses and images is not what sharing is for, and `pose` is the role name
|
|
165
|
+
* Camera Source's own documentation uses for this consumer.
|
|
166
|
+
*/
|
|
167
|
+
private acquireSharedCamera;
|
|
155
168
|
stopCamera(): void;
|
|
156
169
|
isCameraRunning(): any;
|
|
157
170
|
getCameraMenuItems(): {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubohiroya/turbowarp-teachable-machine",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.0",
|
|
4
4
|
"description": "A TurboWarp extension for recognition using Teachable Machine pose, image, and audio models.",
|
|
5
5
|
"author": "Hiroya Kubo <hiroya@cuc.ac.jp>",
|
|
6
6
|
"license": "MPL-2.0",
|
|
@@ -72,6 +72,7 @@
|
|
|
72
72
|
"prepack": "npm run build && npm run release:consistency:check"
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
|
+
"@kubohiroya/turbowarp-camera-source": "0.13.0",
|
|
75
76
|
"@kubohiroya/vite-plugin-turbowarp-extension": "0.4.0",
|
|
76
77
|
"@teachablemachine/image": "0.8.5",
|
|
77
78
|
"@teachablemachine/pose": "0.8.6",
|