@wix/legends-platform-sdk 1.27.0 → 1.29.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 +2 -2
- package/dist/cjs/components/ChromaKey/ChromaKey.js +25 -6
- package/dist/cjs/components/ChromaKey/ChromaKey.js.map +1 -1
- package/dist/cjs/components/ChromaKey/chroma-key.js +3 -1
- package/dist/cjs/components/ChromaKey/chroma-key.js.map +1 -1
- package/dist/cjs/conversation/types.js.map +1 -1
- package/dist/cjs/hooks/useConversation/livekit/useConversation.js +30 -16
- package/dist/cjs/hooks/useConversation/livekit/useConversation.js.map +1 -1
- package/dist/cjs/hooks/useConversation/livekit/utils/dataChannel.js +8 -1
- package/dist/cjs/hooks/useConversation/livekit/utils/dataChannel.js.map +1 -1
- package/dist/cjs/hooks/useConversationEvents/types.js.map +1 -1
- package/dist/cjs/hooks/usePictureInPicture/usePictureInPictureAuto.js +10 -9
- package/dist/cjs/hooks/usePictureInPicture/usePictureInPictureAuto.js.map +1 -1
- package/dist/esm/components/ChromaKey/ChromaKey.js +26 -5
- package/dist/esm/components/ChromaKey/ChromaKey.js.map +1 -1
- package/dist/esm/components/ChromaKey/chroma-key.js +3 -1
- package/dist/esm/components/ChromaKey/chroma-key.js.map +1 -1
- package/dist/esm/conversation/types.js.map +1 -1
- package/dist/esm/hooks/useConversation/livekit/useConversation.js +31 -17
- package/dist/esm/hooks/useConversation/livekit/useConversation.js.map +1 -1
- package/dist/esm/hooks/useConversation/livekit/utils/dataChannel.js +7 -1
- package/dist/esm/hooks/useConversation/livekit/utils/dataChannel.js.map +1 -1
- package/dist/esm/hooks/useConversationEvents/types.js.map +1 -1
- package/dist/esm/hooks/usePictureInPicture/usePictureInPictureAuto.js +10 -9
- package/dist/esm/hooks/usePictureInPicture/usePictureInPictureAuto.js.map +1 -1
- package/dist/types/components/ChromaKey/ChromaKey.d.ts +1 -0
- package/dist/types/components/ChromaKey/ChromaKey.d.ts.map +1 -1
- package/dist/types/components/ChromaKey/chroma-key.d.ts +1 -1
- package/dist/types/components/ChromaKey/chroma-key.d.ts.map +1 -1
- package/dist/types/conversation/types.d.ts +1 -1
- package/dist/types/conversation/types.d.ts.map +1 -1
- package/dist/types/hooks/useConversation/livekit/useConversation.d.ts.map +1 -1
- package/dist/types/hooks/useConversation/livekit/utils/dataChannel.d.ts +1 -0
- package/dist/types/hooks/useConversation/livekit/utils/dataChannel.d.ts.map +1 -1
- package/dist/types/hooks/useConversationEvents/types.d.ts +4 -0
- package/dist/types/hooks/useConversationEvents/types.d.ts.map +1 -1
- package/dist/types/hooks/usePictureInPicture/usePictureInPictureAuto.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["decodeDataPayload","data","JSON","parse","TextDecoder","decode","error","console","checkIsTurnDetectionData","checkIsInactivityWarningData","type","grace_period_sec","checkIsInactivityTimeoutData","
|
|
1
|
+
{"version":3,"names":["decodeDataPayload","data","JSON","parse","TextDecoder","decode","error","console","checkIsTurnDetectionData","checkIsInactivityWarningData","type","grace_period_sec","checkIsInactivityTimeoutData","checkIsBillingEndedMessage","topic","reason","checkIsCreditExhaustedMessage","checkIsConversationLimitReachedMessage"],"sources":["../../../../../../src/hooks/useConversation/livekit/utils/dataChannel.ts"],"sourcesContent":["import type {\n InactivityWarningData,\n InactivityTimeoutData,\n TurnDetectionData,\n} from '../types';\n\nexport function decodeDataPayload(data: Uint8Array): unknown {\n try {\n return JSON.parse(new TextDecoder().decode(data));\n } catch (error) {\n console.error('Failed to decode data received payload', error);\n return null;\n }\n}\n\nexport function checkIsTurnDetectionData(\n data: unknown,\n): data is TurnDetectionData {\n return (\n typeof data === 'object' &&\n data !== null &&\n 'participantKind' in data &&\n 'state' in data\n );\n}\n\nexport function checkIsInactivityWarningData(\n data: unknown,\n): data is InactivityWarningData {\n return (\n typeof data === 'object' &&\n data !== null &&\n 'type' in data &&\n (data as Record<string, unknown>).type === 'inactivity_warning' &&\n 'grace_period_sec' in data &&\n typeof (data as Record<string, unknown>).grace_period_sec === 'number'\n );\n}\n\nexport function checkIsInactivityTimeoutData(\n data: unknown,\n): data is InactivityTimeoutData {\n return (\n typeof data === 'object' &&\n data !== null &&\n 'type' in data &&\n (data as Record<string, unknown>).type === 'inactivity_timeout'\n );\n}\n\nfunction checkIsBillingEndedMessage(\n data: unknown,\n topic: string | undefined,\n reason: string,\n): boolean {\n return (\n topic === 'billing' &&\n typeof data === 'object' &&\n data !== null &&\n (data as Record<string, unknown>).type === 'ended' &&\n (data as Record<string, unknown>).reason === reason\n );\n}\n\nexport function checkIsCreditExhaustedMessage(\n data: unknown,\n topic: string | undefined,\n): boolean {\n return checkIsBillingEndedMessage(data, topic, 'insufficient_credit');\n}\n\nexport function checkIsConversationLimitReachedMessage(\n data: unknown,\n topic: string | undefined,\n): boolean {\n return checkIsBillingEndedMessage(data, topic, 'limit_reached');\n}\n"],"mappings":";;;;;;;;;AAMO,SAASA,iBAAiBA,CAACC,IAAgB,EAAW;EAC3D,IAAI;IACF,OAAOC,IAAI,CAACC,KAAK,CAAC,IAAIC,WAAW,CAAC,CAAC,CAACC,MAAM,CAACJ,IAAI,CAAC,CAAC;EACnD,CAAC,CAAC,OAAOK,KAAK,EAAE;IACdC,OAAO,CAACD,KAAK,CAAC,wCAAwC,EAAEA,KAAK,CAAC;IAC9D,OAAO,IAAI;EACb;AACF;AAEO,SAASE,wBAAwBA,CACtCP,IAAa,EACc;EAC3B,OACE,OAAOA,IAAI,KAAK,QAAQ,IACxBA,IAAI,KAAK,IAAI,IACb,iBAAiB,IAAIA,IAAI,IACzB,OAAO,IAAIA,IAAI;AAEnB;AAEO,SAASQ,4BAA4BA,CAC1CR,IAAa,EACkB;EAC/B,OACE,OAAOA,IAAI,KAAK,QAAQ,IACxBA,IAAI,KAAK,IAAI,IACb,MAAM,IAAIA,IAAI,IACbA,IAAI,CAA6BS,IAAI,KAAK,oBAAoB,IAC/D,kBAAkB,IAAIT,IAAI,IAC1B,OAAQA,IAAI,CAA6BU,gBAAgB,KAAK,QAAQ;AAE1E;AAEO,SAASC,4BAA4BA,CAC1CX,IAAa,EACkB;EAC/B,OACE,OAAOA,IAAI,KAAK,QAAQ,IACxBA,IAAI,KAAK,IAAI,IACb,MAAM,IAAIA,IAAI,IACbA,IAAI,CAA6BS,IAAI,KAAK,oBAAoB;AAEnE;AAEA,SAASG,0BAA0BA,CACjCZ,IAAa,EACba,KAAyB,EACzBC,MAAc,EACL;EACT,OACED,KAAK,KAAK,SAAS,IACnB,OAAOb,IAAI,KAAK,QAAQ,IACxBA,IAAI,KAAK,IAAI,IACZA,IAAI,CAA6BS,IAAI,KAAK,OAAO,IACjDT,IAAI,CAA6Bc,MAAM,KAAKA,MAAM;AAEvD;AAEO,SAASC,6BAA6BA,CAC3Cf,IAAa,EACba,KAAyB,EAChB;EACT,OAAOD,0BAA0B,CAACZ,IAAI,EAAEa,KAAK,EAAE,qBAAqB,CAAC;AACvE;AAEO,SAASG,sCAAsCA,CACpDhB,IAAa,EACba,KAAyB,EAChB;EACT,OAAOD,0BAA0B,CAACZ,IAAI,EAAEa,KAAK,EAAE,eAAe,CAAC;AACjE","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["../../../../src/hooks/useConversationEvents/types.tsx"],"sourcesContent":["import React from 'react';\nimport type { RemoteParticipant } from 'livekit-client';\n\nexport type UserSpeakStartPayload = {\n conversationId: string;\n};\n\nexport type TimeExceededPayload = {\n conversationId: string;\n limit: number;\n};\n\nexport type UserSpeakStopPayload = {\n conversationId: string;\n};\n\nexport type AgentSpeakStartPayload = {\n conversationId: string;\n};\n\nexport type AgentSpeakStopPayload = {\n conversationId: string;\n};\n\nexport type ResponseLatencyPayload = {\n conversationId: string;\n latencyMs: number;\n turnDetectionStrategy: string;\n sequence?: number;\n speechId?: string;\n};\n\nexport type ConversationTurnLatencyPayload = {\n conversationId: string;\n speechId?: string;\n sequence?: number;\n clientAcousticLatencyMs: number;\n rttMs?: number;\n jitterBufferDelayMs?: number;\n userPacketsLost?: number;\n agentPacketsLost?: number;\n};\n\nexport type InterruptPayload = {\n conversationId: string;\n};\n\nexport type CallStartedPayload = {\n conversationId: string;\n};\n\nexport type CallEndedPayload = {\n conversationId: string;\n};\n\nexport type UserSendMessagePayload = {\n conversationId: string;\n message: string;\n};\n\nexport type AgentJoinedPayload = {\n conversationId: string;\n participant: RemoteParticipant;\n};\n\nexport type AgentLeftPayload = {\n conversationId: string;\n participant?: RemoteParticipant;\n};\n\nexport type AgentVideoLoadedPayload = {\n videoRef: React.RefObject<HTMLVideoElement>;\n};\n\nexport type InactivityWarningPayload = {\n conversationId: string;\n gracePeriodSec: number;\n};\n\nexport type InactivityTimeoutPayload = {\n conversationId: string;\n};\n\nexport type CreditExhaustedPayload = {\n conversationId: string;\n};\n\nexport type ConversationEventMap = {\n userSpeakStart: UserSpeakStartPayload;\n userSpeakStop: UserSpeakStopPayload;\n agentSpeakStart: AgentSpeakStartPayload;\n agentSpeakStop: AgentSpeakStopPayload;\n responseLatency: ResponseLatencyPayload;\n conversationTurnLatency: ConversationTurnLatencyPayload;\n interrupt: InterruptPayload;\n callStarted: CallStartedPayload;\n callEnded: CallEndedPayload;\n userSendMessage: UserSendMessagePayload;\n agentJoined: AgentJoinedPayload;\n agentLeft: AgentLeftPayload;\n timeExceeded: TimeExceededPayload;\n agentVideoLoaded: AgentVideoLoadedPayload;\n inactivityWarning: InactivityWarningPayload;\n inactivityTimeout: InactivityTimeoutPayload;\n creditExhausted: CreditExhaustedPayload;\n};\n\nexport type ConversationEvent = keyof ConversationEventMap;\n\nexport type EventPayload<T extends ConversationEvent> = ConversationEventMap[T];\n"],"mappings":"","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sources":["../../../../src/hooks/useConversationEvents/types.tsx"],"sourcesContent":["import React from 'react';\nimport type { RemoteParticipant } from 'livekit-client';\n\nexport type UserSpeakStartPayload = {\n conversationId: string;\n};\n\nexport type TimeExceededPayload = {\n conversationId: string;\n limit: number;\n};\n\nexport type UserSpeakStopPayload = {\n conversationId: string;\n};\n\nexport type AgentSpeakStartPayload = {\n conversationId: string;\n};\n\nexport type AgentSpeakStopPayload = {\n conversationId: string;\n};\n\nexport type ResponseLatencyPayload = {\n conversationId: string;\n latencyMs: number;\n turnDetectionStrategy: string;\n sequence?: number;\n speechId?: string;\n};\n\nexport type ConversationTurnLatencyPayload = {\n conversationId: string;\n speechId?: string;\n sequence?: number;\n clientAcousticLatencyMs: number;\n rttMs?: number;\n jitterBufferDelayMs?: number;\n userPacketsLost?: number;\n agentPacketsLost?: number;\n};\n\nexport type InterruptPayload = {\n conversationId: string;\n};\n\nexport type CallStartedPayload = {\n conversationId: string;\n};\n\nexport type CallEndedPayload = {\n conversationId: string;\n};\n\nexport type UserSendMessagePayload = {\n conversationId: string;\n message: string;\n};\n\nexport type AgentJoinedPayload = {\n conversationId: string;\n participant: RemoteParticipant;\n};\n\nexport type AgentLeftPayload = {\n conversationId: string;\n participant?: RemoteParticipant;\n};\n\nexport type AgentVideoLoadedPayload = {\n videoRef: React.RefObject<HTMLVideoElement>;\n};\n\nexport type InactivityWarningPayload = {\n conversationId: string;\n gracePeriodSec: number;\n};\n\nexport type InactivityTimeoutPayload = {\n conversationId: string;\n};\n\nexport type CreditExhaustedPayload = {\n conversationId: string;\n};\n\nexport type ConversationLimitReachedPayload = {\n conversationId: string;\n};\n\nexport type ConversationEventMap = {\n userSpeakStart: UserSpeakStartPayload;\n userSpeakStop: UserSpeakStopPayload;\n agentSpeakStart: AgentSpeakStartPayload;\n agentSpeakStop: AgentSpeakStopPayload;\n responseLatency: ResponseLatencyPayload;\n conversationTurnLatency: ConversationTurnLatencyPayload;\n interrupt: InterruptPayload;\n callStarted: CallStartedPayload;\n callEnded: CallEndedPayload;\n userSendMessage: UserSendMessagePayload;\n agentJoined: AgentJoinedPayload;\n agentLeft: AgentLeftPayload;\n timeExceeded: TimeExceededPayload;\n agentVideoLoaded: AgentVideoLoadedPayload;\n inactivityWarning: InactivityWarningPayload;\n inactivityTimeout: InactivityTimeoutPayload;\n creditExhausted: CreditExhaustedPayload;\n conversationLimitReached: ConversationLimitReachedPayload;\n};\n\nexport type ConversationEvent = keyof ConversationEventMap;\n\nexport type EventPayload<T extends ConversationEvent> = ConversationEventMap[T];\n"],"mappings":"","ignoreList":[]}
|
|
@@ -19,6 +19,7 @@ function usePictureInPictureAuto(options) {
|
|
|
19
19
|
const setIsActive = (0, _jotai.useSetAtom)(_state.pipActiveAtom);
|
|
20
20
|
const isSupported = (0, _jotai.useAtomValue)(_state.pipSupportedAtom);
|
|
21
21
|
const canvasVideoRef = (0, _react.useRef)(null);
|
|
22
|
+
const ownsPiPVideo = !!element && isSupported && pipVideo === (canvasVideoRef.current ?? element);
|
|
22
23
|
const callbacksRef = (0, _reactUse.useLatest)({
|
|
23
24
|
onEnter,
|
|
24
25
|
onExit,
|
|
@@ -26,7 +27,6 @@ function usePictureInPictureAuto(options) {
|
|
|
26
27
|
});
|
|
27
28
|
(0, _react.useEffect)(() => {
|
|
28
29
|
if (!element || !isSupported) {
|
|
29
|
-
setPipVideo(null);
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
32
32
|
let video;
|
|
@@ -43,11 +43,11 @@ function usePictureInPictureAuto(options) {
|
|
|
43
43
|
destroyCanvasVideo(canvasVideoRef.current);
|
|
44
44
|
canvasVideoRef.current = null;
|
|
45
45
|
}
|
|
46
|
-
setPipVideo(null);
|
|
46
|
+
setPipVideo(current => current === video ? null : current);
|
|
47
47
|
};
|
|
48
48
|
}, [element, isSupported, setPipVideo]);
|
|
49
49
|
(0, _react.useEffect)(() => {
|
|
50
|
-
if (!pipVideo) {
|
|
50
|
+
if (!pipVideo || !ownsPiPVideo) {
|
|
51
51
|
return;
|
|
52
52
|
}
|
|
53
53
|
const handleEnter = () => {
|
|
@@ -64,9 +64,9 @@ function usePictureInPictureAuto(options) {
|
|
|
64
64
|
pipVideo.removeEventListener('enterpictureinpicture', handleEnter);
|
|
65
65
|
pipVideo.removeEventListener('leavepictureinpicture', handleLeave);
|
|
66
66
|
};
|
|
67
|
-
}, [pipVideo, setIsActive]);
|
|
67
|
+
}, [pipVideo, ownsPiPVideo, setIsActive]);
|
|
68
68
|
(0, _react.useEffect)(() => {
|
|
69
|
-
if (!pipVideo || !
|
|
69
|
+
if (!pipVideo || !ownsPiPVideo) {
|
|
70
70
|
return;
|
|
71
71
|
}
|
|
72
72
|
try {
|
|
@@ -86,17 +86,18 @@ function usePictureInPictureAuto(options) {
|
|
|
86
86
|
navigator.mediaSession.setActionHandler('enterpictureinpicture', null);
|
|
87
87
|
} catch {}
|
|
88
88
|
};
|
|
89
|
-
}, [pipVideo,
|
|
89
|
+
}, [pipVideo, ownsPiPVideo]);
|
|
90
90
|
(0, _react.useEffect)(() => {
|
|
91
|
-
if (!element) {
|
|
91
|
+
if (!element || !isSupported) {
|
|
92
92
|
return;
|
|
93
93
|
}
|
|
94
|
+
const ownedVideo = canvasVideoRef.current ?? element;
|
|
94
95
|
return () => {
|
|
95
|
-
if (document.pictureInPictureElement) {
|
|
96
|
+
if (document.pictureInPictureElement === ownedVideo) {
|
|
96
97
|
document.exitPictureInPicture().catch(() => {});
|
|
97
98
|
}
|
|
98
99
|
};
|
|
99
|
-
}, [element]);
|
|
100
|
+
}, [element, isSupported]);
|
|
100
101
|
}
|
|
101
102
|
function createVideoFromCanvas(canvas) {
|
|
102
103
|
const video = document.createElement('video');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_react","require","_reactUse","_jotai","_state","usePictureInPictureAuto","options","element","onEnter","onExit","onError","pipVideo","setPipVideo","useAtom","pipVideoAtom","setIsActive","useSetAtom","pipActiveAtom","isSupported","useAtomValue","pipSupportedAtom","canvasVideoRef","useRef","callbacksRef","useLatest","useEffect","video","HTMLCanvasElement","createVideoFromCanvas","
|
|
1
|
+
{"version":3,"names":["_react","require","_reactUse","_jotai","_state","usePictureInPictureAuto","options","element","onEnter","onExit","onError","pipVideo","setPipVideo","useAtom","pipVideoAtom","setIsActive","useSetAtom","pipActiveAtom","isSupported","useAtomValue","pipSupportedAtom","canvasVideoRef","useRef","ownsPiPVideo","current","callbacksRef","useLatest","useEffect","video","HTMLCanvasElement","createVideoFromCanvas","setAttribute","destroyCanvasVideo","handleEnter","handleLeave","addEventListener","removeEventListener","navigator","mediaSession","setActionHandler","paused","srcObject","play","requestPictureInPicture","error","ownedVideo","document","pictureInPictureElement","exitPictureInPicture","catch","canvas","createElement","muted","playsInline","autoplay","captureStream","stream","getTracks","forEach","track","stop"],"sources":["../../../../src/hooks/usePictureInPicture/usePictureInPictureAuto.ts"],"sourcesContent":["/* eslint-disable no-undef */\nimport { useEffect, useRef } from 'react';\nimport { useLatest } from 'react-use';\nimport { useAtom, useAtomValue, useSetAtom } from 'jotai';\n\nimport { pipVideoAtom, pipActiveAtom, pipSupportedAtom } from './state';\nimport type { UsePictureInPictureAutoOptions } from './types';\n\nexport function usePictureInPictureAuto(\n options: UsePictureInPictureAutoOptions,\n) {\n const { element, onEnter, onExit, onError } = options;\n\n const [pipVideo, setPipVideo] = useAtom(pipVideoAtom);\n const setIsActive = useSetAtom(pipActiveAtom);\n const isSupported = useAtomValue(pipSupportedAtom);\n\n const canvasVideoRef = useRef<HTMLVideoElement | null>(null);\n const ownsPiPVideo =\n !!element &&\n isSupported &&\n pipVideo === (canvasVideoRef.current ?? element);\n\n const callbacksRef = useLatest({ onEnter, onExit, onError });\n\n useEffect(() => {\n if (!element || !isSupported) {\n return;\n }\n\n let video: HTMLVideoElement;\n\n if (element instanceof HTMLCanvasElement) {\n video = createVideoFromCanvas(element);\n canvasVideoRef.current = video;\n } else {\n video = element;\n }\n\n video.setAttribute('autopictureinpicture', 'true');\n setPipVideo(video);\n\n return () => {\n if (canvasVideoRef.current) {\n destroyCanvasVideo(canvasVideoRef.current);\n canvasVideoRef.current = null;\n }\n setPipVideo((current) => (current === video ? null : current));\n };\n }, [element, isSupported, setPipVideo]);\n\n useEffect(() => {\n if (!pipVideo || !ownsPiPVideo) {\n return;\n }\n\n const handleEnter = () => {\n setIsActive(true);\n callbacksRef.current.onEnter?.();\n };\n\n const handleLeave = () => {\n setIsActive(false);\n callbacksRef.current.onExit?.();\n };\n\n pipVideo.addEventListener('enterpictureinpicture', handleEnter);\n pipVideo.addEventListener('leavepictureinpicture', handleLeave);\n\n return () => {\n pipVideo.removeEventListener('enterpictureinpicture', handleEnter);\n pipVideo.removeEventListener('leavepictureinpicture', handleLeave);\n };\n }, [pipVideo, ownsPiPVideo, setIsActive]);\n\n useEffect(() => {\n if (!pipVideo || !ownsPiPVideo) {\n return;\n }\n\n try {\n navigator.mediaSession.setActionHandler(\n 'enterpictureinpicture' as MediaSessionAction,\n async () => {\n try {\n if (pipVideo.paused && pipVideo.srcObject) {\n await pipVideo.play();\n }\n await pipVideo.requestPictureInPicture();\n } catch (error) {\n callbacksRef.current.onError?.(error as Error);\n }\n },\n );\n } catch {}\n\n return () => {\n try {\n navigator.mediaSession.setActionHandler(\n 'enterpictureinpicture' as MediaSessionAction,\n null,\n );\n } catch {}\n };\n }, [pipVideo, ownsPiPVideo]);\n\n useEffect(() => {\n if (!element || !isSupported) {\n return;\n }\n const ownedVideo = canvasVideoRef.current ?? element;\n\n return () => {\n if (document.pictureInPictureElement === ownedVideo) {\n document.exitPictureInPicture().catch(() => {});\n }\n };\n }, [element, isSupported]);\n}\n\nfunction createVideoFromCanvas(canvas: HTMLCanvasElement): HTMLVideoElement {\n const video = document.createElement('video');\n video.muted = true;\n video.playsInline = true;\n video.autoplay = true;\n video.srcObject = canvas.captureStream(30);\n return video;\n}\n\nfunction destroyCanvasVideo(video: HTMLVideoElement) {\n if (video.srcObject) {\n const stream = video.srcObject as MediaStream;\n stream.getTracks().forEach((track) => track.stop());\n video.srcObject = null;\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose";
|
|
2
|
-
const _excluded = ["className", "style", "width", "height", "pip", "onPiPEnter", "onPiPExit", "onPiPError"];
|
|
2
|
+
const _excluded = ["className", "style", "width", "height", "pip", "pipFallback", "onPiPEnter", "onPiPExit", "onPiPError"];
|
|
3
3
|
import React, { useEffect, useRef, useState } from 'react';
|
|
4
4
|
import { chromaKey } from './chroma-key';
|
|
5
5
|
import { pipActiveAtom, usePictureInPictureAuto } from '../../hooks/usePictureInPicture';
|
|
@@ -24,6 +24,7 @@ export function ChromaKey(props) {
|
|
|
24
24
|
width = _children$props.width,
|
|
25
25
|
height = _children$props.height,
|
|
26
26
|
pip = _children$props.pip,
|
|
27
|
+
pipFallback = _children$props.pipFallback,
|
|
27
28
|
onPiPEnter = _children$props.onPiPEnter,
|
|
28
29
|
onPiPExit = _children$props.onPiPExit,
|
|
29
30
|
onPiPError = _children$props.onPiPError,
|
|
@@ -31,13 +32,18 @@ export function ChromaKey(props) {
|
|
|
31
32
|
const _useState = useState(false),
|
|
32
33
|
isPlayable = _useState[0],
|
|
33
34
|
setIsPlayable = _useState[1];
|
|
35
|
+
const _useState2 = useState(null),
|
|
36
|
+
isWebGLAvailable = _useState2[0],
|
|
37
|
+
setIsWebGLAvailable = _useState2[1];
|
|
34
38
|
const $video = useRef(null);
|
|
35
39
|
const $canvas = useRef(null);
|
|
36
40
|
const isPiPActive = useAtomValue(pipActiveAtom);
|
|
41
|
+
const useVideoFallback = isWebGLAvailable === false;
|
|
42
|
+
const pipElement = isWebGLAvailable === null ? null : useVideoFallback ? $video.current : $canvas.current;
|
|
37
43
|
|
|
38
44
|
// Setup PiP - hook handles canvas → video conversion internally
|
|
39
45
|
usePictureInPictureAuto({
|
|
40
|
-
element: pip && isPlayable ?
|
|
46
|
+
element: pip && isPlayable ? pipElement : null,
|
|
41
47
|
onEnter: onPiPEnter,
|
|
42
48
|
onExit: onPiPExit,
|
|
43
49
|
onError: onPiPError
|
|
@@ -55,6 +61,10 @@ export function ChromaKey(props) {
|
|
|
55
61
|
smoothness,
|
|
56
62
|
background
|
|
57
63
|
});
|
|
64
|
+
setIsWebGLAvailable(process !== null);
|
|
65
|
+
if (!process) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
58
68
|
debug && console.log('Chroma key initialized', $video.current, $canvas.current, {
|
|
59
69
|
color,
|
|
60
70
|
spill,
|
|
@@ -89,7 +99,7 @@ export function ChromaKey(props) {
|
|
|
89
99
|
style: {
|
|
90
100
|
width: '100%',
|
|
91
101
|
height: '100%',
|
|
92
|
-
display: showPipFallback ? 'none' : 'block',
|
|
102
|
+
display: useVideoFallback || showPipFallback ? 'none' : 'block',
|
|
93
103
|
...(isPlayable ? {} : {
|
|
94
104
|
position: 'absolute',
|
|
95
105
|
opacity: 0,
|
|
@@ -98,10 +108,21 @@ export function ChromaKey(props) {
|
|
|
98
108
|
zIndex: -1
|
|
99
109
|
})
|
|
100
110
|
}
|
|
101
|
-
}), !isPlayable && fallback, /*#__PURE__*/React.cloneElement(children, {
|
|
111
|
+
}), !isPlayable && fallback, showPipFallback && pipFallback, /*#__PURE__*/React.cloneElement(children, {
|
|
102
112
|
...restVideoProps,
|
|
113
|
+
// cloneElement retains original props; only ChromaKey should own PiP.
|
|
114
|
+
pip: false,
|
|
115
|
+
pipFallback: undefined,
|
|
116
|
+
onPiPEnter: undefined,
|
|
117
|
+
onPiPExit: undefined,
|
|
118
|
+
onPiPError: undefined,
|
|
103
119
|
ref: $video,
|
|
104
|
-
style: {
|
|
120
|
+
style: useVideoFallback ? {
|
|
121
|
+
width: '100%',
|
|
122
|
+
height: '100%',
|
|
123
|
+
...style,
|
|
124
|
+
display: isPlayable && !showPipFallback ? style == null ? void 0 : style.display : 'none'
|
|
125
|
+
} : {
|
|
105
126
|
display: 'none'
|
|
106
127
|
},
|
|
107
128
|
onCanPlay: checkPlayable,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","useEffect","useRef","useState","chromaKey","pipActiveAtom","usePictureInPictureAuto","useAtomValue","ChromaKey","props","_props$debug","debug","children","_props$color","color","_props$spill","spill","_props$smoothness","smoothness","_props$similarity","similarity","fallback","background","_children$props","className","style","width","height","pip","onPiPEnter","onPiPExit","onPiPError","restVideoProps","_objectWithoutPropertiesLoose","_excluded","_useState","isPlayable","setIsPlayable","$video","$canvas","isPiPActive","
|
|
1
|
+
{"version":3,"names":["React","useEffect","useRef","useState","chromaKey","pipActiveAtom","usePictureInPictureAuto","useAtomValue","ChromaKey","props","_props$debug","debug","children","_props$color","color","_props$spill","spill","_props$smoothness","smoothness","_props$similarity","similarity","fallback","background","_children$props","className","style","width","height","pip","pipFallback","onPiPEnter","onPiPExit","onPiPError","restVideoProps","_objectWithoutPropertiesLoose","_excluded","_useState","isPlayable","setIsPlayable","_useState2","isWebGLAvailable","setIsWebGLAvailable","$video","$canvas","isPiPActive","useVideoFallback","pipElement","current","element","onEnter","onExit","onError","showPipFallback","console","warn","process","log","rafId","isActive","loop","requestAnimationFrame","cancelAnimationFrame","createElement","ref","display","position","opacity","pointerEvents","visibility","zIndex","cloneElement","undefined","onCanPlay","checkPlayable","onLoadedMetadata","event","readyState","currentTarget","HTMLMediaElement","HAVE_FUTURE_DATA"],"sources":["../../../../src/components/ChromaKey/ChromaKey.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react';\n\nimport { chromaKey } from './chroma-key';\nimport {\n pipActiveAtom,\n usePictureInPictureAuto,\n} from '../../hooks/usePictureInPicture';\nimport { useAtomValue } from 'jotai';\n\ninterface ChromaKeyProps extends React.HTMLAttributes<HTMLCanvasElement> {\n debug?: boolean;\n color?: string;\n spill?: number;\n similarity?: number;\n smoothness?: number;\n fallback?: React.ReactNode;\n background?: string | null;\n children: React.ReactElement<\n React.VideoHTMLAttributes<HTMLVideoElement> & {\n ref?: React.Ref<HTMLVideoElement>;\n pip?: boolean;\n pipFallback?: React.ReactNode;\n onPiPEnter?: () => void;\n onPiPExit?: () => void;\n onPiPError?: (error: Error) => void;\n }\n >;\n}\n\nexport function ChromaKey(props: ChromaKeyProps) {\n const {\n debug = false,\n children,\n color = '#03ff9c',\n spill = 0.1,\n smoothness = 0.15,\n similarity = 0.3,\n fallback,\n background,\n } = props;\n\n const {\n className,\n style,\n width,\n height,\n pip,\n pipFallback,\n onPiPEnter,\n onPiPExit,\n onPiPError,\n ...restVideoProps\n } = children.props;\n const [isPlayable, setIsPlayable] = useState(false);\n const [isWebGLAvailable, setIsWebGLAvailable] = useState<boolean | null>(\n null,\n );\n\n const $video = useRef<HTMLVideoElement>(null);\n const $canvas = useRef<HTMLCanvasElement>(null);\n const isPiPActive = useAtomValue(pipActiveAtom);\n const useVideoFallback = isWebGLAvailable === false;\n const pipElement =\n isWebGLAvailable === null\n ? null\n : useVideoFallback\n ? $video.current\n : $canvas.current;\n\n // Setup PiP - hook handles canvas → video conversion internally\n usePictureInPictureAuto({\n element: pip && isPlayable ? pipElement : null,\n onEnter: onPiPEnter,\n onExit: onPiPExit,\n onError: onPiPError,\n });\n\n const showPipFallback = pip && isPiPActive;\n\n useEffect(() => {\n if (!$video.current || !$canvas.current || !isPlayable) {\n debug && console.warn('Video or canvas is not initialized');\n\n return;\n }\n\n const process = chromaKey($video.current, $canvas.current, {\n color,\n spill,\n similarity,\n smoothness,\n background,\n });\n setIsWebGLAvailable(process !== null);\n if (!process) {\n return;\n }\n\n debug &&\n console.log('Chroma key initialized', $video.current, $canvas.current, {\n color,\n spill,\n similarity,\n smoothness,\n });\n\n let rafId: number;\n let isActive = true;\n\n function loop() {\n if (!isActive) {\n return;\n }\n process?.();\n rafId = requestAnimationFrame(loop);\n }\n\n rafId = requestAnimationFrame(loop);\n\n return () => {\n debug && console.log('Chroma key process cleanup');\n isActive = false;\n cancelAnimationFrame(rafId);\n };\n }, [color, spill, similarity, smoothness, isPlayable, debug, background]);\n\n return (\n <div\n className={className}\n style={{\n ...style,\n width,\n height,\n }}\n >\n <canvas\n ref={$canvas}\n style={{\n width: '100%',\n height: '100%',\n display: useVideoFallback || showPipFallback ? 'none' : 'block',\n ...(isPlayable\n ? {}\n : {\n position: 'absolute',\n opacity: 0,\n pointerEvents: 'none',\n visibility: 'hidden',\n zIndex: -1,\n }),\n }}\n />\n {!isPlayable && fallback}\n {showPipFallback && pipFallback}\n\n {React.cloneElement(children, {\n ...restVideoProps,\n // cloneElement retains original props; only ChromaKey should own PiP.\n pip: false,\n pipFallback: undefined,\n onPiPEnter: undefined,\n onPiPExit: undefined,\n onPiPError: undefined,\n ref: $video,\n style: useVideoFallback\n ? {\n width: '100%',\n height: '100%',\n ...style,\n display: isPlayable && !showPipFallback ? style?.display : 'none',\n }\n : { display: 'none' },\n onCanPlay: checkPlayable,\n onLoadedMetadata: checkPlayable,\n })}\n </div>\n );\n\n function checkPlayable(event: React.SyntheticEvent<HTMLVideoElement>) {\n const readyState = event.currentTarget.readyState;\n\n setIsPlayable(readyState >= HTMLMediaElement.HAVE_FUTURE_DATA);\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -6,7 +6,9 @@ export function chromaKey($video, $canvas, options) {
|
|
|
6
6
|
premultipliedAlpha: false,
|
|
7
7
|
preserveDrawingBuffer: true
|
|
8
8
|
});
|
|
9
|
-
|
|
9
|
+
if (!gl) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
10
12
|
const BUFFER = gl.createBuffer();
|
|
11
13
|
const TEXTURE = gl.createTexture();
|
|
12
14
|
const program = gl.createProgram();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["invariant","shaders","chromaKey","$video","$canvas","options","gl","getContext","alpha","premultipliedAlpha","preserveDrawingBuffer","BUFFER","createBuffer","TEXTURE","createTexture","program","createProgram","_VS_","createShader","VERTEX_SHADER","_FS_","FRAGMENT_SHADER","shaderSource","VertexAlign","ChromaKey","compileShader","getShaderParameter","COMPILE_STATUS","console","error","getShaderInfoLog","attachShader","linkProgram","useProgram","bindTexture","TEXTURE_2D","bindBuffer","ARRAY_BUFFER","bufferData","Float32Array","STATIC_DRAW","texParameteri","TEXTURE_MIN_FILTER","LINEAR","TEXTURE_WRAP_S","CLAMP_TO_EDGE","TEXTURE_WRAP_T","$coords$","getAttribLocation","$texture$","getUniformLocation","$width$","$height$","$color$","$similarity$","$smoothness$","$spill$","vertexAttribPointer","FLOAT","enableVertexAttribArray","activeTexture","TEXTURE0","enable","BLEND","blendFunc","SRC_ALPHA","ONE_MINUS_SRC_ALPHA","process","color","spill","similarity","smoothness","background","videoWidth","videoHeight","width","window","devicePixelRatio","height","viewport","r","parseInt","substring","g","b","clearColor","clear","COLOR_BUFFER_BIT","uniform1i","uniform1f","uniform3f","substr","texImage2D","RGB","UNSIGNED_BYTE","drawArrays","TRIANGLE_FAN"],"sources":["../../../../src/components/ChromaKey/chroma-key.ts"],"sourcesContent":["import invariant from 'invariant';\n\nimport * as shaders from './shaders';\n\nexport type ProcessCallback = () => void;\n\nexport function chromaKey(\n $video: HTMLVideoElement,\n $canvas: HTMLCanvasElement,\n options: {\n color: string;\n spill: number;\n similarity: number;\n smoothness: number;\n background?: string | null;\n },\n): ProcessCallback {\n const gl = $canvas.getContext('webgl', {\n alpha: true,\n premultipliedAlpha: false,\n preserveDrawingBuffer: true,\n });\n\n invariant(gl, 'WebGL context is not initialized');\n\n const BUFFER = gl.createBuffer();\n const TEXTURE = gl.createTexture();\n const program = gl.createProgram();\n const _VS_ = gl.createShader(gl.VERTEX_SHADER);\n const _FS_ = gl.createShader(gl.FRAGMENT_SHADER);\n\n invariant(program, 'Program is not initialized');\n invariant(_VS_, 'Vertex shader is not initialized');\n invariant(_FS_, 'Fragment shader is not initialized');\n\n gl.shaderSource(_VS_, shaders.VertexAlign);\n gl.shaderSource(_FS_, shaders.ChromaKey);\n\n gl.compileShader(_VS_);\n gl.compileShader(_FS_);\n\n if (!gl.getShaderParameter(_FS_, gl.COMPILE_STATUS)) {\n console.error(\n 'Fragment shader compilation failed',\n gl.getShaderInfoLog(_FS_),\n );\n }\n\n gl.attachShader(program, _VS_);\n gl.attachShader(program, _FS_);\n\n gl.linkProgram(program);\n gl.useProgram(program);\n\n gl.bindTexture(gl.TEXTURE_2D, TEXTURE);\n gl.bindBuffer(gl.ARRAY_BUFFER, BUFFER);\n\n gl.bufferData(\n gl.ARRAY_BUFFER,\n new Float32Array([-1, 1, -1, -1, 1, -1, 1, 1]),\n gl.STATIC_DRAW,\n );\n\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n\n const $coords$ = gl.getAttribLocation(program, 'coords');\n const $texture$ = gl.getUniformLocation(program, 'tex');\n const $width$ = gl.getUniformLocation(program, 'texWidth');\n const $height$ = gl.getUniformLocation(program, 'texHeight');\n const $color$ = gl.getUniformLocation(program, 'keyColor');\n const $similarity$ = gl.getUniformLocation(program, 'similarity');\n const $smoothness$ = gl.getUniformLocation(program, 'smoothness');\n const $spill$ = gl.getUniformLocation(program, 'spill');\n\n gl.vertexAttribPointer($coords$, 2, gl.FLOAT, false, 0, 0);\n gl.enableVertexAttribArray($coords$);\n\n gl.activeTexture(gl.TEXTURE0);\n\n // Enable blending for transparency (critical for Safari)\n gl.enable(gl.BLEND);\n gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n\n return function process() {\n const { color, spill, similarity, smoothness, background } = options;\n\n // Use video dimensions directly instead of metadata (for Safari compatibility)\n const videoWidth = $video.videoWidth;\n const videoHeight = $video.videoHeight;\n\n if (!videoWidth || !videoHeight) {\n return; // Video not ready yet\n }\n\n const width = videoWidth * window.devicePixelRatio;\n const height = videoHeight * window.devicePixelRatio;\n\n $canvas.width = width;\n $canvas.height = height;\n\n gl.viewport(0, 0, width, height);\n\n // Clear with background color or transparent\n if (background) {\n const r = parseInt(background.substring(1, 3), 16) / 255;\n const g = parseInt(background.substring(3, 5), 16) / 255;\n const b = parseInt(background.substring(5, 7), 16) / 255;\n gl.clearColor(r, g, b, 1);\n } else {\n gl.clearColor(0, 0, 0, 0);\n }\n gl.clear(gl.COLOR_BUFFER_BIT);\n\n gl.useProgram(program);\n\n gl.uniform1i($texture$, 0);\n gl.uniform1f($width$, width);\n gl.uniform1f($height$, height);\n gl.uniform1f($spill$, spill);\n gl.uniform1f($similarity$, similarity);\n gl.uniform1f($smoothness$, smoothness);\n gl.uniform3f(\n $color$,\n parseInt(color.substr(1, 2), 16) / 255,\n parseInt(color.substr(3, 2), 16) / 255,\n parseInt(color.substr(5, 2), 16) / 255,\n );\n\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, $video);\n gl.drawArrays(gl.TRIANGLE_FAN, 0, 4);\n };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["invariant","shaders","chromaKey","$video","$canvas","options","gl","getContext","alpha","premultipliedAlpha","preserveDrawingBuffer","BUFFER","createBuffer","TEXTURE","createTexture","program","createProgram","_VS_","createShader","VERTEX_SHADER","_FS_","FRAGMENT_SHADER","shaderSource","VertexAlign","ChromaKey","compileShader","getShaderParameter","COMPILE_STATUS","console","error","getShaderInfoLog","attachShader","linkProgram","useProgram","bindTexture","TEXTURE_2D","bindBuffer","ARRAY_BUFFER","bufferData","Float32Array","STATIC_DRAW","texParameteri","TEXTURE_MIN_FILTER","LINEAR","TEXTURE_WRAP_S","CLAMP_TO_EDGE","TEXTURE_WRAP_T","$coords$","getAttribLocation","$texture$","getUniformLocation","$width$","$height$","$color$","$similarity$","$smoothness$","$spill$","vertexAttribPointer","FLOAT","enableVertexAttribArray","activeTexture","TEXTURE0","enable","BLEND","blendFunc","SRC_ALPHA","ONE_MINUS_SRC_ALPHA","process","color","spill","similarity","smoothness","background","videoWidth","videoHeight","width","window","devicePixelRatio","height","viewport","r","parseInt","substring","g","b","clearColor","clear","COLOR_BUFFER_BIT","uniform1i","uniform1f","uniform3f","substr","texImage2D","RGB","UNSIGNED_BYTE","drawArrays","TRIANGLE_FAN"],"sources":["../../../../src/components/ChromaKey/chroma-key.ts"],"sourcesContent":["import invariant from 'invariant';\n\nimport * as shaders from './shaders';\n\nexport type ProcessCallback = () => void;\n\nexport function chromaKey(\n $video: HTMLVideoElement,\n $canvas: HTMLCanvasElement,\n options: {\n color: string;\n spill: number;\n similarity: number;\n smoothness: number;\n background?: string | null;\n },\n): ProcessCallback | null {\n const gl = $canvas.getContext('webgl', {\n alpha: true,\n premultipliedAlpha: false,\n preserveDrawingBuffer: true,\n });\n\n if (!gl) {\n return null;\n }\n\n const BUFFER = gl.createBuffer();\n const TEXTURE = gl.createTexture();\n const program = gl.createProgram();\n const _VS_ = gl.createShader(gl.VERTEX_SHADER);\n const _FS_ = gl.createShader(gl.FRAGMENT_SHADER);\n\n invariant(program, 'Program is not initialized');\n invariant(_VS_, 'Vertex shader is not initialized');\n invariant(_FS_, 'Fragment shader is not initialized');\n\n gl.shaderSource(_VS_, shaders.VertexAlign);\n gl.shaderSource(_FS_, shaders.ChromaKey);\n\n gl.compileShader(_VS_);\n gl.compileShader(_FS_);\n\n if (!gl.getShaderParameter(_FS_, gl.COMPILE_STATUS)) {\n console.error(\n 'Fragment shader compilation failed',\n gl.getShaderInfoLog(_FS_),\n );\n }\n\n gl.attachShader(program, _VS_);\n gl.attachShader(program, _FS_);\n\n gl.linkProgram(program);\n gl.useProgram(program);\n\n gl.bindTexture(gl.TEXTURE_2D, TEXTURE);\n gl.bindBuffer(gl.ARRAY_BUFFER, BUFFER);\n\n gl.bufferData(\n gl.ARRAY_BUFFER,\n new Float32Array([-1, 1, -1, -1, 1, -1, 1, 1]),\n gl.STATIC_DRAW,\n );\n\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n\n const $coords$ = gl.getAttribLocation(program, 'coords');\n const $texture$ = gl.getUniformLocation(program, 'tex');\n const $width$ = gl.getUniformLocation(program, 'texWidth');\n const $height$ = gl.getUniformLocation(program, 'texHeight');\n const $color$ = gl.getUniformLocation(program, 'keyColor');\n const $similarity$ = gl.getUniformLocation(program, 'similarity');\n const $smoothness$ = gl.getUniformLocation(program, 'smoothness');\n const $spill$ = gl.getUniformLocation(program, 'spill');\n\n gl.vertexAttribPointer($coords$, 2, gl.FLOAT, false, 0, 0);\n gl.enableVertexAttribArray($coords$);\n\n gl.activeTexture(gl.TEXTURE0);\n\n // Enable blending for transparency (critical for Safari)\n gl.enable(gl.BLEND);\n gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n\n return function process() {\n const { color, spill, similarity, smoothness, background } = options;\n\n // Use video dimensions directly instead of metadata (for Safari compatibility)\n const videoWidth = $video.videoWidth;\n const videoHeight = $video.videoHeight;\n\n if (!videoWidth || !videoHeight) {\n return; // Video not ready yet\n }\n\n const width = videoWidth * window.devicePixelRatio;\n const height = videoHeight * window.devicePixelRatio;\n\n $canvas.width = width;\n $canvas.height = height;\n\n gl.viewport(0, 0, width, height);\n\n // Clear with background color or transparent\n if (background) {\n const r = parseInt(background.substring(1, 3), 16) / 255;\n const g = parseInt(background.substring(3, 5), 16) / 255;\n const b = parseInt(background.substring(5, 7), 16) / 255;\n gl.clearColor(r, g, b, 1);\n } else {\n gl.clearColor(0, 0, 0, 0);\n }\n gl.clear(gl.COLOR_BUFFER_BIT);\n\n gl.useProgram(program);\n\n gl.uniform1i($texture$, 0);\n gl.uniform1f($width$, width);\n gl.uniform1f($height$, height);\n gl.uniform1f($spill$, spill);\n gl.uniform1f($similarity$, similarity);\n gl.uniform1f($smoothness$, smoothness);\n gl.uniform3f(\n $color$,\n parseInt(color.substr(1, 2), 16) / 255,\n parseInt(color.substr(3, 2), 16) / 255,\n parseInt(color.substr(5, 2), 16) / 255,\n );\n\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, $video);\n gl.drawArrays(gl.TRIANGLE_FAN, 0, 4);\n };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["../../../src/conversation/types.ts"],"sourcesContent":["export type ConversationType = 'video' | 'audio';\n\nexport type ConversationParticipantRole = 'user' | 'agent';\n\nexport type ConversationVendor =\n | 'LIVEKIT'\n | 'DAILY'\n | 'HUME'\n | 'ELEVEN_LABS'\n | 'UNKNOWN_VENDOR';\n\nexport type AgentConnectionState =\n | 'joined' // agent is connected to the conversation\n | 'joining' // agent is connecting to the conversation\n | 'left' // agent left the conversation\n | 'idle'; // agent is not connected to the conversation\n\nexport type UserConnectionState =\n | 'joined' // user is connected to the conversation\n | 'joining' // user is connecting to the conversation\n | 'idle' // user is not connected to the conversation\n | 'leaving' // user is leaving the conversation\n | 'join-error'; // failed to join the conversation\n\nexport type ActivityState = 'idle' | 'speaking' | 'listening';\n\nexport type ConversationStatus =\n // Initial state\n | 'pending' // conversation is not created yet\n // States\n | 'created' // conversation was created\n | 'destroying' // destroying the conversation\n | 'destroyed' // conversation was destroyed\n | 'exceeded' // conversation limit is exceeded\n | 'inactivity-timeout' // conversation ended due to inactivity\n | 'credit-exhausted' // the server ended the conversation because the Legend owner ran out of credit\n // Errors\n | 'voice-not-found' // failed to find a voice\n | 'initialization-error' // failed to create conversation\n | 'error'; // unknown error\n\nexport type Conversation = {\n id: string;\n url: string;\n limit?: number;\n type: ConversationType;\n};\n\nexport type ConversationTranscription = {\n message: string;\n source: ConversationParticipantRole;\n id: string;\n};\n\nexport type ConversationDevice = {\n enabled: boolean;\n deviceId: string;\n};\n\nexport type ConversationAudio = {\n // Range between `0.0` and `1.0`.\n volume: number;\n muted: boolean;\n};\n"],"mappings":"","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sources":["../../../src/conversation/types.ts"],"sourcesContent":["export type ConversationType = 'video' | 'audio';\n\nexport type ConversationParticipantRole = 'user' | 'agent';\n\nexport type ConversationVendor =\n | 'LIVEKIT'\n | 'DAILY'\n | 'HUME'\n | 'ELEVEN_LABS'\n | 'UNKNOWN_VENDOR';\n\nexport type AgentConnectionState =\n | 'joined' // agent is connected to the conversation\n | 'joining' // agent is connecting to the conversation\n | 'left' // agent left the conversation\n | 'idle'; // agent is not connected to the conversation\n\nexport type UserConnectionState =\n | 'joined' // user is connected to the conversation\n | 'joining' // user is connecting to the conversation\n | 'idle' // user is not connected to the conversation\n | 'leaving' // user is leaving the conversation\n | 'join-error'; // failed to join the conversation\n\nexport type ActivityState = 'idle' | 'speaking' | 'listening';\n\nexport type ConversationStatus =\n // Initial state\n | 'pending' // conversation is not created yet\n // States\n | 'created' // conversation was created\n | 'destroying' // destroying the conversation\n | 'destroyed' // conversation was destroyed\n | 'exceeded' // conversation limit is exceeded\n | 'inactivity-timeout' // conversation ended due to inactivity\n | 'credit-exhausted' // the server ended the conversation because the Legend owner ran out of credit\n | 'conversation-limit-reached' // the server ended the conversation because the caller reached the Legend's daily conversation limit\n // Errors\n | 'voice-not-found' // failed to find a voice\n | 'initialization-error' // failed to create conversation\n | 'error'; // unknown error\n\nexport type Conversation = {\n id: string;\n url: string;\n limit?: number;\n type: ConversationType;\n};\n\nexport type ConversationTranscription = {\n message: string;\n source: ConversationParticipantRole;\n id: string;\n};\n\nexport type ConversationDevice = {\n enabled: boolean;\n deviceId: string;\n};\n\nexport type ConversationAudio = {\n // Range between `0.0` and `1.0`.\n volume: number;\n muted: boolean;\n};\n"],"mappings":"","ignoreList":[]}
|
|
@@ -13,7 +13,7 @@ import { useParticipantTrack, Source, getTrackStats, parseTrackStats } from '../
|
|
|
13
13
|
import { useEmitConversationEvent } from '../../useConversationEvents/useEmitConversationEvent';
|
|
14
14
|
import { useToolCallingRuntime } from '../../useTools/runtime/useToolCallingRuntime';
|
|
15
15
|
import { extractToolErrorMessage } from '../../useTools/utils/serialize';
|
|
16
|
-
import { checkIsTurnDetectionData, checkIsInactivityWarningData, checkIsInactivityTimeoutData, checkIsCreditExhaustedMessage, buildToolDefinitions, decodeDataPayload, findJoinedAgentParticipant, mergeTranscriptions, parseFunctionCallPayload, publishConversationDataMessage, safeStringify, shouldHandleParticipantConnected } from './utils';
|
|
16
|
+
import { checkIsTurnDetectionData, checkIsInactivityWarningData, checkIsInactivityTimeoutData, checkIsCreditExhaustedMessage, checkIsConversationLimitReachedMessage, buildToolDefinitions, decodeDataPayload, findJoinedAgentParticipant, mergeTranscriptions, parseFunctionCallPayload, publishConversationDataMessage, safeStringify, shouldHandleParticipantConnected } from './utils';
|
|
17
17
|
import { ACOUSTIC_AGENT_HANGOVER_MS, ACOUSTIC_USER_HANGOVER_MS, ACOUSTIC_USER_THRESHOLD_RMS, EXECUTE_TOOL_RPC_METHOD, GET_TOOLS_RPC_METHOD } from './constants';
|
|
18
18
|
export function useConversation(_ref) {
|
|
19
19
|
var _conversation$data2;
|
|
@@ -82,6 +82,7 @@ export function useConversation(_ref) {
|
|
|
82
82
|
const emitEvent = useEmitConversationEvent();
|
|
83
83
|
const inactivityTimeoutRef = useRef(false);
|
|
84
84
|
const creditExhaustedRef = useRef(false);
|
|
85
|
+
const conversationLimitReachedRef = useRef(false);
|
|
85
86
|
const acousticPhaseRef = useRef('idle');
|
|
86
87
|
const acousticT0Ref = useRef(null);
|
|
87
88
|
const latestTurnMetadataRef = useRef({});
|
|
@@ -360,6 +361,14 @@ export function useConversation(_ref) {
|
|
|
360
361
|
});
|
|
361
362
|
return;
|
|
362
363
|
}
|
|
364
|
+
if (checkIsConversationLimitReachedMessage(decoded, topic)) {
|
|
365
|
+
var _conversationRef$curr7;
|
|
366
|
+
conversationLimitReachedRef.current = true;
|
|
367
|
+
emitEvent('conversationLimitReached', {
|
|
368
|
+
conversationId: (_conversationRef$curr7 = conversationRef.current) == null ? void 0 : _conversationRef$curr7.id
|
|
369
|
+
});
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
363
372
|
for (const _ref2 of dataChannelHandlers) {
|
|
364
373
|
const guard = _ref2.guard;
|
|
365
374
|
const handle = _ref2.handle;
|
|
@@ -372,12 +381,12 @@ export function useConversation(_ref) {
|
|
|
372
381
|
}
|
|
373
382
|
}
|
|
374
383
|
function handleConnectedEvent() {
|
|
375
|
-
var _conversationRef$
|
|
384
|
+
var _conversationRef$curr8;
|
|
376
385
|
isConnectedRef.current = true;
|
|
377
386
|
setUserConnectionState('joined');
|
|
378
387
|
setAgentConnectionState('joining');
|
|
379
388
|
emitEvent('callStarted', {
|
|
380
|
-
conversationId: (_conversationRef$
|
|
389
|
+
conversationId: (_conversationRef$curr8 = conversationRef.current) == null ? void 0 : _conversationRef$curr8.id
|
|
381
390
|
});
|
|
382
391
|
}
|
|
383
392
|
async function handleEncryptionErrorEvent(error) {
|
|
@@ -405,6 +414,11 @@ export function useConversation(_ref) {
|
|
|
405
414
|
setConversationStatus('credit-exhausted');
|
|
406
415
|
return;
|
|
407
416
|
}
|
|
417
|
+
if (conversationLimitReachedRef.current) {
|
|
418
|
+
conversationLimitReachedRef.current = false;
|
|
419
|
+
setConversationStatus('conversation-limit-reached');
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
408
422
|
switch (reason) {
|
|
409
423
|
case DisconnectReason.CLIENT_INITIATED:
|
|
410
424
|
break;
|
|
@@ -423,18 +437,18 @@ export function useConversation(_ref) {
|
|
|
423
437
|
}
|
|
424
438
|
}
|
|
425
439
|
function handleAgentJoin(participant) {
|
|
426
|
-
var _conversationRef$
|
|
440
|
+
var _conversationRef$curr9;
|
|
427
441
|
setAgentConnectionState('joined');
|
|
428
442
|
emitEvent('agentJoined', {
|
|
429
|
-
conversationId: (_conversationRef$
|
|
443
|
+
conversationId: (_conversationRef$curr9 = conversationRef.current) == null ? void 0 : _conversationRef$curr9.id,
|
|
430
444
|
participant
|
|
431
445
|
});
|
|
432
446
|
}
|
|
433
447
|
function handleParticipantDisconnectedEvent(participant) {
|
|
434
|
-
var _conversationRef$
|
|
448
|
+
var _conversationRef$curr0;
|
|
435
449
|
setAgentConnectionState('left');
|
|
436
450
|
emitEvent('agentLeft', {
|
|
437
|
-
conversationId: (_conversationRef$
|
|
451
|
+
conversationId: (_conversationRef$curr0 = conversationRef.current) == null ? void 0 : _conversationRef$curr0.id,
|
|
438
452
|
participant
|
|
439
453
|
});
|
|
440
454
|
}
|
|
@@ -443,13 +457,13 @@ export function useConversation(_ref) {
|
|
|
443
457
|
return;
|
|
444
458
|
}
|
|
445
459
|
try {
|
|
446
|
-
var _conversationRef$
|
|
460
|
+
var _conversationRef$curr1;
|
|
447
461
|
setUserConnectionState('leaving');
|
|
448
462
|
await (room == null ? void 0 : room.disconnect(true));
|
|
449
463
|
setConversationStatus('destroyed');
|
|
450
464
|
setJoinedAt(undefined);
|
|
451
465
|
emitEvent('callEnded', {
|
|
452
|
-
conversationId: (_conversationRef$
|
|
466
|
+
conversationId: (_conversationRef$curr1 = conversationRef.current) == null ? void 0 : _conversationRef$curr1.id
|
|
453
467
|
});
|
|
454
468
|
} catch (error) {
|
|
455
469
|
console.error('Failed to leave', error);
|
|
@@ -457,22 +471,22 @@ export function useConversation(_ref) {
|
|
|
457
471
|
}
|
|
458
472
|
}
|
|
459
473
|
async function handleExpire() {
|
|
460
|
-
var _conversationRef$
|
|
474
|
+
var _conversationRef$curr10, _conversationRef$curr11;
|
|
461
475
|
// The duration timer keeps running after the call ends.
|
|
462
|
-
if (conversationStatus === 'credit-exhausted') {
|
|
476
|
+
if (conversationStatus === 'credit-exhausted' || conversationStatus === 'conversation-limit-reached') {
|
|
463
477
|
return;
|
|
464
478
|
}
|
|
465
479
|
emitEvent('timeExceeded', {
|
|
466
|
-
conversationId: (_conversationRef$
|
|
467
|
-
limit: (_conversationRef$
|
|
480
|
+
conversationId: (_conversationRef$curr10 = conversationRef.current) == null ? void 0 : _conversationRef$curr10.id,
|
|
481
|
+
limit: (_conversationRef$curr11 = conversationRef.current) == null ? void 0 : _conversationRef$curr11.limit
|
|
468
482
|
});
|
|
469
483
|
await leave();
|
|
470
484
|
setConversationStatus('exceeded');
|
|
471
485
|
}
|
|
472
486
|
async function interrupt() {
|
|
473
|
-
var _conversationRef$
|
|
487
|
+
var _conversationRef$curr12;
|
|
474
488
|
emitEvent('interrupt', {
|
|
475
|
-
conversationId: (_conversationRef$
|
|
489
|
+
conversationId: (_conversationRef$curr12 = conversationRef.current) == null ? void 0 : _conversationRef$curr12.id
|
|
476
490
|
});
|
|
477
491
|
await publishConversationDataMessage(room, {}, 'interrupt');
|
|
478
492
|
}
|
|
@@ -482,7 +496,7 @@ export function useConversation(_ref) {
|
|
|
482
496
|
}, 'inactivity_dismiss');
|
|
483
497
|
}
|
|
484
498
|
async function send(message, attachments) {
|
|
485
|
-
var _conversationRef$
|
|
499
|
+
var _conversationRef$curr13;
|
|
486
500
|
if (attachments === void 0) {
|
|
487
501
|
attachments = [];
|
|
488
502
|
}
|
|
@@ -493,7 +507,7 @@ export function useConversation(_ref) {
|
|
|
493
507
|
}
|
|
494
508
|
}));
|
|
495
509
|
emitEvent('userSendMessage', {
|
|
496
|
-
conversationId: (_conversationRef$
|
|
510
|
+
conversationId: (_conversationRef$curr13 = conversationRef.current) == null ? void 0 : _conversationRef$curr13.id,
|
|
497
511
|
message
|
|
498
512
|
});
|
|
499
513
|
}
|