start shared camera
Requests camera permission and starts or keeps a named MediaStream such as `pose` or `qr`.
TurboWarp capability extension
TurboWarp-Camera-Source owns `navigator.mediaDevices.getUserMedia()` and shares live frame sources by role name, so TM can use a horizontal camera while jsQR or image recognition uses a downward camera.
Requests camera permission and starts or keeps a named MediaStream such as `pose` or `qr`.
Controls the opt-in GPU-backed stage preview. Repeated show calls keep one block-owned lease per camera.
Updates the browser camera list so projects can bind role names to device IDs.
Reports whether a named stream is active. The device-ID reporter identifies the selected physical camera when available.
Reports the latest failure code and message for each named camera, and clears them after a successful start.
Reports the delivered width, height, and track frame rate. Unavailable values and stopped cameras report zero.
Unsandboxed extensions can read `Scratch.vm.runtime.ext_kubohiroyacamerasource`.
const poseLease = await cameraSource.acquireCamera({
owner: 'tm',
cameraId: 'pose',
deviceId: poseDeviceId
});
const qrLease = await cameraSource.acquireCamera({
owner: 'jsqr',
cameraId: 'qr',
deviceId: qrDeviceId
});
const previewLease = await cameraSource.acquireCamera({
owner: 'camera-preview',
cameraId: 'pose',
preview: true,
mirrored: true
});
const frame = qrLease.getFrameSource();
// frame.element is an HTMLVideoElement.
await qrLease.release();
await previewLease.release();
await poseLease.release();
Each named stream remains active until its last lease is released. Consumers that use the same `cameraId` share one physical camera; different IDs can run separate cameras.
preview: true enables the dedicated GPU-backed stage preview for that lease. It sends the shared video element to texImage2D(video) without drawImage(), getImageData(), or CPU pixel scanning. Mirroring changes only the drawable scale, leaving frame.element unmodified for WebGPU, WebCodecs, and vision consumers.
The path avoids explicit CPU readback but does not guarantee browser-internal zero-copy. The browser may still perform color conversion or GPU transfer.
Block-owned previews are cleaned up when the named camera stops, the project stops or reloads, or the runtime is disposed.
Camera access requires user permission and a secure browser context such as HTTPS or localhost. Camera Source does not upload frames or store images.