@camera.ui/browser 0.0.118 → 0.0.120
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/index.d.ts +1 -0
- package/dist/index.js +189 -137
- package/package.json +10 -10
package/dist/index.d.ts
CHANGED
|
@@ -256,6 +256,7 @@ export declare interface CodecCompatibility {
|
|
|
256
256
|
export declare interface CoreManagerInterface {
|
|
257
257
|
getFFmpegPath(): Promise<string>;
|
|
258
258
|
getServerAddresses(): Promise<string[]>;
|
|
259
|
+
getCloudServerId(): Promise<string>;
|
|
259
260
|
getPlugin(pluginName: string): Promise<PluginInfo | undefined>;
|
|
260
261
|
getPluginsByInterface(interfaceName: PluginInterface): Promise<PluginInfo[]>;
|
|
261
262
|
}
|
package/dist/index.js
CHANGED
|
@@ -3324,7 +3324,7 @@ var StreamManager = class {
|
|
|
3324
3324
|
videoElementRef,
|
|
3325
3325
|
cameraDeviceRef,
|
|
3326
3326
|
containerElementRef,
|
|
3327
|
-
consumerContainerRefs: new Set([containerElementRef]),
|
|
3327
|
+
consumerContainerRefs: /* @__PURE__ */ new Set([containerElementRef]),
|
|
3328
3328
|
sharedVideoElement,
|
|
3329
3329
|
mediaStream: null,
|
|
3330
3330
|
refCount: 1
|
|
@@ -3350,15 +3350,17 @@ var StreamManager = class {
|
|
|
3350
3350
|
entry.refCount--;
|
|
3351
3351
|
if (consumerContainerRef) {
|
|
3352
3352
|
entry.consumerContainerRefs.delete(consumerContainerRef);
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3353
|
+
const video = entry.sharedVideoElement;
|
|
3354
|
+
const releasingContainer = consumerContainerRef.value;
|
|
3355
|
+
const videoParent = video?.parentElement ?? null;
|
|
3356
|
+
if (entry.refCount > 0 && video && (videoParent === releasingContainer || videoParent === null || !videoParent.isConnected)) {
|
|
3357
|
+
const target = this.pickVisibleConsumer(entry, releasingContainer);
|
|
3358
|
+
if (target) {
|
|
3359
|
+
entry.containerElementRef = target.ref;
|
|
3360
|
+
if (video.parentElement !== target.el) {
|
|
3361
|
+
target.el.appendChild(video);
|
|
3362
|
+
video.play().catch(() => {});
|
|
3360
3363
|
}
|
|
3361
|
-
break;
|
|
3362
3364
|
}
|
|
3363
3365
|
}
|
|
3364
3366
|
}
|
|
@@ -3389,6 +3391,22 @@ var StreamManager = class {
|
|
|
3389
3391
|
resolution: entry.stream.activeResolution.value
|
|
3390
3392
|
}));
|
|
3391
3393
|
}
|
|
3394
|
+
pickVisibleConsumer(entry, excludeContainer) {
|
|
3395
|
+
let fallback;
|
|
3396
|
+
for (const ref of entry.consumerContainerRefs) {
|
|
3397
|
+
const el = ref.value;
|
|
3398
|
+
if (!el || el === excludeContainer || !el.isConnected) continue;
|
|
3399
|
+
if (el.checkVisibility?.() ?? el.offsetParent !== null) return {
|
|
3400
|
+
ref,
|
|
3401
|
+
el
|
|
3402
|
+
};
|
|
3403
|
+
fallback ??= {
|
|
3404
|
+
ref,
|
|
3405
|
+
el
|
|
3406
|
+
};
|
|
3407
|
+
}
|
|
3408
|
+
return fallback;
|
|
3409
|
+
}
|
|
3392
3410
|
cancelRelease(cameraName) {
|
|
3393
3411
|
const timer = this.releaseTimers.get(cameraName);
|
|
3394
3412
|
if (timer) {
|
|
@@ -3530,15 +3548,15 @@ function acquireAutoStaggerDelay() {
|
|
|
3530
3548
|
autoStaggerLastTouch = now;
|
|
3531
3549
|
return delay;
|
|
3532
3550
|
}
|
|
3551
|
+
function isElementVisible(el) {
|
|
3552
|
+
if (!el || !el.isConnected) return false;
|
|
3553
|
+
return el.checkVisibility?.() ?? el.offsetParent !== null;
|
|
3554
|
+
}
|
|
3533
3555
|
function useCameraStream(options) {
|
|
3534
3556
|
const { activityConfig, autoStart: autoStartOption = true, isolated = false } = options;
|
|
3535
3557
|
const shouldAutoStart = () => toValue(autoStartOption);
|
|
3536
3558
|
const startDelay = options.startDelay ?? acquireAutoStaggerDelay();
|
|
3537
|
-
const
|
|
3538
|
-
let startDelayTimer;
|
|
3539
|
-
if (startDelay > 0) startDelayTimer = setTimeout(() => {
|
|
3540
|
-
autoStartReady.value = true;
|
|
3541
|
-
}, startDelay);
|
|
3559
|
+
const cleanupFns = [];
|
|
3542
3560
|
const { isConnected } = useCameraUi();
|
|
3543
3561
|
const cameraGetter = computed(() => toValue(options.camera));
|
|
3544
3562
|
const isCameraString = computed(() => typeof cameraGetter.value === "string");
|
|
@@ -3551,21 +3569,54 @@ function useCameraStream(options) {
|
|
|
3551
3569
|
if (isCameraString.value) return cameraDeviceFromLookup.value;
|
|
3552
3570
|
return cameraGetter.value;
|
|
3553
3571
|
});
|
|
3572
|
+
let startDelayTimer;
|
|
3573
|
+
let ownedConnection;
|
|
3554
3574
|
const containerElement = shallowRef();
|
|
3555
3575
|
const fullscreenElement = shallowRef();
|
|
3556
3576
|
const videoElement = shallowRef();
|
|
3557
3577
|
const streamVideoElementRef = shallowRef();
|
|
3558
3578
|
const currentStream = shallowRef();
|
|
3579
|
+
const cameraDeviceRef = shallowRef();
|
|
3559
3580
|
const isUsingCachedStream = ref(false);
|
|
3560
3581
|
const initialized = ref(false);
|
|
3561
3582
|
const cleanedUp = ref(false);
|
|
3562
|
-
const
|
|
3583
|
+
const nativeWidth = ref(0);
|
|
3584
|
+
const nativeHeight = ref(0);
|
|
3585
|
+
const isPip = ref(false);
|
|
3586
|
+
const autoStartReady = ref(startDelay <= 0);
|
|
3587
|
+
if (startDelay > 0) startDelayTimer = setTimeout(() => {
|
|
3588
|
+
autoStartReady.value = true;
|
|
3589
|
+
}, startDelay);
|
|
3563
3590
|
watch(resolvedCameraDevice, (device) => {
|
|
3564
3591
|
cameraDeviceRef.value = device;
|
|
3565
3592
|
}, { immediate: true });
|
|
3566
3593
|
const isCameraDisabled = computed(() => cameraDeviceRef.value?.disabled.value === true);
|
|
3567
|
-
const
|
|
3568
|
-
|
|
3594
|
+
const status = computed(() => currentStream.value?.status.value ?? "idle");
|
|
3595
|
+
const isPlaying = computed(() => currentStream.value?.isPlaying.value ?? false);
|
|
3596
|
+
const activeMode = computed(() => currentStream.value?.activeMode.value ?? "webrtc");
|
|
3597
|
+
const activeResolution = computed(() => currentStream.value?.activeResolution.value ?? "low-resolution");
|
|
3598
|
+
const hasAudio = computed(() => currentStream.value?.hasAudio.value ?? false);
|
|
3599
|
+
const hasBackchannel = computed(() => currentStream.value?.hasBackchannel.value ?? false);
|
|
3600
|
+
const error = computed(() => currentStream.value?.error.value);
|
|
3601
|
+
const isReconnecting = computed(() => status.value === "reconnecting");
|
|
3602
|
+
const isBusy = computed(() => cameraDeviceLoading.value || !isPlaying.value && status.value !== "error");
|
|
3603
|
+
const hasSound = computed(() => hasAudio.value && status.value === "connected");
|
|
3604
|
+
const hasIntercom = computed(() => Boolean(typeof navigator !== "undefined" && navigator.mediaDevices) && hasBackchannel.value);
|
|
3605
|
+
const muted = computed(() => currentStream.value?.muted.value ?? true);
|
|
3606
|
+
const paused = computed(() => currentStream.value?.paused.value ?? false);
|
|
3607
|
+
const supportsPip = computed(() => typeof document !== "undefined" && document.pictureInPictureEnabled && !!videoElement.value);
|
|
3608
|
+
const renderElement = computed(() => videoElement.value);
|
|
3609
|
+
const fullscreenTarget = computed(() => fullscreenElement.value ?? containerElement.value);
|
|
3610
|
+
const activityModeManager = createActivityMode({
|
|
3611
|
+
initialMode: toValue(options.activityMode) ?? "always-on",
|
|
3612
|
+
config: activityConfig,
|
|
3613
|
+
onStreamStart: () => {
|
|
3614
|
+
if (!isCameraDisabled.value) currentStream.value?.start();
|
|
3615
|
+
},
|
|
3616
|
+
onStreamStop: () => currentStream.value?.stop(),
|
|
3617
|
+
isStreamPlaying: () => isPlaying.value
|
|
3618
|
+
});
|
|
3619
|
+
const { isFullscreen, toggle: toggleFullscreen } = useCuiFullscreen(fullscreenTarget);
|
|
3569
3620
|
function createOwnedStream() {
|
|
3570
3621
|
ownedConnection = createStreamConnection({
|
|
3571
3622
|
camera: cameraDeviceRef,
|
|
@@ -3596,117 +3647,24 @@ function useCameraStream(options) {
|
|
|
3596
3647
|
if (video.parentElement && video.parentElement !== container) video.parentElement.removeChild(video);
|
|
3597
3648
|
if (video.parentElement !== container) container.appendChild(video);
|
|
3598
3649
|
}
|
|
3599
|
-
|
|
3600
|
-
if (
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
const isBusy = computed(() => cameraDeviceLoading.value || !isPlaying.value && status.value !== "error");
|
|
3611
|
-
const hasSound = computed(() => hasAudio.value && status.value === "connected");
|
|
3612
|
-
const hasIntercom = computed(() => Boolean(typeof navigator !== "undefined" && navigator.mediaDevices) && hasBackchannel.value);
|
|
3613
|
-
const muted = computed(() => currentStream.value?.muted.value ?? true);
|
|
3614
|
-
const paused = computed(() => currentStream.value?.paused.value ?? false);
|
|
3615
|
-
const nativeWidth = ref(0);
|
|
3616
|
-
const nativeHeight = ref(0);
|
|
3617
|
-
const stopDimensionSync = watch([() => currentStream.value?.nativeWidth.value, () => currentStream.value?.nativeHeight.value], ([w, h]) => {
|
|
3618
|
-
if (w && w > 0) nativeWidth.value = w;
|
|
3619
|
-
if (h && h > 0) nativeHeight.value = h;
|
|
3620
|
-
});
|
|
3621
|
-
cleanupFns.push(stopDimensionSync);
|
|
3622
|
-
if (options.canvasStyle !== void 0 || options.canvasClass !== void 0) {
|
|
3623
|
-
let stopCanvasListener;
|
|
3624
|
-
function applyCanvasStyles(canvas) {
|
|
3625
|
-
const style = toValue(options.canvasStyle);
|
|
3626
|
-
const cls = toValue(options.canvasClass);
|
|
3627
|
-
if (style) if (typeof style === "string") canvas.style.cssText += ";" + style;
|
|
3628
|
-
else if (Array.isArray(style)) {
|
|
3629
|
-
for (const s of style) if (typeof s === "string") canvas.style.cssText += ";" + s;
|
|
3630
|
-
else if (s) Object.assign(canvas.style, s);
|
|
3631
|
-
} else Object.assign(canvas.style, style);
|
|
3632
|
-
if (cls) if (typeof cls === "string") canvas.className = cls;
|
|
3633
|
-
else if (Array.isArray(cls)) canvas.className = cls.filter(Boolean).join(" ");
|
|
3634
|
-
else for (const [name, active] of Object.entries(cls)) canvas.classList.toggle(name, !!active);
|
|
3635
|
-
}
|
|
3636
|
-
const stopContainerWatch = watch(containerElement, (container) => {
|
|
3637
|
-
stopCanvasListener?.();
|
|
3638
|
-
stopCanvasListener = void 0;
|
|
3639
|
-
if (!container) return;
|
|
3640
|
-
Array.from(container.querySelectorAll("canvas")).forEach((node) => {
|
|
3641
|
-
applyCanvasStyles(node);
|
|
3642
|
-
});
|
|
3643
|
-
const observer = new MutationObserver((records) => {
|
|
3644
|
-
for (const r of records) Array.from(r.addedNodes).forEach((added) => {
|
|
3645
|
-
if (added instanceof HTMLCanvasElement) applyCanvasStyles(added);
|
|
3646
|
-
else if (added instanceof HTMLElement) Array.from(added.querySelectorAll("canvas")).forEach((c) => applyCanvasStyles(c));
|
|
3647
|
-
});
|
|
3648
|
-
});
|
|
3649
|
-
observer.observe(container, {
|
|
3650
|
-
childList: true,
|
|
3651
|
-
subtree: true
|
|
3652
|
-
});
|
|
3653
|
-
stopCanvasListener = () => observer.disconnect();
|
|
3654
|
-
}, { immediate: true });
|
|
3655
|
-
cleanupFns.push(() => {
|
|
3656
|
-
stopContainerWatch();
|
|
3657
|
-
stopCanvasListener?.();
|
|
3658
|
-
});
|
|
3659
|
-
}
|
|
3660
|
-
if (options.videoStyle !== void 0 || options.videoClass !== void 0) {
|
|
3661
|
-
const stopVideoStyleWatch = watch([
|
|
3662
|
-
videoElement,
|
|
3663
|
-
() => toValue(options.videoStyle),
|
|
3664
|
-
() => toValue(options.videoClass)
|
|
3665
|
-
], ([video, style, cls]) => {
|
|
3666
|
-
if (!video) return;
|
|
3667
|
-
if (style) if (typeof style === "string") video.style.cssText += ";" + style;
|
|
3668
|
-
else if (Array.isArray(style)) {
|
|
3669
|
-
for (const s of style) if (typeof s === "string") video.style.cssText += ";" + s;
|
|
3670
|
-
else if (s) Object.assign(video.style, s);
|
|
3671
|
-
} else Object.assign(video.style, style);
|
|
3672
|
-
if (cls) if (typeof cls === "string") video.className = cls;
|
|
3673
|
-
else if (Array.isArray(cls)) video.className = cls.filter(Boolean).join(" ");
|
|
3674
|
-
else for (const [name, active] of Object.entries(cls)) video.classList.toggle(name, active);
|
|
3675
|
-
}, { immediate: true });
|
|
3676
|
-
cleanupFns.push(stopVideoStyleWatch);
|
|
3650
|
+
function reclaimSharedVideo() {
|
|
3651
|
+
if (isolated) return;
|
|
3652
|
+
const container = containerElement.value;
|
|
3653
|
+
const video = videoElement.value;
|
|
3654
|
+
if (!container || !video || video.parentElement === container) return;
|
|
3655
|
+
if (!isElementVisible(container) || isElementVisible(video.parentElement)) return;
|
|
3656
|
+
insertVideoIntoContainer(video, container);
|
|
3657
|
+
video.play().catch(() => {});
|
|
3658
|
+
const camName = cameraName.value;
|
|
3659
|
+
const entry = camName ? streamManager.get(camName) : void 0;
|
|
3660
|
+
if (entry) entry.containerElementRef = containerElement;
|
|
3677
3661
|
}
|
|
3678
|
-
const isPip = ref(false);
|
|
3679
|
-
const supportsPip = computed(() => typeof document !== "undefined" && document.pictureInPictureEnabled && !!videoElement.value);
|
|
3680
3662
|
function onEnterPip() {
|
|
3681
3663
|
isPip.value = true;
|
|
3682
3664
|
}
|
|
3683
3665
|
function onLeavePip() {
|
|
3684
3666
|
isPip.value = false;
|
|
3685
3667
|
}
|
|
3686
|
-
const stopPipWatch = watch(videoElement, (video, oldVideo) => {
|
|
3687
|
-
if (oldVideo) {
|
|
3688
|
-
oldVideo.removeEventListener("enterpictureinpicture", onEnterPip);
|
|
3689
|
-
oldVideo.removeEventListener("leavepictureinpicture", onLeavePip);
|
|
3690
|
-
}
|
|
3691
|
-
if (video) {
|
|
3692
|
-
video.addEventListener("enterpictureinpicture", onEnterPip);
|
|
3693
|
-
video.addEventListener("leavepictureinpicture", onLeavePip);
|
|
3694
|
-
}
|
|
3695
|
-
}, { immediate: true });
|
|
3696
|
-
cleanupFns.push(stopPipWatch);
|
|
3697
|
-
const { isFullscreen, toggle: toggleFullscreen } = useCuiFullscreen(computed(() => fullscreenElement.value ?? containerElement.value));
|
|
3698
|
-
const activityModeManager = createActivityMode({
|
|
3699
|
-
initialMode: toValue(options.activityMode) ?? "always-on",
|
|
3700
|
-
config: activityConfig,
|
|
3701
|
-
onStreamStart: () => {
|
|
3702
|
-
if (!isCameraDisabled.value) currentStream.value?.start();
|
|
3703
|
-
},
|
|
3704
|
-
onStreamStop: () => currentStream.value?.stop(),
|
|
3705
|
-
isStreamPlaying: () => isPlaying.value
|
|
3706
|
-
});
|
|
3707
|
-
watch(() => toValue(options.activityMode), (newMode) => {
|
|
3708
|
-
if (newMode && newMode !== activityModeManager.mode.value) activityModeManager.setMode(newMode);
|
|
3709
|
-
});
|
|
3710
3668
|
function initializeIsolated() {
|
|
3711
3669
|
if (initialized.value) return;
|
|
3712
3670
|
const container = containerElement.value;
|
|
@@ -3879,7 +3837,6 @@ function useCameraStream(options) {
|
|
|
3879
3837
|
if (document.pictureInPictureElement) document.exitPictureInPicture();
|
|
3880
3838
|
else if (document.pictureInPictureEnabled && videoElement.value) videoElement.value.requestPictureInPicture();
|
|
3881
3839
|
}
|
|
3882
|
-
const renderElement = computed(() => videoElement.value);
|
|
3883
3840
|
function captureScreenshot() {
|
|
3884
3841
|
const video = videoElement.value;
|
|
3885
3842
|
if (!video || video.videoWidth === 0) return null;
|
|
@@ -3889,20 +3846,6 @@ function useCameraStream(options) {
|
|
|
3889
3846
|
tmp.getContext("2d")?.drawImage(video, 0, 0);
|
|
3890
3847
|
return tmp.toDataURL("image/png");
|
|
3891
3848
|
}
|
|
3892
|
-
watch([
|
|
3893
|
-
containerElement,
|
|
3894
|
-
resolvedCameraDevice,
|
|
3895
|
-
isConnected,
|
|
3896
|
-
autoStartReady
|
|
3897
|
-
], () => {
|
|
3898
|
-
if (!initialized.value) initialize();
|
|
3899
|
-
else if (autoStartReady.value && shouldAutoStart() && !isPlaying.value && status.value === "idle" && !isCameraDisabled.value) currentStream.value?.start();
|
|
3900
|
-
}, { immediate: true });
|
|
3901
|
-
watch(isCameraDisabled, (disabled, wasDisabled) => {
|
|
3902
|
-
if (!initialized.value) return;
|
|
3903
|
-
if (!wasDisabled && disabled) currentStream.value?.stop();
|
|
3904
|
-
else if (wasDisabled && !disabled && shouldAutoStart()) currentStream.value?.restart();
|
|
3905
|
-
});
|
|
3906
3849
|
function cleanup() {
|
|
3907
3850
|
if (cleanedUp.value) return;
|
|
3908
3851
|
cleanedUp.value = true;
|
|
@@ -3923,6 +3866,114 @@ function useCameraStream(options) {
|
|
|
3923
3866
|
}
|
|
3924
3867
|
activityModeManager.dispose();
|
|
3925
3868
|
}
|
|
3869
|
+
function applyCanvasStyles(canvas) {
|
|
3870
|
+
const style = toValue(options.canvasStyle);
|
|
3871
|
+
const cls = toValue(options.canvasClass);
|
|
3872
|
+
if (style) if (typeof style === "string") canvas.style.cssText += ";" + style;
|
|
3873
|
+
else if (Array.isArray(style)) {
|
|
3874
|
+
for (const s of style) if (typeof s === "string") canvas.style.cssText += ";" + s;
|
|
3875
|
+
else if (s) Object.assign(canvas.style, s);
|
|
3876
|
+
} else Object.assign(canvas.style, style);
|
|
3877
|
+
if (cls) if (typeof cls === "string") canvas.className = cls;
|
|
3878
|
+
else if (Array.isArray(cls)) canvas.className = cls.filter(Boolean).join(" ");
|
|
3879
|
+
else for (const [name, active] of Object.entries(cls)) canvas.classList.toggle(name, !!active);
|
|
3880
|
+
}
|
|
3881
|
+
if (!isolated && typeof IntersectionObserver !== "undefined") {
|
|
3882
|
+
let visibilityObserver;
|
|
3883
|
+
const stopVisibilityWatch = watch(containerElement, (container) => {
|
|
3884
|
+
visibilityObserver?.disconnect();
|
|
3885
|
+
visibilityObserver = void 0;
|
|
3886
|
+
if (!container) return;
|
|
3887
|
+
visibilityObserver = new IntersectionObserver((entries) => {
|
|
3888
|
+
if (entries.some((e) => e.isIntersecting)) reclaimSharedVideo();
|
|
3889
|
+
});
|
|
3890
|
+
visibilityObserver.observe(container);
|
|
3891
|
+
}, { immediate: true });
|
|
3892
|
+
cleanupFns.push(() => {
|
|
3893
|
+
stopVisibilityWatch();
|
|
3894
|
+
visibilityObserver?.disconnect();
|
|
3895
|
+
});
|
|
3896
|
+
}
|
|
3897
|
+
if (options.canvasStyle !== void 0 || options.canvasClass !== void 0) {
|
|
3898
|
+
let stopCanvasListener;
|
|
3899
|
+
const stopContainerWatch = watch(containerElement, (container) => {
|
|
3900
|
+
stopCanvasListener?.();
|
|
3901
|
+
stopCanvasListener = void 0;
|
|
3902
|
+
if (!container) return;
|
|
3903
|
+
Array.from(container.querySelectorAll("canvas")).forEach((node) => {
|
|
3904
|
+
applyCanvasStyles(node);
|
|
3905
|
+
});
|
|
3906
|
+
const observer = new MutationObserver((records) => {
|
|
3907
|
+
for (const r of records) Array.from(r.addedNodes).forEach((added) => {
|
|
3908
|
+
if (added instanceof HTMLCanvasElement) applyCanvasStyles(added);
|
|
3909
|
+
else if (added instanceof HTMLElement) Array.from(added.querySelectorAll("canvas")).forEach((c) => applyCanvasStyles(c));
|
|
3910
|
+
});
|
|
3911
|
+
});
|
|
3912
|
+
observer.observe(container, {
|
|
3913
|
+
childList: true,
|
|
3914
|
+
subtree: true
|
|
3915
|
+
});
|
|
3916
|
+
stopCanvasListener = () => observer.disconnect();
|
|
3917
|
+
}, { immediate: true });
|
|
3918
|
+
cleanupFns.push(() => {
|
|
3919
|
+
stopContainerWatch();
|
|
3920
|
+
stopCanvasListener?.();
|
|
3921
|
+
});
|
|
3922
|
+
}
|
|
3923
|
+
if (options.videoStyle !== void 0 || options.videoClass !== void 0) {
|
|
3924
|
+
const stopVideoStyleWatch = watch([
|
|
3925
|
+
videoElement,
|
|
3926
|
+
() => toValue(options.videoStyle),
|
|
3927
|
+
() => toValue(options.videoClass)
|
|
3928
|
+
], ([video, style, cls]) => {
|
|
3929
|
+
if (!video) return;
|
|
3930
|
+
if (style) if (typeof style === "string") video.style.cssText += ";" + style;
|
|
3931
|
+
else if (Array.isArray(style)) {
|
|
3932
|
+
for (const s of style) if (typeof s === "string") video.style.cssText += ";" + s;
|
|
3933
|
+
else if (s) Object.assign(video.style, s);
|
|
3934
|
+
} else Object.assign(video.style, style);
|
|
3935
|
+
if (cls) if (typeof cls === "string") video.className = cls;
|
|
3936
|
+
else if (Array.isArray(cls)) video.className = cls.filter(Boolean).join(" ");
|
|
3937
|
+
else for (const [name, active] of Object.entries(cls)) video.classList.toggle(name, active);
|
|
3938
|
+
}, { immediate: true });
|
|
3939
|
+
cleanupFns.push(stopVideoStyleWatch);
|
|
3940
|
+
}
|
|
3941
|
+
const stopDimensionSync = watch([() => currentStream.value?.nativeWidth.value, () => currentStream.value?.nativeHeight.value], ([w, h]) => {
|
|
3942
|
+
if (w && w > 0) nativeWidth.value = w;
|
|
3943
|
+
if (h && h > 0) nativeHeight.value = h;
|
|
3944
|
+
});
|
|
3945
|
+
cleanupFns.push(stopDimensionSync);
|
|
3946
|
+
const stopPipWatch = watch(videoElement, (video, oldVideo) => {
|
|
3947
|
+
if (oldVideo) {
|
|
3948
|
+
oldVideo.removeEventListener("enterpictureinpicture", onEnterPip);
|
|
3949
|
+
oldVideo.removeEventListener("leavepictureinpicture", onLeavePip);
|
|
3950
|
+
}
|
|
3951
|
+
if (video) {
|
|
3952
|
+
video.addEventListener("enterpictureinpicture", onEnterPip);
|
|
3953
|
+
video.addEventListener("leavepictureinpicture", onLeavePip);
|
|
3954
|
+
}
|
|
3955
|
+
}, { immediate: true });
|
|
3956
|
+
cleanupFns.push(stopPipWatch);
|
|
3957
|
+
watch([containerElement, videoElement], ([container, video]) => {
|
|
3958
|
+
if (container && video) insertVideoIntoContainer(video, container);
|
|
3959
|
+
}, { immediate: true });
|
|
3960
|
+
watch(() => toValue(options.activityMode), (newMode) => {
|
|
3961
|
+
if (newMode && newMode !== activityModeManager.mode.value) activityModeManager.setMode(newMode);
|
|
3962
|
+
});
|
|
3963
|
+
watch([
|
|
3964
|
+
containerElement,
|
|
3965
|
+
resolvedCameraDevice,
|
|
3966
|
+
isConnected,
|
|
3967
|
+
autoStartReady
|
|
3968
|
+
], () => {
|
|
3969
|
+
if (!initialized.value) initialize();
|
|
3970
|
+
else if (autoStartReady.value && shouldAutoStart() && !isPlaying.value && status.value === "idle" && !isCameraDisabled.value) currentStream.value?.start();
|
|
3971
|
+
}, { immediate: true });
|
|
3972
|
+
watch(isCameraDisabled, (disabled, wasDisabled) => {
|
|
3973
|
+
if (!initialized.value) return;
|
|
3974
|
+
if (!wasDisabled && disabled) currentStream.value?.stop();
|
|
3975
|
+
else if (wasDisabled && !disabled && shouldAutoStart()) currentStream.value?.restart();
|
|
3976
|
+
});
|
|
3926
3977
|
onBeforeUnmount(cleanup);
|
|
3927
3978
|
tryOnScopeDispose(cleanup);
|
|
3928
3979
|
return {
|
|
@@ -3979,7 +4030,8 @@ function useCoreManager() {
|
|
|
3979
4030
|
return {
|
|
3980
4031
|
getFFmpegPath: () => rpcCall(ctx.rpc, (rpc) => proxy(rpc).getFFmpegPath()),
|
|
3981
4032
|
getServerAddresses: () => rpcCall(ctx.rpc, (rpc) => proxy(rpc).getServerAddresses()),
|
|
3982
|
-
getPluginsByInterface: (interfaceName) => rpcCall(ctx.rpc, (rpc) => proxy(rpc).getPluginsByInterface(interfaceName))
|
|
4033
|
+
getPluginsByInterface: (interfaceName) => rpcCall(ctx.rpc, (rpc) => proxy(rpc).getPluginsByInterface(interfaceName)),
|
|
4034
|
+
getCloudServerId: () => rpcCall(ctx.rpc, (rpc) => proxy(rpc).getCloudServerId())
|
|
3983
4035
|
};
|
|
3984
4036
|
}
|
|
3985
4037
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camera.ui/browser",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.120",
|
|
4
4
|
"description": "camera.ui browser client",
|
|
5
5
|
"author": "seydx (https://github.com/cameraui/clients)",
|
|
6
6
|
"type": "module",
|
|
@@ -30,14 +30,14 @@
|
|
|
30
30
|
},
|
|
31
31
|
"peerDependencies": {
|
|
32
32
|
"@camera.ui/rpc": ">=1.0.4",
|
|
33
|
-
"@camera.ui/sdk": ">=0.0.
|
|
33
|
+
"@camera.ui/sdk": ">=0.0.9",
|
|
34
34
|
"@camera.ui/transport": ">=0.0.1",
|
|
35
35
|
"@vueuse/core": ">=14.3.0",
|
|
36
|
-
"vue": ">=3.5.
|
|
36
|
+
"vue": ">=3.5.39"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@camera.ui/rpc": "^1.0.4",
|
|
40
|
-
"@camera.ui/sdk": "~0.0.
|
|
40
|
+
"@camera.ui/sdk": "~0.0.9",
|
|
41
41
|
"@camera.ui/transport": "file:../../packages/transport",
|
|
42
42
|
"@eneris/push-receiver": "^4.3.1",
|
|
43
43
|
"@microsoft/api-extractor": "^7.58.9",
|
|
@@ -50,19 +50,19 @@
|
|
|
50
50
|
"@vue/language-core": "^3.3.5",
|
|
51
51
|
"@vue/tsconfig": "^0.9.1",
|
|
52
52
|
"@vueuse/core": "^14.3.0",
|
|
53
|
-
"@webgpu/types": "^0.1.
|
|
53
|
+
"@webgpu/types": "^0.1.71",
|
|
54
54
|
"eslint": "9.39.2",
|
|
55
55
|
"eslint-plugin-vue": "^10.9.2",
|
|
56
56
|
"globals": "^17.7.0",
|
|
57
|
-
"prettier": "^3.
|
|
57
|
+
"prettier": "^3.9.1",
|
|
58
58
|
"rimraf": "^6.1.3",
|
|
59
59
|
"typescript": "5.9.3",
|
|
60
60
|
"typescript-eslint": "^8.62.0",
|
|
61
|
-
"unplugin-dts": "^1.0.
|
|
62
|
-
"updates": "^17.18.
|
|
63
|
-
"vite": "^8.0
|
|
61
|
+
"unplugin-dts": "^1.0.3",
|
|
62
|
+
"updates": "^17.18.1",
|
|
63
|
+
"vite": "^8.1.0",
|
|
64
64
|
"vitest": "^4.1.9",
|
|
65
|
-
"vue": "^3.5.
|
|
65
|
+
"vue": "^3.5.39",
|
|
66
66
|
"vue-tsc": "^3.3.5"
|
|
67
67
|
},
|
|
68
68
|
"overrides": {
|