@davi-ai/retorik-framework 4.0.4 → 5.0.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/README.md +13 -0
- package/dist/{AttachmentDetail.637ad44f.js → AttachmentDetail.3f9c113d.js} +15 -6
- package/dist/AttachmentDetail.3f9c113d.js.map +1 -0
- package/dist/{AttachmentDetail.83788045.js → AttachmentDetail.57c5579a.js} +15 -6
- package/dist/AttachmentDetail.57c5579a.js.map +1 -0
- package/dist/{CustomView.bf84bdf3.js → CustomView.6b96f53f.js} +8 -4
- package/dist/CustomView.6b96f53f.js.map +1 -0
- package/dist/{CustomView.9930c671.js → CustomView.b32a608f.js} +8 -4
- package/dist/CustomView.b32a608f.js.map +1 -0
- package/dist/{Emergency.1112c09f.js → Emergency.43605d14.js} +11 -2
- package/dist/Emergency.43605d14.js.map +1 -0
- package/dist/{Emergency.d5810ff2.js → Emergency.f1287bd5.js} +11 -2
- package/dist/Emergency.f1287bd5.js.map +1 -0
- package/dist/FullScreenImage.17df27bf.js.map +1 -1
- package/dist/FullScreenImage.99e19e10.js.map +1 -1
- package/dist/{HistoryList.3b4b1ffb.js → HistoryList.c19556a7.js} +8 -2
- package/dist/HistoryList.c19556a7.js.map +1 -0
- package/dist/{HistoryList.e5c01f21.js → HistoryList.e7262d62.js} +8 -2
- package/dist/HistoryList.e7262d62.js.map +1 -0
- package/dist/{LanguageChoice.1d866cfa.js → LanguageChoice.54fae1dc.js} +19 -8
- package/dist/LanguageChoice.54fae1dc.js.map +1 -0
- package/dist/{LanguageChoice.cce361a3.js → LanguageChoice.6e8b74f6.js} +19 -8
- package/dist/LanguageChoice.6e8b74f6.js.map +1 -0
- package/dist/LittleWeatherContainer.7e41105e.js.map +1 -1
- package/dist/LittleWeatherContainer.ee087e22.js.map +1 -1
- package/dist/{MapContainer.14c28128.js → MapContainer.25c8f4b4.js} +20 -5
- package/dist/MapContainer.25c8f4b4.js.map +1 -0
- package/dist/{MapContainer.f22ad81f.js → MapContainer.d00ab5b2.js} +20 -5
- package/dist/MapContainer.d00ab5b2.js.map +1 -0
- package/dist/{NewsContainer.d9de093c.js → NewsContainer.a39630c3.js} +33 -26
- package/dist/NewsContainer.a39630c3.js.map +1 -0
- package/dist/{NewsContainer.463e74de.js → NewsContainer.ec15c3bb.js} +33 -26
- package/dist/NewsContainer.ec15c3bb.js.map +1 -0
- package/dist/PrintingPreview.375e62b0.js.map +1 -1
- package/dist/PrintingPreview.c0ca7706.js.map +1 -1
- package/dist/RecognitionManager.c58b8a3d.js +298 -0
- package/dist/RecognitionManager.c58b8a3d.js.map +1 -0
- package/dist/RecognitionManager.cdfb39fc.js +314 -0
- package/dist/RecognitionManager.cdfb39fc.js.map +1 -0
- package/dist/SpiritEngineWrapper.21ea10d4.js.map +1 -1
- package/dist/SpiritEngineWrapper.39627300.js.map +1 -1
- package/dist/SynthesisPonyfillManager.10888d6d.js +888 -0
- package/dist/SynthesisPonyfillManager.10888d6d.js.map +1 -0
- package/dist/SynthesisPonyfillManager.f9f9a915.js +920 -0
- package/dist/SynthesisPonyfillManager.f9f9a915.js.map +1 -0
- package/dist/{ThreeJsWrapper.dd4906ff.js → ThreeJsWrapper.0285d280.js} +24 -12
- package/dist/ThreeJsWrapper.0285d280.js.map +1 -0
- package/dist/{ThreeJsWrapper.c02a077f.js → ThreeJsWrapper.ad746197.js} +24 -11
- package/dist/ThreeJsWrapper.ad746197.js.map +1 -0
- package/dist/{VeilleManager.f3bafdec.js → VeilleManager.0b3f2454.js} +11 -13
- package/dist/VeilleManager.0b3f2454.js.map +1 -0
- package/dist/{VeilleManager.85967e7c.js → VeilleManager.340a7825.js} +11 -13
- package/dist/VeilleManager.340a7825.js.map +1 -0
- package/dist/{Weather.7e945307.js → Weather.abc13d88.js} +9 -3
- package/dist/Weather.abc13d88.js.map +1 -0
- package/dist/{Weather.e81b7205.js → Weather.b9d9f82e.js} +9 -3
- package/dist/Weather.b9d9f82e.js.map +1 -0
- package/dist/index.d.ts +21 -951
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +52952 -33750
- package/dist/index.js.map +1 -1
- package/dist/index.modern.js +53468 -34269
- package/dist/index.modern.js.map +1 -1
- package/package.json +21 -21
- package/dist/AttachmentDetail.637ad44f.js.map +0 -1
- package/dist/AttachmentDetail.83788045.js.map +0 -1
- package/dist/CustomView.9930c671.js.map +0 -1
- package/dist/CustomView.bf84bdf3.js.map +0 -1
- package/dist/Emergency.1112c09f.js.map +0 -1
- package/dist/Emergency.d5810ff2.js.map +0 -1
- package/dist/HistoryList.3b4b1ffb.js.map +0 -1
- package/dist/HistoryList.e5c01f21.js.map +0 -1
- package/dist/LanguageChoice.1d866cfa.js.map +0 -1
- package/dist/LanguageChoice.cce361a3.js.map +0 -1
- package/dist/MapContainer.14c28128.js.map +0 -1
- package/dist/MapContainer.f22ad81f.js.map +0 -1
- package/dist/NewsContainer.463e74de.js.map +0 -1
- package/dist/NewsContainer.d9de093c.js.map +0 -1
- package/dist/ThreeJsWrapper.c02a077f.js.map +0 -1
- package/dist/ThreeJsWrapper.dd4906ff.js.map +0 -1
- package/dist/VeilleManager.85967e7c.js.map +0 -1
- package/dist/VeilleManager.f3bafdec.js.map +0 -1
- package/dist/Weather.7e945307.js.map +0 -1
- package/dist/Weather.e81b7205.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"mappings":"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","sources":["src/components/Speech/SynthesisPonyfillManager.tsx","src/utils/fetchSpeechServicesToken.ts","src/utils/selectVoice.ts","src/components/Speech/SynthesisManager.tsx","src/utils/speechSynthesisUtils.ts","src/utils/createUtterance.ts","src/components/Speech/RetorikSpeech.tsx","src/components/Speech/IndexedDbManager.ts"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react'\r\nimport { createSpeechSynthesisPonyfill } from '@davi-ai/web-speech-cognitive-services-davi'\r\nimport type { SpeechSynthesisPonyfillType, PonyfillOptions } from '@davi-ai/web-speech-cognitive-services-davi'\r\nimport { useSelector, useDispatch } from 'react-redux'\r\nimport { RootState, storeActions } from '../../store'\r\nimport { fetchSpeechServicesToken } from '../../utils/fetchSpeechServicesToken'\r\nimport { selectVoice } from '../../utils/selectVoice'\r\nimport SynthesisManager from './SynthesisManager'\r\n\r\ninterface SynthesisPonyfillManagerProps {\r\n isRetorikNews?: boolean\r\n}\r\n\r\nconst SynthesisPonyfillManager = ({ isRetorikNews }: SynthesisPonyfillManagerProps): React.JSX.Element | null => {\r\n const dispatch = useDispatch()\r\n const customVoice = useSelector((state: RootState) => state.speechReducer.customVoice)\r\n const ponyfillCredentials = useSelector((state: RootState) => state.speechReducer.ponyfillCredentials)\r\n const locale = useSelector((state: RootState) => state.localeReducer.locale)\r\n const agentData = useSelector((state: RootState) => state.retorikReducer.agentData)\r\n\r\n const [ponyfillCreated, setPonyfillCreated] = useState<boolean>(false)\r\n const ponyfillRef = useRef<SpeechSynthesisPonyfillType | undefined>(undefined)\r\n const refreshTimerRef = useRef<NodeJS.Timeout | null>(null)\r\n\r\n /**\r\n * Async function to retrieve a new token and assign it to the speechConfig inside ponyfill.speechSynthesis\r\n * @param {string} region\r\n * @param {string} key\r\n */\r\n const refreshTokenInNineMinutes = async (region: string, key: string): Promise<void> => {\r\n // A token is valid during 10 minutes, let's refresh it after 9 minutes\r\n refreshTimerRef.current = setTimeout(async () => {\r\n const token = await fetchSpeechServicesToken(region, key)\r\n\r\n if (token && ponyfillRef.current?.speechSynthesis?.speechConfig) {\r\n ponyfillRef.current.speechSynthesis.speechConfig.authorizationToken = token\r\n refreshTokenInNineMinutes(region, key)\r\n }\r\n }, 1000 * 60 * 9) // 9 minutes\r\n }\r\n\r\n /**\r\n * Fetch speech synthesis token and create the ponyfill containing all data\r\n * @param {string} region\r\n * @param {string} key\r\n */\r\n const fetchTokenAndCreatePonyfill = async (region: string, key: string): Promise<void> => {\r\n const token = await fetchSpeechServicesToken(region, key)\r\n\r\n if (token) {\r\n ponyfillRef.current = createSpeechSynthesisPonyfill({\r\n credentials: {\r\n region: ponyfillCredentials?.region,\r\n authorizationToken: token\r\n }\r\n })\r\n // Launch token refresh after ponyfill creation\r\n refreshTokenInNineMinutes(region, key)\r\n setPonyfillCreated(true)\r\n }\r\n }\r\n\r\n useEffect(() => {\r\n if (ponyfillCredentials?.authorizationToken && ponyfillCredentials.region) {\r\n const data: PonyfillOptions = {\r\n credentials: ponyfillCredentials\r\n }\r\n ponyfillRef.current = createSpeechSynthesisPonyfill(data)\r\n setPonyfillCreated(true)\r\n } else if (ponyfillCredentials?.subscriptionKey && ponyfillCredentials.region) {\r\n fetchTokenAndCreatePonyfill(ponyfillCredentials.region, ponyfillCredentials.subscriptionKey)\r\n } else if (ponyfillCredentials?.speechSynthesisHostname) {\r\n // To use self-hosted voice containers, we need no 'region', and 'speechSynthesisHostname' and 'speechRecognitionHostname' must both be defined\r\n // As this ponyfill is for speech synthesis only, we put a mock 'speechRecognitionHostname'\r\n const data: PonyfillOptions = {\r\n credentials: {\r\n // @ts-ignore\r\n speechSynthesisHostname: new URL(ponyfillCredentials.speechSynthesisHostname),\r\n speechRecognitionHostname: ponyfillCredentials.speechRecognitionHostname || 'mandatory_recognition_host_name',\r\n subscriptionKey: ponyfillCredentials.subscriptionKey || 'mandatory_subscription_key'\r\n }\r\n }\r\n ponyfillRef.current = createSpeechSynthesisPonyfill(data)\r\n setPonyfillCreated(true)\r\n }\r\n }, [ponyfillCredentials])\r\n\r\n const onVoicesChanged = (): void => {\r\n const voices = ponyfillRef.current?.speechSynthesis.getVoices()\r\n if (voices && Array.isArray(voices) && voices.length) {\r\n dispatch(storeActions.speech.setVoice(selectVoice(voices, locale, customVoice, agentData) || undefined))\r\n }\r\n }\r\n\r\n useEffect(() => {\r\n if (ponyfillRef.current) {\r\n const voices = ponyfillRef.current.speechSynthesis.getVoices()\r\n if (voices && Array.isArray(voices) && voices.length) {\r\n dispatch(storeActions.speech.setVoice(selectVoice(voices, locale, customVoice, agentData) || undefined))\r\n } else {\r\n ponyfillRef.current.speechSynthesis.onvoiceschanged = onVoicesChanged\r\n }\r\n }\r\n }, [ponyfillCreated, customVoice, agentData, locale])\r\n\r\n useEffect(() => {\r\n return (): void => {\r\n refreshTimerRef.current && clearTimeout(refreshTimerRef.current)\r\n }\r\n }, [])\r\n\r\n return ponyfillCreated && ponyfillRef.current ? <SynthesisManager ponyfill={ponyfillRef.current} isRetorikNews={isRetorikNews} /> : <React.Fragment />\r\n}\r\n\r\nexport default SynthesisPonyfillManager\r\n","const fetchSpeechServicesToken = async (\r\n region: string,\r\n key: string\r\n): Promise<any | undefined> => {\r\n const tokenRes = await fetch(\r\n `https://${region}.api.cognitive.microsoft.com/sts/v1.0/issueToken`,\r\n {\r\n method: 'POST',\r\n headers: {\r\n 'Ocp-Apim-Subscription-Key': key\r\n }\r\n }\r\n )\r\n .then((value) => {\r\n return value.text()\r\n })\r\n .catch((error) => {\r\n console.log('Error : ', error)\r\n return undefined\r\n })\r\n\r\n return tokenRes\r\n}\r\n\r\nexport { fetchSpeechServicesToken }\r\n","const selectVoice = (\r\n voices,\r\n locale,\r\n customVoice,\r\n agentData\r\n): SpeechSynthesisVoice | null => {\r\n let voice: SpeechSynthesisVoice | null = null\r\n // Check if a custom voice is defined in the props\r\n if (customVoice) {\r\n if (customVoice.voice) {\r\n // Search voice with its full name (ex: AriaNeural, GuyNeural)\r\n const neuralVoice = new RegExp(customVoice.voice, 'iu')\r\n voice = voices.find(\r\n ({ name }) => neuralVoice.test(name) || name === customVoice.voice\r\n )\r\n } else if (customVoice.gender) {\r\n // Search voice depending on given gender and locale\r\n voice = voices.find(({ gender, lang }) => {\r\n return (\r\n gender.toLowerCase() === customVoice?.gender?.toLowerCase() &&\r\n lang === locale\r\n )\r\n })\r\n }\r\n }\r\n // Get voice depending on locale and gender\r\n if (!voice) {\r\n voice = voices.find(({ gender, lang }) => {\r\n return (\r\n gender.toLowerCase() ===\r\n (agentData?.gender?.toLowerCase() || 'female') && lang === locale\r\n )\r\n })\r\n }\r\n // No voice found, fall back to US default voices : female => Aria / male => Guy\r\n if (!voice) {\r\n const genderedVoice =\r\n agentData?.gender?.toLowerCase() === 'female' ? 'AriaNeural' : 'GuyNeural'\r\n const neuralVoice = new RegExp(genderedVoice, 'iu')\r\n voice = voices.find(({ name }) => neuralVoice.test(name))\r\n }\r\n\r\n return voice\r\n}\r\n\r\nexport { selectVoice }\r\n","import React, { useEffect, useState, useRef } from 'react'\r\nimport { SpeechSynthesisUtterance, SpeechSynthesisPonyfillType } from '@davi-ai/web-speech-cognitive-services-davi'\r\nimport { useSelector, useDispatch } from 'react-redux'\r\nimport { RootState, storeActions, Mode, RecognitionState, Routes } from '../../store'\r\nimport { useTelemetry } from '../Contexts/TelemetryContext'\r\n\r\nimport type { CreateUtteranceParams } from '../../models/speechTypes'\r\nimport type { RetorikActivity } from '../../store/models/activityTypes'\r\nimport { TraceType } from '../../models/enums'\r\nimport { selectVoice } from '../../utils/selectVoice'\r\nimport { checkSayAsWordsAndCreateUtterance } from '../../utils/speechSynthesisUtils'\r\n\r\nimport RetorikSpeech from './RetorikSpeech'\r\n\r\ninterface SynthesisManagerProps {\r\n ponyfill: SpeechSynthesisPonyfillType\r\n isRetorikNews?: boolean\r\n}\r\n\r\nconst SynthesisManager = ({ ponyfill, isRetorikNews }: SynthesisManagerProps): React.JSX.Element | null => {\r\n const dispatch = useDispatch()\r\n const cancel = useSelector((state: RootState) => state.speechReducer.cancel)\r\n const streamingQueue = useSelector((state: RootState) => state.speechReducer.streamingQueue)\r\n const voice = useSelector((state: RootState) => state.speechReducer.voice)\r\n const customVoice = useSelector((state: RootState) => state.speechReducer.customVoice)\r\n const activeRecognitionState = useSelector((state: RootState) => state.speechReducer.activeRecognitionState)\r\n const externalTextToSpeech = useSelector((state: RootState) => state.speechReducer.externalTextToSpeech)\r\n const isMicrophoneAllowed = useSelector((state: RootState) => state.speechReducer.isMicrophoneAllowed)\r\n const mode = useSelector((state: RootState) => state.speechReducer.mode)\r\n const route = useSelector((state: RootState) => state.viewReducer.route)\r\n const locale = useSelector((state: RootState) => state.localeReducer.locale)\r\n const replacementLocales = useSelector((state: RootState) => state.localeReducer.replacementLocales)\r\n const agentData = useSelector((state: RootState) => state.retorikReducer.agentData)\r\n const appAvailable = useSelector((state: RootState) => state.retorikReducer.appAvailable)\r\n const preventExpectedInputHint = useSelector((state: RootState) => state.retorikReducer.configuration.preventExpectedInputHint)\r\n const speechSynthesisOptions = useSelector((state: RootState) => state.retorikReducer.configuration.speechSynthesisOptions)\r\n const sendTrace = useTelemetry().sendTrace\r\n\r\n const [utterance, setUtterance] = useState<SpeechSynthesisUtterance | null>(null)\r\n const [nextUtterance, setNextUtterance] = useState<SpeechSynthesisUtterance | null>(null)\r\n const [forceSpeechCaching, setForceSpeechCaching] = useState<boolean>(false)\r\n\r\n const isNewsViewRef = useRef<boolean>(!!isRetorikNews)\r\n const lastListTextPlayedRef = useRef<string>('')\r\n const streamingQueueRef = useRef<Array<RetorikActivity>>([])\r\n const currentActivityRef = useRef<RetorikActivity | null>(null)\r\n\r\n /**\r\n * Check activity locale in case of voice change during the speech, to keep the language defined in activity\r\n * instead of switching languages between answers that are written in the same language\r\n * @param {string} activityLocale\r\n * @returns {SpeechSynthesisVoice | null}\r\n */\r\n const getVoiceAfterCheckingActivityLocale = (activityLocale: string): SpeechSynthesisVoice | null => {\r\n return activityLocale === locale ? voice : selectVoice(ponyfill.speechSynthesis.getVoices(), activityLocale, customVoice, agentData)\r\n }\r\n\r\n /**\r\n * Check if the activity is a list one, to prevent text re-reading on state update\r\n * @param {CreateUtteranceParams} params\r\n * @returns {SpeechSynthesisUtterance}\r\n */\r\n const checkActivityAndCreateUtterance = (params: CreateUtteranceParams): SpeechSynthesisUtterance => {\r\n if (params.activity.attachmentLayout && params.activity.attachmentLayout.toLowerCase() === 'davilist') {\r\n const textToSpeak = params.activity.speak || params.activity.text\r\n if (textToSpeak) {\r\n if (textToSpeak === lastListTextPlayedRef.current) {\r\n return checkSayAsWordsAndCreateUtterance({ ...params, voice: null }, speechSynthesisOptions?.sayAs)\r\n } else {\r\n lastListTextPlayedRef.current = textToSpeak\r\n }\r\n }\r\n }\r\n\r\n return checkSayAsWordsAndCreateUtterance(params, speechSynthesisOptions?.sayAs)\r\n }\r\n\r\n const resetData = (): void => {\r\n // Set all activities currently in the queue as ended\r\n streamingQueueRef.current?.forEach((activity) => {\r\n dispatch(storeActions.activity.addEndedActivity(activity.id))\r\n })\r\n streamingQueueRef.current = []\r\n dispatch(storeActions.speech.killCurrentStreaming())\r\n\r\n currentActivityRef.current = null\r\n setUtterance(null)\r\n setNextUtterance(null)\r\n dispatch(storeActions.speech.resetCancelCurrentUtterance())\r\n dispatch(storeActions.speech.setSpeaking(false))\r\n dispatch(storeActions.speech.setBoundaryData([]))\r\n }\r\n\r\n const checkReplacementLocaleAndGetUtterance = (activity: RetorikActivity, checkReplacement: boolean = true): SpeechSynthesisUtterance => {\r\n const replacementLocale = checkReplacement ? replacementLocales?.[locale] || locale : locale\r\n const params: CreateUtteranceParams = {\r\n activity: activity,\r\n voice: getVoiceAfterCheckingActivityLocale(replacementLocale),\r\n locale: replacementLocale\r\n }\r\n\r\n return checkActivityAndCreateUtterance(params)\r\n }\r\n\r\n /**\r\n * Check if the microphone can be opened automatically\r\n */\r\n const checkDictateState = (): void => {\r\n if (!preventExpectedInputHint && mode === Mode.vocal && activeRecognitionState === RecognitionState.Closed) {\r\n if (!isMicrophoneAllowed) {\r\n dispatch(storeActions.speech.askPermission())\r\n } else {\r\n dispatch(storeActions.speech.toggleMicrophone(true))\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * On route change, reset all data and check if we are on the news view\r\n */\r\n useEffect(() => {\r\n resetData()\r\n if (!isRetorikNews) isNewsViewRef.current = route === Routes.News || route === Routes.NewsInVeille\r\n // Force speech caching when using Retorik News or when using news in veille\r\n setForceSpeechCaching(isRetorikNews || route === Routes.NewsInVeille)\r\n }, [route])\r\n\r\n /**\r\n * On cancel call, reset all data and kill current streaming\r\n */\r\n useEffect(() => {\r\n cancel && resetData()\r\n }, [cancel])\r\n\r\n /**\r\n * Play external speech immediately but don't add it to the history\r\n */\r\n useEffect(() => {\r\n if (externalTextToSpeech) {\r\n const activity = {\r\n speak: externalTextToSpeech,\r\n locale: locale\r\n } as RetorikActivity\r\n currentActivityRef.current = activity\r\n setUtterance(checkReplacementLocaleAndGetUtterance(activity, false))\r\n }\r\n }, [externalTextToSpeech])\r\n\r\n const dispatchSpeechEvent = (start: boolean): void => {\r\n const speechEvent = start ? new Event('retorikSpeakStart') : new Event('retorikSpeakStop')\r\n document.dispatchEvent(speechEvent)\r\n }\r\n\r\n /**\r\n * Called when utterance's \"start\" event is fired\r\n */\r\n const handleUtteranceStart = (): void => {\r\n sendTrace(TraceType.utteranceStart, {\r\n activityId: currentActivityRef.current?.id,\r\n text: currentActivityRef.current?.speak || currentActivityRef.current?.text\r\n })\r\n dispatch(storeActions.speech.setSpeaking(true))\r\n\r\n if (!isNewsViewRef.current && currentActivityRef?.current) {\r\n dispatch(storeActions.speech.setCurrentOrLastPlayedActivity(currentActivityRef.current))\r\n currentActivityRef.current.id && dispatch(storeActions.directline.dispatchMarkActivity({ id: currentActivityRef.current.id, speaking: true }))\r\n }\r\n dispatchSpeechEvent(true)\r\n\r\n // Set next utterance to prepare synthesis data in order to improve fluidity\r\n if (streamingQueueRef.current.length && !streamingQueueRef.current[0].value?.streamingCount) {\r\n const utt = checkReplacementLocaleAndGetUtterance(streamingQueueRef.current[0], false)\r\n setNextUtterance((current) => (utt.text === current?.text ? null : utt))\r\n } else {\r\n setNextUtterance(null)\r\n }\r\n }\r\n\r\n /**\r\n * Called when utterance's \"end\" event is fired\r\n */\r\n const handleUtteranceEnd = (): void => {\r\n sendTrace(TraceType.utteranceEnd, {\r\n activityId: currentActivityRef.current?.id\r\n })\r\n dispatch(storeActions.speech.setSpeaking(false))\r\n dispatchSpeechEvent(false)\r\n\r\n if (isNewsViewRef.current) {\r\n dispatch(storeActions.utils.setRetorikNewsEnded(true))\r\n currentActivityRef.current = null\r\n } else {\r\n handleEnded()\r\n }\r\n }\r\n\r\n const handleEnded = (): void => {\r\n // Add played activity id to context's endedActivities\r\n if (currentActivityRef.current?.id) {\r\n dispatch(storeActions.activity.addEndedActivity(currentActivityRef.current.id))\r\n dispatch(storeActions.directline.dispatchMarkActivity({ id: currentActivityRef.current.id, speaking: false }))\r\n }\r\n\r\n if (streamingQueueRef.current?.length) {\r\n // Check if this is the message sent after streaming activities\r\n if (streamingQueueRef.current[0].value?.streamingCount) {\r\n dispatch(storeActions.activity.addEndedActivity(streamingQueueRef.current[0].id))\r\n // If there is another activity after this message, play it. If not, let's check if the microphone should be opened\r\n if (streamingQueueRef.current?.length > 1) {\r\n const utt = checkReplacementLocaleAndGetUtterance(streamingQueueRef.current[1])\r\n currentActivityRef.current = streamingQueueRef.current[1]\r\n setUtterance(utt)\r\n dispatch(storeActions.speech.removeFirstFromStreamingQueue(true))\r\n } else {\r\n streamingQueueRef.current[0].inputHint === 'expectingInput' && checkDictateState()\r\n currentActivityRef.current = null\r\n setUtterance(null)\r\n setNextUtterance(null)\r\n dispatch(storeActions.speech.removeFirstFromStreamingQueue(false))\r\n }\r\n } else {\r\n const utt = checkReplacementLocaleAndGetUtterance(streamingQueueRef.current[0])\r\n currentActivityRef.current = streamingQueueRef.current[0]\r\n setUtterance(utt)\r\n dispatch(storeActions.speech.removeFirstFromStreamingQueue(false))\r\n }\r\n } else {\r\n currentActivityRef.current?.inputHint === 'expectingInput' && checkDictateState()\r\n currentActivityRef.current = null\r\n setUtterance(null)\r\n setNextUtterance(null)\r\n }\r\n }\r\n\r\n /**\r\n * Wait for app loading and voice selection to begin playing speech\r\n */\r\n useEffect(() => {\r\n // Set ref from the state to use in events\r\n streamingQueueRef.current = streamingQueue\r\n\r\n if (appAvailable && voice && streamingQueue.length && !currentActivityRef.current) {\r\n handleEnded()\r\n }\r\n }, [appAvailable, voice, streamingQueue])\r\n\r\n return (\r\n <RetorikSpeech\r\n ponyfill={ponyfill}\r\n appAvailable={appAvailable}\r\n utterance={utterance}\r\n nextUtterance={nextUtterance}\r\n forceSpeechCaching={forceSpeechCaching}\r\n onStart={handleUtteranceStart}\r\n onError={handleUtteranceEnd}\r\n onEnd={handleUtteranceEnd}\r\n />\r\n )\r\n}\r\n\r\nexport default SynthesisManager\r\n","import { SpeechSynthesisUtterance } from '@davi-ai/web-speech-cognitive-services-davi'\r\nimport createUtterance from './createUtterance'\r\nimport type { CreateUtteranceParams } from '../models/speechTypes'\r\nimport type { SayAsItem } from '../store/models/types'\r\n\r\ninterface SayAs {\r\n common?: Array<SayAsItem>\r\n localized?: Record<string, Array<SayAsItem>>\r\n}\r\n\r\n/**\r\n * Check if there are some replacement codes for this language, to improve speech synthesis, and then create the utterance\r\n * @param {CreateUtteranceParams} params - data needed to create an utterance\r\n * @param {SayAs} sayAs - string that should be replaced by their ipa codes\r\n * @returns {SpeechSynthesisUtterance}\r\n */\r\nconst checkSayAsWordsAndCreateUtterance = (params: CreateUtteranceParams, sayAs?: SayAs): SpeechSynthesisUtterance => {\r\n let sayAsWords: Array<SayAsItem> = []\r\n if (sayAs) {\r\n sayAs.common?.length && (sayAsWords = [...sayAs.common])\r\n sayAs.localized && sayAs.localized[params.locale]?.length && (sayAsWords = [...sayAsWords, ...sayAs.localized[params.locale]])\r\n }\r\n\r\n return createUtterance({ ...params, sayAsWords })\r\n}\r\n\r\nexport { checkSayAsWordsAndCreateUtterance }\r\n","import { SpeechMarkdown } from '@davi-ai/speechmarkdown-davi-js'\r\nimport { SpeechSynthesisUtterance } from '@davi-ai/web-speech-cognitive-services-davi'\r\nimport type { CreateUtteranceParams } from '../models/speechTypes'\r\nimport { SayAsItem } from '../store/models/types'\r\n\r\nconst buildSSML = (activity: any, locale: string, speechMarkdownParser: SpeechMarkdown, sayAsWords?: Array<SayAsItem>): string => {\r\n let speech: string = activity.speak || activity.text\r\n // Replace character not recognized in Microsoft TTS\r\n speech = speech.replaceAll('’', \"'\")\r\n let textParsedAsSSML = ''\r\n\r\n try {\r\n if (sayAsWords?.length) {\r\n const wordsUsed: Array<string> = []\r\n sayAsWords.forEach((tuple) => {\r\n if (!wordsUsed.includes(tuple.text.toLocaleLowerCase(locale))) {\r\n const regex = new RegExp(`\\\\b${tuple.text}\\\\b`, 'gi')\r\n speech = speech.replaceAll(regex, `(${tuple.text})[ipa:\"${tuple.ipa}\"]`)\r\n wordsUsed.push(tuple.text.toLocaleLowerCase(locale))\r\n }\r\n })\r\n }\r\n\r\n textParsedAsSSML = speechMarkdownParser.toSSML(speech)\r\n } catch (e) {\r\n console.warn('Retorik Framework > error in speechmarkdown parser : ', e)\r\n }\r\n\r\n return (\r\n `<speak version=\"1.0\" xmlns=\"http://www.w3.org/2001/10/synthesis\" xmlns:mstts=\"https://www.w3.org/2001/mstts\" xmlns:emo=\"http://www.w3.org/2009/10/emotionml\" xml:lang=\"${locale}\">` +\r\n textParsedAsSSML +\r\n '</speak>'\r\n )\r\n}\r\n\r\nconst createUtterance = ({ activity, voice, locale, sayAsWords }: CreateUtteranceParams): SpeechSynthesisUtterance => {\r\n // If there is no text to be read, create an empty utterance that will be put in the array of ended activities\r\n if (!voice || (!activity.speak && !activity.text)) {\r\n return new SpeechSynthesisUtterance('')\r\n }\r\n\r\n return new SpeechSynthesisUtterance(\r\n buildSSML(\r\n activity,\r\n locale,\r\n new SpeechMarkdown({\r\n platform: 'microsoft-azure',\r\n includeSpeakTag: false,\r\n globalVoiceAndLang: {\r\n voice: voice.name,\r\n lang: voice.name.toLowerCase().includes('multilingual') ? locale : undefined\r\n }\r\n }),\r\n sayAsWords\r\n )\r\n )\r\n}\r\n\r\nexport default createUtterance\r\n","import React, { useEffect, useRef, useState } from 'react'\r\nimport { SpeechSynthesisPonyfillType, SpeechSynthesisUtterance } from '@davi-ai/web-speech-cognitive-services-davi'\r\nimport type { SpeechSynthesisEventProps } from '@davi-ai/web-speech-cognitive-services-davi'\r\nimport { useSelector, useDispatch } from 'react-redux'\r\nimport { RootState, storeActions, RecognitionState } from '../../store'\r\n\r\nimport type { Boundary, Bookmark } from '../../store/models/speechTypes'\r\nimport { audioFiles } from '../../utils/audioFiles'\r\n\r\nimport IndexedDbManager from './IndexedDbManager'\r\nimport GdprAndLoader from '../Loader/GdprAndLoader'\r\n\r\ninterface RetorikSpeechProps {\r\n ponyfill: SpeechSynthesisPonyfillType\r\n onEnd?: () => void\r\n onError?: () => void\r\n onStart?: () => void\r\n utterance: SpeechSynthesisUtterance | null\r\n nextUtterance: SpeechSynthesisUtterance | null\r\n appAvailable: boolean\r\n forceSpeechCaching: boolean\r\n}\r\n\r\ninterface NextUtteranceData {\r\n speechData: ArrayBuffer\r\n boundaries: Array<Boundary>\r\n visemes: Array<SpeechSynthesisEventProps>\r\n bookmarks: Array<Bookmark>\r\n}\r\n\r\nconst DBManager = new IndexedDbManager()\r\nconst tagsRemoverRegex = /<[^<>]+>/g\r\n\r\nconst RetorikSpeech = ({ ponyfill, onEnd, onError, onStart, utterance, nextUtterance, appAvailable, forceSpeechCaching }: RetorikSpeechProps): React.JSX.Element => {\r\n const dispatch = useDispatch()\r\n const locale = useSelector((state: RootState) => state.localeReducer.locale)\r\n const loaderClosed = useSelector((state: RootState) => state.retorikReducer.loaderClosed)\r\n const enableSpeechCaching = useSelector((state: RootState) => state.retorikReducer.configuration.enableSpeechCaching)\r\n const speechRecognitionOptions = useSelector((state: RootState) => state.retorikReducer.configuration.speechRecognitionOptions)\r\n const useOldRemote = useSelector((state: RootState) => state.retorikReducer.configuration.useOldRemote)\r\n const voice = useSelector((state: RootState) => state.speechReducer.voice)\r\n const muted = useSelector((state: RootState) => state.speechReducer.muted)\r\n const activeRecognitionState = useSelector((state: RootState) => state.speechReducer.activeRecognitionState)\r\n\r\n const boundaryRef = useRef<Array<Boundary> | undefined | null>(null)\r\n const visemeRef = useRef<Array<SpeechSynthesisEventProps> | undefined | null>(null)\r\n const bookmarkRef = useRef<Array<Bookmark> | undefined | null>(null)\r\n const audioRef = useRef<HTMLAudioElement>(null)\r\n const speechRecognitionAudioRef = useRef<HTMLAudioElement>(null)\r\n const microphoneOpenAudioRef = useRef<HTMLAudioElement>(null)\r\n const microphoneCloseAudioRef = useRef<HTMLAudioElement>(null)\r\n\r\n const [DBReady, setDBReady] = useState<boolean>(false)\r\n const [playingBlob, setPlayingBlob] = useState<boolean>(false)\r\n\r\n const nextUtteranceDataRef = useRef<{ text: string; data: NextUtteranceData | null } | null>(null)\r\n const nextUtteranceTextRef = useRef<string | null>(null)\r\n const nextUtteranceBoundariesRef = useRef<Array<Boundary>>([])\r\n const nextUtteranceVisemesRef = useRef<Array<SpeechSynthesisEventProps>>([])\r\n const nextUtteranceBookmarksRef = useRef<Array<Bookmark>>([])\r\n const emptyTextUtteranceRef = useRef<NodeJS.Timeout | null>(null)\r\n\r\n useEffect(() => {\r\n DBManager.checkDB().then((result) => setDBReady(result))\r\n\r\n return (): void => {\r\n stopCurrentPlaying()\r\n emptyTextUtteranceRef?.current && clearTimeout(emptyTextUtteranceRef.current)\r\n }\r\n }, [])\r\n\r\n const stopCurrentPlaying = (): void => {\r\n if (appAvailable || loaderClosed) {\r\n // Cancel synthesis if using synthesizer\r\n if (!playingBlob) {\r\n ponyfill.speechSynthesis.cancel()\r\n }\r\n\r\n resetNextUtteranceData()\r\n\r\n if (audioRef.current && !audioRef.current?.paused) {\r\n audioRef.current.pause()\r\n handleEnd()\r\n }\r\n }\r\n }\r\n\r\n const attachEvents = (tempUtterance: SpeechSynthesisUtterance, isMainUtterance?: boolean): SpeechSynthesisUtterance => {\r\n tempUtterance.onerror = (event): void => {\r\n isMainUtterance ? handleError(event) : (nextUtteranceDataRef.current = null)\r\n }\r\n\r\n tempUtterance.onsynthesiscompleted = (): void => {\r\n const endBoundary: Boundary = {\r\n word: '',\r\n startTime: 0,\r\n endTime: 0,\r\n boundaryType: 'EndBoundary'\r\n }\r\n\r\n if (isMainUtterance) {\r\n const tempBoundaries = boundaryRef?.current || []\r\n boundaryRef.current = [...tempBoundaries, endBoundary]\r\n dispatch(storeActions.speech.setBoundaryData([...tempBoundaries, endBoundary]))\r\n } else {\r\n nextUtteranceBoundariesRef.current = [...nextUtteranceBoundariesRef.current, endBoundary]\r\n }\r\n }\r\n\r\n tempUtterance.onboundary = (event: SpeechSynthesisEventProps): void => {\r\n if (event.boundaryType !== 'Viseme') {\r\n const newBoundary: Boundary = {\r\n word: event.name,\r\n startTime: event.elapsedTime,\r\n endTime: event.elapsedTime + event.duration,\r\n boundaryType: event.boundaryType\r\n }\r\n\r\n if (isMainUtterance) {\r\n // Update the boundaryData state with the new data.\r\n const tempBoundaries = boundaryRef?.current || []\r\n boundaryRef.current = [...tempBoundaries, newBoundary]\r\n dispatch(storeActions.speech.setBoundaryData([...tempBoundaries, newBoundary]))\r\n } else {\r\n nextUtteranceBoundariesRef.current = [...nextUtteranceBoundariesRef.current, newBoundary]\r\n }\r\n }\r\n }\r\n\r\n tempUtterance.onviseme = (event: SpeechSynthesisEventProps) => {\r\n if (isMainUtterance) {\r\n // Collect visemes locally - they will be dispatched when audio starts playing\r\n const tempVisemes = visemeRef?.current || []\r\n visemeRef.current = [...tempVisemes, event]\r\n } else {\r\n nextUtteranceVisemesRef.current = [...nextUtteranceVisemesRef.current, event]\r\n }\r\n }\r\n\r\n tempUtterance.onmark = (event: SpeechSynthesisEventProps) => {\r\n console.log('Retorik Framework > onmark event', event)\r\n const bookmark: Bookmark = {\r\n name: event.name,\r\n time: event.elapsedTime\r\n }\r\n\r\n if (isMainUtterance) {\r\n // Collect bookmarks locally - they will be dispatched when audio starts playing\r\n const tempBookmarks = bookmarkRef?.current || []\r\n bookmarkRef.current = [...tempBookmarks, bookmark]\r\n } else {\r\n nextUtteranceBookmarksRef.current = [...nextUtteranceBookmarksRef.current, bookmark]\r\n }\r\n }\r\n\r\n return tempUtterance\r\n }\r\n\r\n const processNextData = (data: ArrayBuffer) => {\r\n nextUtteranceDataRef.current =\r\n data?.byteLength && nextUtteranceTextRef.current\r\n ? {\r\n text: nextUtteranceTextRef.current,\r\n data: {\r\n speechData: data,\r\n boundaries: nextUtteranceBoundariesRef.current,\r\n visemes: nextUtteranceVisemesRef.current,\r\n bookmarks: nextUtteranceBookmarksRef.current\r\n }\r\n }\r\n : null\r\n\r\n // Reset boundary / viseme data\r\n resetNextUtteranceData(true)\r\n }\r\n\r\n const resetNextUtteranceData = (keepArrayBufferData?: boolean): void => {\r\n !keepArrayBufferData && (nextUtteranceDataRef.current = null)\r\n nextUtteranceTextRef.current = null\r\n nextUtteranceBoundariesRef.current = []\r\n nextUtteranceVisemesRef.current = []\r\n nextUtteranceBookmarksRef.current = []\r\n }\r\n\r\n useEffect(() => {\r\n if (utterance) {\r\n if (utterance.text) {\r\n if (audioRef?.current) {\r\n if (nextUtteranceDataRef.current?.text === utterance.text && nextUtteranceDataRef.current.data) {\r\n boundaryRef.current = nextUtteranceDataRef.current.data.boundaries\r\n dispatch(storeActions.speech.setBoundaryData(nextUtteranceDataRef.current.data.boundaries))\r\n // Store visemes locally - they will be dispatched when audio starts playing\r\n visemeRef.current = nextUtteranceDataRef.current.data.visemes\r\n processData(nextUtteranceDataRef.current.data.speechData, true)\r\n } else {\r\n // Play utterance whether by asking for a speech synthesis, or by retrieving data from indexedDB\r\n playUtterance(attachEvents(utterance, true))\r\n }\r\n } else {\r\n stopCurrentPlaying()\r\n }\r\n } else {\r\n handleEmptyTextUtterance()\r\n }\r\n } else {\r\n stopCurrentPlaying()\r\n }\r\n }, [utterance])\r\n\r\n useEffect(() => {\r\n // If there are data in nextUtteranceTextRef, this means the previous synthesis data retrieval is not finished, so we don't begin a new one\r\n if (nextUtterance?.text && !nextUtteranceTextRef.current) {\r\n const tempUtterance = attachEvents(nextUtterance)\r\n nextUtteranceTextRef.current = nextUtterance.text\r\n ponyfill.speechSynthesis.synthesizeAndGetArrayData(tempUtterance, processNextData)\r\n } else {\r\n resetNextUtteranceData()\r\n }\r\n }, [nextUtterance])\r\n\r\n const playUtterance = async (utt: SpeechSynthesisUtterance): Promise<void> => {\r\n if (DBReady && (enableSpeechCaching !== false || forceSpeechCaching) && utt) {\r\n const dataFromIndexedDB = await DBManager.getSpeechData(`${locale}.${voice?.name}.${utt.text.replace(tagsRemoverRegex, '')}`)\r\n\r\n if (dataFromIndexedDB) {\r\n boundaryRef.current = dataFromIndexedDB.boundaries\r\n dispatch(storeActions.speech.setBoundaryData(dataFromIndexedDB.boundaries))\r\n // Store visemes locally - they will be dispatched when audio starts playing\r\n visemeRef.current = dataFromIndexedDB.visemes || []\r\n processData(dataFromIndexedDB.value, true)\r\n } else {\r\n ponyfill.speechSynthesis.synthesizeAndGetArrayData(utt, processData)\r\n }\r\n } else {\r\n ponyfill.speechSynthesis.synthesizeAndGetArrayData(utt, processData)\r\n }\r\n }\r\n\r\n const processData = (data: ArrayBuffer, alreadyExistsInDB?: boolean) => {\r\n if (data?.byteLength) {\r\n const blob = new Blob([data], { type: 'audio/mp3' })\r\n\r\n !alreadyExistsInDB &&\r\n (enableSpeechCaching !== false || forceSpeechCaching) &&\r\n DBReady &&\r\n boundaryRef?.current &&\r\n utterance &&\r\n DBManager.addSpeechData({\r\n id: `${locale}.${voice?.name}.${utterance.text.replace(tagsRemoverRegex, '')}`,\r\n value: data,\r\n boundaries: boundaryRef.current,\r\n visemes: visemeRef.current || []\r\n })\r\n\r\n const url = URL.createObjectURL(blob)\r\n\r\n if (audioRef?.current) {\r\n setPlayingBlob(true)\r\n audioRef.current.src = url\r\n audioRef.current.play().catch((e) => console.warn(e))\r\n }\r\n } else {\r\n handleEmptyTextUtterance()\r\n }\r\n }\r\n\r\n const resetData = (): void => {\r\n boundaryRef.current = []\r\n visemeRef.current = []\r\n dispatch(storeActions.speech.setBoundaryData([]))\r\n dispatch(storeActions.speech.setVisemeData([]))\r\n dispatch(storeActions.speech.setBookmarkData([]))\r\n setPlayingBlob(false)\r\n }\r\n\r\n const handleStart = (): void => {\r\n if (appAvailable || loaderClosed) {\r\n // Dispatch visemes now that audio is playing, ensuring lip sync timing is correct\r\n if (visemeRef.current?.length) {\r\n dispatch(storeActions.speech.setVisemeData(visemeRef.current))\r\n dispatch(storeActions.speech.setBookmarkData(bookmarkRef.current || []))\r\n }\r\n onStart?.()\r\n }\r\n }\r\n\r\n const handleEnd = (): void => {\r\n if (appAvailable || loaderClosed) {\r\n onEnd?.()\r\n resetData()\r\n } else {\r\n dispatch(storeActions.retorik.setLoaderClosed(true))\r\n }\r\n }\r\n\r\n const handleError = (error): void => {\r\n console.log('Retorik Framework > speech synthesis error ', error)\r\n onError?.()\r\n resetData()\r\n }\r\n\r\n const handleEmptyTextUtterance = (): void => {\r\n handleStart()\r\n emptyTextUtteranceRef?.current && clearTimeout(emptyTextUtteranceRef.current)\r\n emptyTextUtteranceRef.current = setTimeout(() => {\r\n handleEnd()\r\n }, 50)\r\n }\r\n\r\n /**\r\n * On call :\r\n * - play 1 second muted sound to prime audio output\r\n * - MANDATORY FOR SAFARI IN VOCAL MODE\r\n */\r\n const primeRetorikSpeech = (): void => {\r\n if (audioRef.current) {\r\n audioRef.current.play().catch((e) => console.warn(e))\r\n speechRecognitionAudioRef?.current && speechRecognitionAudioRef.current.play().catch((e) => console.warn(e))\r\n\r\n // Send animation start event to secure animation not playing on safari if permissions are not sufficient\r\n window.dispatchEvent(new Event('retorikSpiritEnginePlay'))\r\n }\r\n }\r\n\r\n /**\r\n * Play sound on speech recognition activation if it isn't disabled in configuration\r\n */\r\n useEffect(() => {\r\n if (useOldRemote) {\r\n if (!!speechRecognitionOptions?.enableActivationSound && activeRecognitionState === RecognitionState.Listening) {\r\n speechRecognitionAudioRef?.current?.play().catch((e) => console.warn(e))\r\n }\r\n } else {\r\n if (!!speechRecognitionOptions?.enableActivationSound) {\r\n switch (activeRecognitionState) {\r\n case RecognitionState.Listening:\r\n microphoneOpenAudioRef?.current?.play().catch((e) => console.warn(e))\r\n break\r\n case RecognitionState.Closing:\r\n case RecognitionState.ForceClosing:\r\n microphoneCloseAudioRef?.current?.play().catch((e) => console.warn(e))\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n }\r\n }, [useOldRemote, activeRecognitionState, speechRecognitionOptions])\r\n\r\n return (\r\n <React.Fragment>\r\n <audio ref={audioRef} src={audioFiles.onesecond} muted={appAvailable || loaderClosed ? muted : true} onPlay={handleStart} onEnded={handleEnd} />\r\n <audio ref={speechRecognitionAudioRef} src={audioFiles.speechrecognition} preload='auto' muted={appAvailable || loaderClosed ? muted : true} />\r\n {/* Microphone opening sound */}\r\n <audio ref={microphoneOpenAudioRef} src={audioFiles.microphoneopen} preload='auto' muted={appAvailable || loaderClosed ? muted : true} />\r\n {/* Microphone closing sound */}\r\n <audio ref={microphoneCloseAudioRef} src={audioFiles.microphoneclose} preload='auto' muted={appAvailable || loaderClosed ? muted : true} />\r\n <GdprAndLoader appAvailable={appAvailable} handleValidation={primeRetorikSpeech} />\r\n </React.Fragment>\r\n )\r\n}\r\n\r\nexport default RetorikSpeech\r\n","import { Boundary } from '../../store/models/speechTypes'\r\nimport type { SpeechSynthesisEventProps } from '@davi-ai/web-speech-cognitive-services-davi'\r\n\r\ninterface DBData {\r\n id: string\r\n value: ArrayBuffer\r\n boundaries: Array<Boundary>\r\n visemes?: Array<SpeechSynthesisEventProps>\r\n}\r\n\r\nclass IndexedDbManager {\r\n version = 1\r\n storeName = 'speechSynthesisData'\r\n\r\n checkDB = async (): Promise<boolean> => {\r\n return new Promise<boolean>((resolve) => {\r\n const request: IDBOpenDBRequest = indexedDB.open(\r\n 'retorik-framework-db',\r\n this.version\r\n )\r\n request.onsuccess = () => {\r\n resolve(true)\r\n }\r\n\r\n request.onerror = () => {\r\n resolve(false)\r\n }\r\n\r\n request.onupgradeneeded = () => {\r\n const db = request.result\r\n\r\n // If the data object store doesn't exist, create it\r\n if (!db.objectStoreNames.contains(this.storeName)) {\r\n db.createObjectStore(this.storeName, {\r\n keyPath: 'id'\r\n })\r\n }\r\n }\r\n })\r\n }\r\n\r\n addSpeechData = async (data: DBData): Promise<boolean> => {\r\n return new Promise<boolean>((resolve) => {\r\n const request: IDBOpenDBRequest = indexedDB.open(\r\n 'retorik-framework-db',\r\n this.version\r\n )\r\n\r\n request.onsuccess = () => {\r\n const db = request.result\r\n const tx = db.transaction(this.storeName, 'readwrite')\r\n const store = tx.objectStore(this.storeName)\r\n // Base 64 encode\r\n data.id = window.btoa(encodeURI(data.id))\r\n store.add(data)\r\n resolve(true)\r\n }\r\n\r\n request.onerror = () => {\r\n resolve(false)\r\n }\r\n })\r\n }\r\n\r\n getSpeechData = async (id: string): Promise<DBData | null> => {\r\n return new Promise<DBData | null>((resolve) => {\r\n const request: IDBOpenDBRequest = indexedDB.open(\r\n 'retorik-framework-db',\r\n this.version\r\n )\r\n\r\n request.onsuccess = () => {\r\n const db = request.result\r\n const tx = db.transaction(this.storeName, 'readonly')\r\n const store = tx.objectStore(this.storeName)\r\n // Base 64 encode\r\n const data = store.get(window.btoa(encodeURI(id)))\r\n data.onsuccess = () => {\r\n resolve(data.result)\r\n }\r\n }\r\n\r\n request.onerror = () => {\r\n resolve(null)\r\n }\r\n })\r\n }\r\n}\r\n\r\nexport default IndexedDbManager\r\n"],"names":[],"version":3,"file":"SynthesisPonyfillManager.f9f9a915.js.map","sourceRoot":"../"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {jsxs as $313pz$jsxs, jsx as $313pz$jsx} from "react/jsx-runtime";
|
|
2
2
|
import $313pz$react, {useState as $313pz$useState, useMemo as $313pz$useMemo, useEffect as $313pz$useEffect, useRef as $313pz$useRef} from "react";
|
|
3
|
-
import {CreationTool as $313pz$CreationTool, Object3D as $313pz$Object3D, addViseme as $313pz$addViseme, setVisemes as $313pz$setVisemes, setCharacterState as $313pz$setCharacterState, CharacterState as $313pz$CharacterState, flushLipSyncData as $313pz$flushLipSyncData, Character as $313pz$Character, presets as $313pz$presets, getCameraPosition as $313pz$getCameraPosition, getCharacterHeight as $313pz$getCharacterHeight, setLookAtCamera as $313pz$setLookAtCamera, setShowFirstTarget as $313pz$setShowFirstTarget} from "@davi-ai/react-bodyengine-three";
|
|
3
|
+
import {CreationTool as $313pz$CreationTool, Object3D as $313pz$Object3D, addViseme as $313pz$addViseme, addBlendshape as $313pz$addBlendshape, setVisemes as $313pz$setVisemes, setCharacterState as $313pz$setCharacterState, CharacterState as $313pz$CharacterState, flushLipSyncData as $313pz$flushLipSyncData, Character as $313pz$Character, presets as $313pz$presets, getCameraPosition as $313pz$getCameraPosition, getCharacterHeight as $313pz$getCharacterHeight, setLookAtCamera as $313pz$setLookAtCamera, setShowFirstTarget as $313pz$setShowFirstTarget} from "@davi-ai/react-bodyengine-three";
|
|
4
4
|
import {useDispatch as $313pz$useDispatch, useSelector as $313pz$useSelector} from "react-redux";
|
|
5
5
|
import {FilesetResolver as $313pz$FilesetResolver, FaceDetector as $313pz$FaceDetector} from "@mediapipe/tasks-vision";
|
|
6
6
|
|
|
@@ -28,20 +28,21 @@ $parcel$export(module.exports, "default", () => $22f0b0bb3c6ec1e7$export$2e2bcd8
|
|
|
28
28
|
|
|
29
29
|
var $8ItUL = parcelRequire("8ItUL");
|
|
30
30
|
|
|
31
|
-
var $4ucVo = parcelRequire("4ucVo");
|
|
32
|
-
|
|
33
31
|
var $7MbNn = parcelRequire("7MbNn");
|
|
34
32
|
|
|
35
33
|
var $gFkoW = parcelRequire("gFkoW");
|
|
36
34
|
const $22f0b0bb3c6ec1e7$var$ThreeJsWrapper = ({ agentData: agentData, visible: visible, height: height, size: size, cameraPreset: cameraPreset, calibration: calibration, centered: centered })=>{
|
|
37
35
|
const dispatch = (0, $313pz$useDispatch)();
|
|
38
36
|
const gpuData = (0, $313pz$useSelector)((state)=>state.retorikReducer.gpuData);
|
|
37
|
+
const addressData = (0, $313pz$useSelector)((state)=>state.retorikReducer.addressData);
|
|
39
38
|
const speaking = (0, $313pz$useSelector)((state)=>state.speechReducer.speaking);
|
|
40
39
|
const loaderClosed = (0, $313pz$useSelector)((state)=>state.retorikReducer.loaderClosed);
|
|
41
40
|
const recognitionState = (0, $313pz$useSelector)((state)=>state.speechReducer.activeRecognitionState);
|
|
42
41
|
const lastRecognitionInterim = (0, $313pz$useSelector)((state)=>state.speechReducer.lastRecognitionInterim);
|
|
43
42
|
const singleViseme = (0, $313pz$useSelector)((state)=>state.speechReducer.singleVisemeAdded);
|
|
43
|
+
const singleBlendShape = (0, $313pz$useSelector)((state)=>state.speechReducer.singleBlendShapeAdded);
|
|
44
44
|
const multiVisemes = (0, $313pz$useSelector)((state)=>state.speechReducer.multiVisemesAdded);
|
|
45
|
+
const multiBlendShapes = (0, $313pz$useSelector)((state)=>state.speechReducer.multiBlendShapesAdded);
|
|
45
46
|
const streamingQueue = (0, $313pz$useSelector)((state)=>state.speechReducer.streamingQueue);
|
|
46
47
|
const characterLoaded = (0, $313pz$useSelector)((state)=>state.viewReducer.characterLoaded);
|
|
47
48
|
const isMobile = (0, $313pz$useSelector)((state)=>state.viewReducer.isMobile);
|
|
@@ -52,13 +53,13 @@ const $22f0b0bb3c6ec1e7$var$ThreeJsWrapper = ({ agentData: agentData, visible: v
|
|
|
52
53
|
* Use model's source to get the right loader. Default to avaturn loader
|
|
53
54
|
*/ const type = (0, $313pz$useMemo)(()=>{
|
|
54
55
|
if (agentData.source) switch(agentData.source.toLowerCase()){
|
|
55
|
-
case (0, $
|
|
56
|
-
case (0, $
|
|
56
|
+
case (0, $8ItUL.Source3DEngine).avatarsdk:
|
|
57
|
+
case (0, $8ItUL.Source3DEngine).avatarsdkbis:
|
|
57
58
|
return (0, $313pz$CreationTool).avatarsdk;
|
|
58
|
-
case (0, $
|
|
59
|
-
case (0, $
|
|
59
|
+
case (0, $8ItUL.Source3DEngine).cc3:
|
|
60
|
+
case (0, $8ItUL.Source3DEngine).cc4:
|
|
60
61
|
return (0, $313pz$CreationTool).cc3;
|
|
61
|
-
case (0, $
|
|
62
|
+
case (0, $8ItUL.Source3DEngine).avaturn:
|
|
62
63
|
default:
|
|
63
64
|
return (0, $313pz$CreationTool).avaturn;
|
|
64
65
|
}
|
|
@@ -122,14 +123,24 @@ const $22f0b0bb3c6ec1e7$var$ThreeJsWrapper = ({ agentData: agentData, visible: v
|
|
|
122
123
|
}, [
|
|
123
124
|
singleViseme
|
|
124
125
|
]);
|
|
126
|
+
(0, $313pz$useEffect)(()=>{
|
|
127
|
+
singleBlendShape && (0, $313pz$addBlendshape)(structuredClone(singleBlendShape));
|
|
128
|
+
}, [
|
|
129
|
+
singleBlendShape
|
|
130
|
+
]);
|
|
125
131
|
(0, $313pz$useEffect)(()=>{
|
|
126
132
|
multiVisemes.length && (0, $313pz$setVisemes)(multiVisemes);
|
|
127
133
|
}, [
|
|
128
134
|
multiVisemes
|
|
129
135
|
]);
|
|
130
136
|
(0, $313pz$useEffect)(()=>{
|
|
131
|
-
if (
|
|
132
|
-
|
|
137
|
+
if (multiBlendShapes.length) for (const frame of multiBlendShapes)(0, $313pz$addBlendshape)(structuredClone(frame));
|
|
138
|
+
}, [
|
|
139
|
+
multiBlendShapes
|
|
140
|
+
]);
|
|
141
|
+
(0, $313pz$useEffect)(()=>{
|
|
142
|
+
if (speaking || !addressData.livekit?.enabled && streamingQueue.length) (0, $313pz$setCharacterState)((0, $313pz$CharacterState).speaking);
|
|
143
|
+
else if (recognitionState === (0, $8ItUL.RecognitionState).Closed) (0, $313pz$setCharacterState)((0, $313pz$CharacterState).idle);
|
|
133
144
|
else if (lastRecognitionInterim) (0, $313pz$setCharacterState)((0, $313pz$CharacterState).listening);
|
|
134
145
|
else (0, $313pz$setCharacterState)((0, $313pz$CharacterState).waiting);
|
|
135
146
|
}, [
|
|
@@ -161,7 +172,8 @@ const $22f0b0bb3c6ec1e7$var$ThreeJsWrapper = ({ agentData: agentData, visible: v
|
|
|
161
172
|
targets: targets,
|
|
162
173
|
autoLookAt: true,
|
|
163
174
|
detectGpuData: gpuData,
|
|
164
|
-
license: "fake-license"
|
|
175
|
+
license: "fake-license",
|
|
176
|
+
useBlendshapeManager: agentData.useBlendshapeManager || false
|
|
165
177
|
})
|
|
166
178
|
}),
|
|
167
179
|
!characterLoaded && /*#__PURE__*/ (0, $313pz$jsx)("div", {
|
|
@@ -643,4 +655,4 @@ var $741aef3293d0db11$export$2e2bcd8739ae039 = $741aef3293d0db11$var$FaceDetecto
|
|
|
643
655
|
|
|
644
656
|
|
|
645
657
|
|
|
646
|
-
//# sourceMappingURL=ThreeJsWrapper.
|
|
658
|
+
//# sourceMappingURL=ThreeJsWrapper.0285d280.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"mappings":"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","sources":["src/components/ChatbotAndSubtitles/ThreeJsWrapper.tsx","src/components/ChatbotAndSubtitles/CalibrationScreen.tsx","src/components/Veille/FaceDetector.tsx"],"sourcesContent":["import React, { useEffect, useMemo, useState } from 'react'\r\nimport { Character, CreationTool, setCharacterState, addViseme, addBlendshape, setVisemes, flushLipSyncData, CharacterState, presets, Object3D } from '@davi-ai/react-bodyengine-three'\r\nimport { useSelector, useDispatch } from 'react-redux'\r\nimport { RootState, storeActions, RecognitionState, Source3DEngine } from '../../store'\r\n\r\nimport type { CalibrationData } from '../../store/models/types'\r\nimport MicrophoneLoader from '../Loader/MicrophoneLoader'\r\nimport CalibrationScreen from './CalibrationScreen'\r\n\r\ninterface EyeTrackingData {\r\n webcamHeight: number\r\n webcamRotation: number\r\n ratioPixelToCentimeter: number\r\n agentEyesHeight: number\r\n distanceFromDevice: number\r\n worldDistancePerDegree: number\r\n cameraX: number\r\n cameraZ: number\r\n}\r\n\r\ninterface ThreeJsWrapperAgentData {\r\n url: string\r\n animationsUrl?: string\r\n source?: string\r\n gender: 'male' | 'female' | 'other'\r\n useBlendshapeManager?: boolean\r\n}\r\n\r\ninterface ThreeJsWrapperProps {\r\n agentData: ThreeJsWrapperAgentData\r\n visible: boolean\r\n height?: string | number\r\n size?: string | number\r\n cameraPreset?: keyof typeof presets\r\n calibration?: CalibrationData\r\n centered: boolean\r\n}\r\n\r\nconst ThreeJsWrapper = ({ agentData, visible, height, size, cameraPreset, calibration, centered }: ThreeJsWrapperProps): React.JSX.Element => {\r\n const dispatch = useDispatch()\r\n const gpuData = useSelector((state: RootState) => state.retorikReducer.gpuData)\r\n const addressData = useSelector((state: RootState) => state.retorikReducer.addressData)\r\n const speaking = useSelector((state: RootState) => state.speechReducer.speaking)\r\n const loaderClosed = useSelector((state: RootState) => state.retorikReducer.loaderClosed)\r\n const recognitionState = useSelector((state: RootState) => state.speechReducer.activeRecognitionState)\r\n const lastRecognitionInterim = useSelector((state: RootState) => state.speechReducer.lastRecognitionInterim)\r\n const singleViseme = useSelector((state: RootState) => state.speechReducer.singleVisemeAdded)\r\n const singleBlendShape = useSelector((state: RootState) => state.speechReducer.singleBlendShapeAdded)\r\n const multiVisemes = useSelector((state: RootState) => state.speechReducer.multiVisemesAdded)\r\n const multiBlendShapes = useSelector((state: RootState) => state.speechReducer.multiBlendShapesAdded)\r\n const streamingQueue = useSelector((state: RootState) => state.speechReducer.streamingQueue)\r\n const characterLoaded = useSelector((state: RootState) => state.viewReducer.characterLoaded)\r\n const isMobile = useSelector((state: RootState) => state.viewReducer.isMobile)\r\n\r\n const [targets, setTargets] = useState<Array<Object3D>>([])\r\n const [dynamicData, setDynamicData] = useState<\r\n | {\r\n webcamHeight: number\r\n ratioPixelToCentimeter: number\r\n deltaAgentHeightAgentWorldHeightInCentimeters: number\r\n cameraRotationInDegrees: number\r\n distanceFromAgentToCameraInCentimeters: number\r\n }\r\n | undefined\r\n >(undefined)\r\n const [openCalibration, setOpenCalibration] = useState<boolean>(false)\r\n\r\n /**\r\n * Use model's source to get the right loader. Default to avaturn loader\r\n */\r\n const type = useMemo<CreationTool | null>(() => {\r\n if (agentData.source) {\r\n switch (agentData.source.toLowerCase()) {\r\n case Source3DEngine.avatarsdk:\r\n case Source3DEngine.avatarsdkbis:\r\n return CreationTool.avatarsdk\r\n case Source3DEngine.cc3:\r\n case Source3DEngine.cc4:\r\n return CreationTool.cc3\r\n case Source3DEngine.avaturn:\r\n default:\r\n return CreationTool.avaturn\r\n }\r\n }\r\n\r\n return CreationTool.avaturn\r\n }, [agentData])\r\n\r\n useEffect(() => {\r\n if ((!calibration?.static?.enabled && !calibration?.dynamic?.enabled) || isMobile) dispatch(storeActions.view.setCalibrationCompleted(true))\r\n }, [calibration, isMobile])\r\n\r\n useEffect(() => {\r\n // Check if we should open the calibration screen or not\r\n if ((calibration?.static?.enabled || calibration?.dynamic?.enabled) && !isMobile) {\r\n // If there are some static data in the props or the local storage, we can directly set the targets without opening the calibration screen\r\n if (calibration?.static?.enabled && calibration.static.staticTarget) {\r\n const o = new Object3D()\r\n o.position.set(calibration.static.staticTarget.x, calibration.static.staticTarget.y, calibration.static.staticTarget.z)\r\n setTargets([o])\r\n setOpenCalibration(false)\r\n dispatch(storeActions.view.setCalibrationCompleted(true))\r\n } else if (calibration?.static?.enabled && calibration.static.loadStaticTargetFromLocalStorage && localStorage.getItem('Retorik.Framework.Static.Target')) {\r\n const calibrationData = JSON.parse(localStorage.getItem('Retorik.Framework.Static.Target') || '{}') as {\r\n x: number\r\n y: number\r\n z: number\r\n }\r\n const o = new Object3D()\r\n o.position.set(calibrationData.x, calibrationData.y, calibrationData.z)\r\n setTargets([o])\r\n setOpenCalibration(false)\r\n dispatch(storeActions.view.setCalibrationCompleted(true))\r\n } else if (calibration.dynamic?.enabled && calibration.dynamic.dynamicData) {\r\n // Check if all the mandatory dynamic data are in the props\r\n if (\r\n calibration.dynamic.dynamicData.webcamHeight &&\r\n calibration.dynamic.dynamicData.ratioPixelToCentimeter &&\r\n calibration.dynamic.dynamicData.deltaAgentHeightAgentWorldHeightInCentimeters &&\r\n calibration.dynamic.dynamicData.distanceFromAgentToCameraInCentimeters\r\n ) {\r\n setDynamicData({ ...calibration.dynamic.dynamicData, cameraRotationInDegrees: calibration.dynamic.dynamicData.cameraRotationInDegrees || 0 })\r\n }\r\n\r\n setOpenCalibration(true)\r\n } else if (calibration.dynamic?.enabled && calibration.dynamic.loadDynamicDataFromLocalStorage && localStorage.getItem('Retorik.Framework.Dynamic.Data')) {\r\n // Check if the local storage data is complete\r\n const calibrationData = JSON.parse(localStorage.getItem('Retorik.Framework.Dynamic.Data') || '{}')\r\n if (\r\n calibrationData.webcamHeight &&\r\n calibrationData.ratioPixelToCentimeter &&\r\n calibrationData.deltaAgentHeightAgentWorldHeightInCentimeters &&\r\n calibrationData.distanceFromAgentToCameraInCentimeters\r\n ) {\r\n setDynamicData({ ...calibrationData, cameraRotationInDegrees: calibrationData.cameraRotationInDegrees || 0 })\r\n }\r\n\r\n setOpenCalibration(true)\r\n } else {\r\n setOpenCalibration(true)\r\n }\r\n } else {\r\n setOpenCalibration(false)\r\n dispatch(storeActions.view.setCalibrationCompleted(true))\r\n }\r\n }, [calibration, isMobile])\r\n\r\n useEffect(() => {\r\n singleViseme && addViseme(singleViseme)\r\n }, [singleViseme])\r\n\r\n useEffect(() => {\r\n singleBlendShape && addBlendshape(structuredClone(singleBlendShape))\r\n }, [singleBlendShape])\r\n\r\n useEffect(() => {\r\n multiVisemes.length && setVisemes(multiVisemes)\r\n }, [multiVisemes])\r\n\r\n useEffect(() => {\r\n if (multiBlendShapes.length) {\r\n for (const frame of multiBlendShapes) {\r\n addBlendshape(structuredClone(frame))\r\n }\r\n }\r\n }, [multiBlendShapes])\r\n\r\n useEffect(() => {\r\n if (speaking || (!addressData.livekit?.enabled && streamingQueue.length)) {\r\n setCharacterState(CharacterState.speaking)\r\n } else if (recognitionState === RecognitionState.Closed) {\r\n setCharacterState(CharacterState.idle)\r\n } else if (lastRecognitionInterim) {\r\n setCharacterState(CharacterState.listening)\r\n } else {\r\n setCharacterState(CharacterState.waiting)\r\n }\r\n }, [speaking, recognitionState, lastRecognitionInterim, streamingQueue])\r\n\r\n useEffect(() => {\r\n !speaking && flushLipSyncData()\r\n }, [speaking])\r\n\r\n return (\r\n <React.Fragment>\r\n <div\r\n style={{\r\n height: size || '100%',\r\n paddingTop: height || 0,\r\n visibility: characterLoaded && visible ? 'visible' : 'hidden'\r\n }}\r\n >\r\n {type && (\r\n <Character\r\n url={agentData.url}\r\n type={type}\r\n animationsUrl={agentData?.animationsUrl || 'https://cdn.retorik.ai/bodyengine-three/animations/cc4/female/standing/'}\r\n gender={agentData?.gender === 'male' ? 'male' : 'female'}\r\n onLoadingCompleted={() => dispatch(storeActions.view.setCharacterLoaded(true))}\r\n camera={presets[cameraPreset || 'default']}\r\n targets={targets}\r\n autoLookAt={true}\r\n detectGpuData={gpuData}\r\n license='fake-license'\r\n useBlendshapeManager={agentData.useBlendshapeManager || false}\r\n />\r\n )}\r\n </div>\r\n {!characterLoaded && (\r\n <div className='rf-absolute rf-top-0 rf-left-0 rf-w-full rf-h-full rf-flex rf-justify-center rf-items-center'>\r\n <div className='rf-w-1/4 rf-aspect-square'>\r\n <MicrophoneLoader />\r\n </div>\r\n </div>\r\n )}\r\n\r\n {openCalibration && loaderClosed && (\r\n <CalibrationScreen\r\n centered={centered}\r\n staticCalibrationEnabled={!!calibration?.static?.enabled}\r\n dynamicCalibrationEnabled={!!calibration?.dynamic?.enabled}\r\n setTargets={(targets: Array<Object3D>) => setTargets(targets)}\r\n dynamicData={dynamicData}\r\n />\r\n )}\r\n </React.Fragment>\r\n )\r\n}\r\n\r\nexport default ThreeJsWrapper\r\nexport type { EyeTrackingData }\r\n","import React, { useEffect, useRef, useState } from 'react'\r\nimport { Object3D, getCameraPosition, getCharacterHeight, setLookAtCamera, setShowFirstTarget } from '@davi-ai/react-bodyengine-three'\r\nimport type { Detection } from '@mediapipe/tasks-vision'\r\nimport { useSelector, useDispatch } from 'react-redux'\r\nimport { RootState, storeActions } from '../../store'\r\nimport FaceDetector from '../Veille/FaceDetector'\r\n\r\ninterface CalibrationScreenProps {\r\n centered: boolean\r\n staticCalibrationEnabled: boolean\r\n dynamicCalibrationEnabled: boolean\r\n dynamicData?: {\r\n webcamHeight: number\r\n ratioPixelToCentimeter: number\r\n deltaAgentHeightAgentWorldHeightInCentimeters: number\r\n cameraRotationInDegrees: number\r\n distanceFromAgentToCameraInCentimeters: number\r\n }\r\n setTargets: (targets: Array<Object3D>) => void\r\n}\r\n\r\nenum CalibrationMode {\r\n none = 1,\r\n static,\r\n dynamic\r\n}\r\n\r\nconst CalibrationScreen = ({ centered, staticCalibrationEnabled, dynamicCalibrationEnabled, dynamicData, setTargets }: CalibrationScreenProps): React.JSX.Element => {\r\n const dispatch = useDispatch()\r\n const cameraPosition = getCameraPosition()\r\n const characterHeight = getCharacterHeight()\r\n const characterLoaded = useSelector((state: RootState) => state.viewReducer.characterLoaded)\r\n const calibrationCompleted = useSelector((state: RootState) => state.viewReducer.calibrationCompleted)\r\n\r\n const [calibrationMode, setCalibrationMode] = useState<CalibrationMode>(dynamicData ? CalibrationMode.dynamic : CalibrationMode.none)\r\n const [distanceFromDevice, setDistanceFromDevice] = useState<number>(dynamicData?.distanceFromAgentToCameraInCentimeters || 0)\r\n const [webcamRotation, setWebcamRotation] = useState<number>(0)\r\n const [agentEyesHeightOnScreen, setAgentEyesHeightOnScreen] = useState<number>(0)\r\n const [worldDistancePerDegree, setWorldDistancePerDegree] = useState<number>(0)\r\n const [currentAngleInDegrees, setCurrentAngleInDegrees] = useState<number>(0)\r\n const [cameraX, setCameraX] = useState<number>(0)\r\n const [cameraY, setCameraY] = useState<number>(0)\r\n const [cameraZ, setCameraZ] = useState<number>(0)\r\n\r\n const cameraXRef = useRef<number>(0)\r\n const cameraYRef = useRef<number>(0)\r\n const cameraZRef = useRef<number>(0)\r\n const currentAngleInDegreesRef = useRef<number>(0)\r\n const webcamHeightRef = useRef<number>(dynamicData?.webcamHeight || 0)\r\n const userEyesHeightRef = useRef<number>(0)\r\n const agentEyesHeightRef = useRef<number>(0)\r\n const distanceFromDeviceRef = useRef<number>(0)\r\n const webcamRotatedRef = useRef<number>(dynamicData?.cameraRotationInDegrees || 0)\r\n const deltaAgentHeightAgentWorldHeightInCentimetersRef = useRef<number>(dynamicData?.deltaAgentHeightAgentWorldHeightInCentimeters || 0)\r\n const ratioPixelToCentimeterRef = useRef<number>(dynamicData?.ratioPixelToCentimeter || 0)\r\n const calibrationCompletedRef = useRef<boolean>(calibrationCompleted)\r\n const counterRef = useRef<number>(0)\r\n\r\n useEffect(() => {\r\n // If dynamic data are given, let's validate immediately to set calibratoin as completed\r\n dynamicData && handleValidate()\r\n }, [])\r\n\r\n useEffect(() => {\r\n characterLoaded && !dynamicData && setLookAtCamera(true)\r\n\r\n return () => {\r\n setLookAtCamera(false)\r\n }\r\n }, [characterLoaded])\r\n\r\n useEffect(() => {\r\n if (worldDistancePerDegree && !dynamicData) {\r\n const o = new Object3D()\r\n o.position.set(cameraX, cameraY + currentAngleInDegrees * worldDistancePerDegree, Math.max(cameraZ / 5, 0.3))\r\n setTargets([o])\r\n }\r\n }, [currentAngleInDegrees, worldDistancePerDegree, distanceFromDevice, cameraX, cameraY, cameraZ])\r\n\r\n useEffect(() => {\r\n if (cameraPosition && !(cameraPosition.x === 0 && cameraPosition.y === 0)) {\r\n const zDistanceCameraPlusUser = cameraPosition.z + distanceFromDevice / 100\r\n setCameraX(cameraPosition.x)\r\n setCameraY(cameraPosition.y)\r\n setCameraZ(zDistanceCameraPlusUser)\r\n cameraXRef.current = cameraPosition.x\r\n cameraYRef.current = cameraPosition.y\r\n cameraZRef.current = zDistanceCameraPlusUser\r\n // Get Y world distance for one degree using tangent. The z distance is divided by 5 with 0.3 at the lowest to show a visible height bar when calibrating\r\n setWorldDistancePerDegree(Math.tan(Math.PI / 180) * Math.max(zDistanceCameraPlusUser / 5, 0.3))\r\n }\r\n }, [cameraPosition, distanceFromDevice])\r\n\r\n useEffect(() => {\r\n if (!dynamicData) {\r\n characterHeight && agentEyesHeightOnScreen && (deltaAgentHeightAgentWorldHeightInCentimetersRef.current = (characterHeight - characterHeight / 16) * 100 - agentEyesHeightOnScreen)\r\n }\r\n }, [characterHeight, agentEyesHeightOnScreen])\r\n\r\n useEffect(() => {\r\n !dynamicData && (webcamRotatedRef.current = webcamRotation)\r\n }, [webcamRotation])\r\n\r\n useEffect(() => {\r\n calibrationCompletedRef.current = calibrationCompleted\r\n }, [calibrationCompleted])\r\n\r\n useEffect(() => {\r\n if (!dynamicData && calibrationMode === CalibrationMode.static) {\r\n setShowFirstTarget(!calibrationCompleted)\r\n }\r\n }, [calibrationMode, calibrationCompleted])\r\n\r\n const handleReset = () => {\r\n setCurrentAngleInDegrees(0)\r\n currentAngleInDegreesRef.current = 0\r\n }\r\n\r\n const handleValidate = () => {\r\n setLookAtCamera(false)\r\n if (calibrationMode === CalibrationMode.static) {\r\n // In static mode, store the target in local storage to be able to reuse it later and avoid asking the user to calibrate again if the data are valid\r\n localStorage.setItem('Retorik.Framework.Static.Target', JSON.stringify({ x: cameraX, y: cameraY + currentAngleInDegrees * worldDistancePerDegree, z: cameraZ }))\r\n } else if (calibrationMode === CalibrationMode.dynamic && ratioPixelToCentimeterRef.current) {\r\n localStorage.setItem(\r\n 'Retorik.Framework.Dynamic.Data',\r\n JSON.stringify({\r\n webcamHeight: webcamHeightRef.current,\r\n ratioPixelToCentimeter: ratioPixelToCentimeterRef.current,\r\n deltaAgentHeightAgentWorldHeightInCentimeters: deltaAgentHeightAgentWorldHeightInCentimetersRef.current,\r\n cameraRotationInDegrees: webcamRotatedRef.current,\r\n distanceFromAgentToCameraInCentimeters: distanceFromDeviceRef.current\r\n })\r\n )\r\n setTargets([])\r\n }\r\n\r\n dispatch(storeActions.view.setCalibrationCompleted(true))\r\n }\r\n\r\n const handleFaceDetected = (detections?: Array<Detection>, width?: number, height?: number): void => {\r\n counterRef.current++\r\n if (detections?.length && width && height) {\r\n // The detections are inverted in X and Y axis (the origin is the top right corner of the image)\r\n const webcamPositionY = webcamRotatedRef.current === 0 ? height / 2 : width / 2\r\n const userPositionY = webcamRotatedRef.current === 0 ? height * (1 - detections[0].keypoints[0].y) : width * (1 - detections[0].keypoints[0].x)\r\n\r\n if (calibrationCompletedRef.current) {\r\n // Check if the mandatory data have been filled (webcam / agent / user heights + distance user <-> device)\r\n if (webcamHeightRef.current && ratioPixelToCentimeterRef.current && deltaAgentHeightAgentWorldHeightInCentimetersRef.current !== 0) {\r\n const deltaHeightInPixels = webcamPositionY - userPositionY\r\n const userEyesHeightInCentimeters = webcamHeightRef.current - deltaHeightInPixels * ratioPixelToCentimeterRef.current\r\n const targetYInWorldCoordinates = (userEyesHeightInCentimeters + deltaAgentHeightAgentWorldHeightInCentimetersRef.current) / 100\r\n\r\n const o = new Object3D()\r\n o.position.set(cameraXRef.current, targetYInWorldCoordinates, cameraZRef.current)\r\n setTargets([o])\r\n }\r\n } else {\r\n // The detections are inverted in X and Y axis (the origin is the top right corner of the image)\r\n if (webcamHeightRef.current && userEyesHeightRef.current && distanceFromDeviceRef.current) {\r\n // Get the difference in height between the webcam and the user's eyes in cm, then use the detection to get the same difference in pixels on the webcam's image\r\n const deltaHeightInCentimeters = Math.abs(webcamHeightRef.current - userEyesHeightRef.current)\r\n const deltaHeightInPixels = Math.abs(webcamPositionY - userPositionY)\r\n\r\n deltaHeightInPixels && (ratioPixelToCentimeterRef.current = deltaHeightInCentimeters / deltaHeightInPixels)\r\n }\r\n }\r\n }\r\n }\r\n\r\n return (\r\n <div\r\n id='retorik-framework-animation-container-calibration'\r\n className={`rf-absolute rf-top-0 rf-h-full rf-w-full rf-grid rf-grid-cols-1 rf-grid-rows-1 ${!centered && 'landscape-retorik:rf-translate-x-1/4'}`}\r\n >\r\n {calibrationMode === CalibrationMode.dynamic && (\r\n <div className='rf-relative rf-z-1 rf-h-full rf-w-full rf-col-start-1 rf-col-span-1 rf-row-start-1 rf-row-span-1 rf-flex rf-justify-start rf-items-start'>\r\n <FaceDetector detectionThreshold={0.8} onFaceDetected={handleFaceDetected} showThumbnail={!calibrationCompleted} rotation={webcamRotation} />\r\n </div>\r\n )}\r\n\r\n {!calibrationCompleted && (\r\n <React.Fragment>\r\n {calibrationMode === CalibrationMode.none ? (\r\n <div className='rf-h-full rf-w-full rf-col-start-1 rf-col-span-1 rf-row-start-1 rf-row-span-1 rf-flex rf-flex-col rf-justify-center rf-items-center rf-gap-4 rf-bg-white rf-bg-opacity-50'>\r\n <p className='rf-text-medium-size-auto'>Choisissez un mode de calibrage :</p>\r\n <div className='rf-flex rf-flex-row rf-gap-4'>\r\n {staticCalibrationEnabled && (\r\n <div\r\n className='rf-px-4 rf-py-2 rf-border rf-border-primary rf-rounded-lg rf-bg-primary rf-bg-opacity-50 rf-cursor-pointer'\r\n onClick={() => setCalibrationMode(CalibrationMode.static)}\r\n >\r\n STATIQUE\r\n </div>\r\n )}\r\n\r\n {dynamicCalibrationEnabled && (\r\n <div\r\n className='rf-px-4 rf-py-2 rf-border rf-border-primary rf-rounded-lg rf-bg-primary rf-bg-opacity-50 rf-cursor-pointer'\r\n onClick={() => setCalibrationMode(CalibrationMode.dynamic)}\r\n >\r\n DYNAMIQUE\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n ) : (\r\n <div className='rf-relative rf-h-full rf-w-full rf-col-start-1 rf-col-span-1 rf-row-start-1 rf-row-span-1 rf-flex rf-flex-col rf-justify-center rf-gap-4'>\r\n {calibrationMode === CalibrationMode.dynamic ? (\r\n <div className='rf-absolute rf-left-32 rf-flex rf-flex-col rf-justify-center rf-items-center rf-gap-4'>\r\n <div className='rf-grid rf-grid-cols-2 rf-grid-rows-3 rf-gap-4'>\r\n <p className='rf-font-bold'>Hauteur webcam (en cm)</p>\r\n <input\r\n type='number'\r\n min={0}\r\n max={300}\r\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\r\n webcamHeightRef.current = parseInt(e.target.value!)\r\n }}\r\n />\r\n <p className='rf-font-bold'>Votre taille (en cm)</p>\r\n <input\r\n type='number'\r\n min={50}\r\n max={300}\r\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\r\n // We estimate the height of the user's eyes is 12 cm less than their total height\r\n userEyesHeightRef.current = parseInt(e.target.value!) - 12\r\n }}\r\n />\r\n <p className='rf-font-bold'>Hauteur des yeux de l'agent (en cm)</p>\r\n <input\r\n type='number'\r\n min={50}\r\n max={300}\r\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\r\n setAgentEyesHeightOnScreen(parseInt(e.target.value!))\r\n agentEyesHeightRef.current = parseInt(e.target.value!)\r\n }}\r\n />\r\n <p className='rf-font-bold'>Distance utilisateur - borne (en cm)</p>\r\n <input\r\n type='number'\r\n min={20}\r\n max={100}\r\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\r\n setDistanceFromDevice(parseInt(e.target.value!))\r\n distanceFromDeviceRef.current = parseInt(e.target.value!)\r\n }}\r\n />\r\n <p className='rf-font-bold'>Rotation de la webcam (en degrés)</p>\r\n <div className='rf-flex rf-flex-row rf-gap-2'>\r\n <button\r\n className={`rf-px-2 rf-py-1 rf-border rf-border-primary rf-rounded-lg rf-bg-primary rf-bg-opacity-50 rf-cursor-pointer ${webcamRotation === 0 && 'rf-bg-opacity-100'}`}\r\n onClick={() => setWebcamRotation(0)}\r\n >\r\n 0\r\n </button>\r\n <button\r\n className={`rf-px-2 rf-py-1 rf-border rf-border-primary rf-rounded-lg rf-bg-primary rf-bg-opacity-50 rf-cursor-pointer ${webcamRotation === 90 && 'rf-bg-opacity-100'}`}\r\n onClick={() => setWebcamRotation(90)}\r\n >\r\n 90\r\n </button>\r\n <button\r\n className={`rf-px-2 rf-py-1 rf-border rf-border-primary rf-rounded-lg rf-bg-primary rf-bg-opacity-50 rf-cursor-pointer ${webcamRotation === -90 && 'rf-bg-opacity-100'}`}\r\n onClick={() => setWebcamRotation(-90)}\r\n >\r\n -90\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div className='rf-h-16 rf-w-16 rf-flex rf-justify-center rf-items-center rf-bg-white rf-border rf-border-black rf-rounded-lg hover: rf-cursor-pointer' onClick={handleValidate}>\r\n Done\r\n </div>\r\n </div>\r\n ) : (\r\n <div className='rf-ml-4 rf-flex rf-flex-col rf-gap-4'>\r\n <div className='rf-flex rf-flex-row rf-items-center rf-gap-4'>\r\n <input\r\n type='range'\r\n min={-25}\r\n max={25}\r\n step={1}\r\n value={currentAngleInDegrees}\r\n onChange={(e) => {\r\n const val = parseInt(e.target.value)\r\n setCurrentAngleInDegrees(val)\r\n currentAngleInDegreesRef.current = val\r\n }}\r\n className='rf-range-vertical rf-w-8 rf-h-80 rf-appearance-none rf-border rf-border-black rf-rounded-lg rf-cursor-pointer'\r\n style={{ writingMode: 'vertical-lr', direction: 'rtl' }}\r\n />\r\n <div className='rf-w-fit rf-p-4 rf-flex rf-flex-col rf-justify-center rf-gap-2 rf-bg-white rf-border rf-border-black rf-rounded-lg'>\r\n <p>Position actuelle de la cible : </p>\r\n <p>{`x: ${cameraX}`}</p>\r\n <p>{`y: ${cameraY + (currentAngleInDegrees ? currentAngleInDegrees * worldDistancePerDegree : 0)}`}</p>\r\n <p>{`z: ${Math.max(cameraZ / 5, 0.3)}`}</p>\r\n <p>{`angle: ${currentAngleInDegrees}°`}</p>\r\n </div>\r\n </div>\r\n\r\n <div className='rf-flex rf-flex-row rf-gap-2'>\r\n <div className='rf-h-10 rf-px-4 rf-flex rf-justify-center rf-items-center rf-bg-white rf-border rf-border-black rf-rounded-lg rf-cursor-pointer' onClick={() => handleReset()}>\r\n Reset\r\n </div>\r\n <div className='rf-h-10 rf-px-4 rf-flex rf-justify-center rf-items-center rf-bg-white rf-border rf-border-black rf-rounded-lg rf-cursor-pointer' onClick={handleValidate}>\r\n Done\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n </React.Fragment>\r\n )}\r\n </div>\r\n )\r\n}\r\n\r\nexport default CalibrationScreen\r\n","import React, { useEffect, useState, useRef } from 'react'\r\nimport { FaceDetector as MediapipeFaceDetector, FilesetResolver, Detection } from '@mediapipe/tasks-vision'\r\n\r\ninterface FaceDetectorProps {\r\n detectionThreshold: number\r\n onFaceDetected: (detections?: Array<Detection>, imageWidth?: number, imageHeight?: number) => void\r\n showThumbnail?: boolean\r\n rotation?: number\r\n}\r\n\r\nconst runningMode = 'VIDEO'\r\nlet lastVideoTime = -1\r\nconst defaultConstraints: MediaStreamConstraints = {\r\n video: {\r\n facingMode: 'user'\r\n }\r\n}\r\n\r\nconst FaceDetector = ({ detectionThreshold, onFaceDetected, showThumbnail, rotation }: FaceDetectorProps): React.JSX.Element => {\r\n const [webcamWidth, setWebcamWidth] = useState<number>(0)\r\n const [webcamHeight, setWebcamHeight] = useState<number>(0)\r\n const [faceDetector, setFaceDetector] = useState<MediapipeFaceDetector | undefined>()\r\n const videoRef = useRef<HTMLVideoElement>(null)\r\n const rotationRef = useRef<number>(rotation || 0)\r\n\r\n useEffect(() => {\r\n rotationRef.current = rotation || 0\r\n }, [rotation])\r\n\r\n useEffect(() => {\r\n const createfaceDetector = async () => {\r\n const vision = await FilesetResolver.forVisionTasks('https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.0/wasm')\r\n const newFaceDetector = await MediapipeFaceDetector.createFromOptions(vision, {\r\n baseOptions: {\r\n modelAssetPath: `https://storage.googleapis.com/mediapipe-models/face_detector/blaze_face_short_range/float16/1/blaze_face_short_range.tflite`,\r\n delegate: 'GPU'\r\n },\r\n runningMode: runningMode\r\n })\r\n\r\n newFaceDetector && setFaceDetector(newFaceDetector)\r\n }\r\n\r\n const initializefaceDetector = async () => {\r\n navigator.mediaDevices\r\n .getUserMedia(defaultConstraints)\r\n .then((display) => {\r\n const settings = display.getVideoTracks()[0].getSettings()\r\n setWebcamWidth(settings.width || 0)\r\n setWebcamHeight(settings.height || 0)\r\n createfaceDetector()\r\n })\r\n .catch((error) => console.warn('Retorik Framework > an error occured when trying to use the webcam : ', error))\r\n }\r\n\r\n initializefaceDetector()\r\n }, [])\r\n\r\n const predictWebcam = async () => {\r\n if (faceDetector && videoRef.current) {\r\n let startTimeMs = performance.now()\r\n\r\n // Detect faces using detectForVideo\r\n if (videoRef.current.currentTime !== lastVideoTime) {\r\n lastVideoTime = videoRef.current.currentTime\r\n const detections = faceDetector.detectForVideo(videoRef.current, startTimeMs, { rotationDegrees: rotationRef.current }).detections\r\n\r\n if (detections.length) {\r\n const score = detections[0].categories[0].score\r\n score > detectionThreshold && onFaceDetected(detections, videoRef.current.videoWidth, videoRef.current.videoHeight)\r\n }\r\n }\r\n }\r\n\r\n // Call this function again to keep predicting when the browser is ready\r\n window.requestAnimationFrame(predictWebcam)\r\n }\r\n\r\n useEffect(() => {\r\n if (faceDetector && videoRef.current) {\r\n // Activate the webcam stream\r\n navigator.mediaDevices\r\n .getUserMedia(defaultConstraints)\r\n .then((stream) => {\r\n if (videoRef.current) {\r\n videoRef.current.srcObject = stream\r\n videoRef.current.addEventListener('loadeddata', predictWebcam)\r\n }\r\n })\r\n .catch((err) => {\r\n console.error(err)\r\n })\r\n }\r\n }, [faceDetector])\r\n\r\n return (\r\n <div id='retorik-framework-face-detector' className={`rf-absolute rf-top-0 rf-left-0 ${!showThumbnail && 'rf-invisible'}`}>\r\n <video\r\n ref={videoRef}\r\n src=''\r\n autoPlay\r\n style={{\r\n rotate: `${rotation}deg`,\r\n width: showThumbnail ? webcamWidth / 2 : webcamWidth,\r\n height: showThumbnail ? webcamHeight / 2 : webcamHeight\r\n }}\r\n />\r\n </div>\r\n )\r\n}\r\n\r\nexport default FaceDetector\r\n"],"names":[],"version":3,"file":"ThreeJsWrapper.0285d280.js.map"}
|
|
@@ -41,8 +41,6 @@ $parcel$export(module.exports, "default", () => $929a5fce6d871a46$export$2e2bcd8
|
|
|
41
41
|
|
|
42
42
|
var $kpW3P = parcelRequire("kpW3P");
|
|
43
43
|
|
|
44
|
-
var $7WHA7 = parcelRequire("7WHA7");
|
|
45
|
-
|
|
46
44
|
var $gp19G = parcelRequire("gp19G");
|
|
47
45
|
|
|
48
46
|
var $dZyZK = parcelRequire("dZyZK");
|
|
@@ -50,12 +48,15 @@ const $929a5fce6d871a46$var$ThreeJsWrapper = ({ agentData: agentData, visible: v
|
|
|
50
48
|
var _calibration_static, _calibration_dynamic;
|
|
51
49
|
const dispatch = (0, $4gYsi$reactredux.useDispatch)();
|
|
52
50
|
const gpuData = (0, $4gYsi$reactredux.useSelector)((state)=>state.retorikReducer.gpuData);
|
|
51
|
+
const addressData = (0, $4gYsi$reactredux.useSelector)((state)=>state.retorikReducer.addressData);
|
|
53
52
|
const speaking = (0, $4gYsi$reactredux.useSelector)((state)=>state.speechReducer.speaking);
|
|
54
53
|
const loaderClosed = (0, $4gYsi$reactredux.useSelector)((state)=>state.retorikReducer.loaderClosed);
|
|
55
54
|
const recognitionState = (0, $4gYsi$reactredux.useSelector)((state)=>state.speechReducer.activeRecognitionState);
|
|
56
55
|
const lastRecognitionInterim = (0, $4gYsi$reactredux.useSelector)((state)=>state.speechReducer.lastRecognitionInterim);
|
|
57
56
|
const singleViseme = (0, $4gYsi$reactredux.useSelector)((state)=>state.speechReducer.singleVisemeAdded);
|
|
57
|
+
const singleBlendShape = (0, $4gYsi$reactredux.useSelector)((state)=>state.speechReducer.singleBlendShapeAdded);
|
|
58
58
|
const multiVisemes = (0, $4gYsi$reactredux.useSelector)((state)=>state.speechReducer.multiVisemesAdded);
|
|
59
|
+
const multiBlendShapes = (0, $4gYsi$reactredux.useSelector)((state)=>state.speechReducer.multiBlendShapesAdded);
|
|
59
60
|
const streamingQueue = (0, $4gYsi$reactredux.useSelector)((state)=>state.speechReducer.streamingQueue);
|
|
60
61
|
const characterLoaded = (0, $4gYsi$reactredux.useSelector)((state)=>state.viewReducer.characterLoaded);
|
|
61
62
|
const isMobile = (0, $4gYsi$reactredux.useSelector)((state)=>state.viewReducer.isMobile);
|
|
@@ -66,13 +67,13 @@ const $929a5fce6d871a46$var$ThreeJsWrapper = ({ agentData: agentData, visible: v
|
|
|
66
67
|
* Use model's source to get the right loader. Default to avaturn loader
|
|
67
68
|
*/ const type = (0, $4gYsi$react.useMemo)(()=>{
|
|
68
69
|
if (agentData.source) switch(agentData.source.toLowerCase()){
|
|
69
|
-
case (0, $
|
|
70
|
-
case (0, $
|
|
70
|
+
case (0, $kpW3P.Source3DEngine).avatarsdk:
|
|
71
|
+
case (0, $kpW3P.Source3DEngine).avatarsdkbis:
|
|
71
72
|
return (0, $4gYsi$daviaireactbodyenginethree.CreationTool).avatarsdk;
|
|
72
|
-
case (0, $
|
|
73
|
-
case (0, $
|
|
73
|
+
case (0, $kpW3P.Source3DEngine).cc3:
|
|
74
|
+
case (0, $kpW3P.Source3DEngine).cc4:
|
|
74
75
|
return (0, $4gYsi$daviaireactbodyenginethree.CreationTool).cc3;
|
|
75
|
-
case (0, $
|
|
76
|
+
case (0, $kpW3P.Source3DEngine).avaturn:
|
|
76
77
|
default:
|
|
77
78
|
return (0, $4gYsi$daviaireactbodyenginethree.CreationTool).avaturn;
|
|
78
79
|
}
|
|
@@ -139,14 +140,25 @@ const $929a5fce6d871a46$var$ThreeJsWrapper = ({ agentData: agentData, visible: v
|
|
|
139
140
|
}, [
|
|
140
141
|
singleViseme
|
|
141
142
|
]);
|
|
143
|
+
(0, $4gYsi$react.useEffect)(()=>{
|
|
144
|
+
singleBlendShape && (0, $4gYsi$daviaireactbodyenginethree.addBlendshape)(structuredClone(singleBlendShape));
|
|
145
|
+
}, [
|
|
146
|
+
singleBlendShape
|
|
147
|
+
]);
|
|
142
148
|
(0, $4gYsi$react.useEffect)(()=>{
|
|
143
149
|
multiVisemes.length && (0, $4gYsi$daviaireactbodyenginethree.setVisemes)(multiVisemes);
|
|
144
150
|
}, [
|
|
145
151
|
multiVisemes
|
|
146
152
|
]);
|
|
147
153
|
(0, $4gYsi$react.useEffect)(()=>{
|
|
148
|
-
if (
|
|
149
|
-
|
|
154
|
+
if (multiBlendShapes.length) for (const frame of multiBlendShapes)(0, $4gYsi$daviaireactbodyenginethree.addBlendshape)(structuredClone(frame));
|
|
155
|
+
}, [
|
|
156
|
+
multiBlendShapes
|
|
157
|
+
]);
|
|
158
|
+
(0, $4gYsi$react.useEffect)(()=>{
|
|
159
|
+
var _addressData_livekit;
|
|
160
|
+
if (speaking || !((_addressData_livekit = addressData.livekit) === null || _addressData_livekit === void 0 ? void 0 : _addressData_livekit.enabled) && streamingQueue.length) (0, $4gYsi$daviaireactbodyenginethree.setCharacterState)((0, $4gYsi$daviaireactbodyenginethree.CharacterState).speaking);
|
|
161
|
+
else if (recognitionState === (0, $kpW3P.RecognitionState).Closed) (0, $4gYsi$daviaireactbodyenginethree.setCharacterState)((0, $4gYsi$daviaireactbodyenginethree.CharacterState).idle);
|
|
150
162
|
else if (lastRecognitionInterim) (0, $4gYsi$daviaireactbodyenginethree.setCharacterState)((0, $4gYsi$daviaireactbodyenginethree.CharacterState).listening);
|
|
151
163
|
else (0, $4gYsi$daviaireactbodyenginethree.setCharacterState)((0, $4gYsi$daviaireactbodyenginethree.CharacterState).waiting);
|
|
152
164
|
}, [
|
|
@@ -178,7 +190,8 @@ const $929a5fce6d871a46$var$ThreeJsWrapper = ({ agentData: agentData, visible: v
|
|
|
178
190
|
targets: targets,
|
|
179
191
|
autoLookAt: true,
|
|
180
192
|
detectGpuData: gpuData,
|
|
181
|
-
license: "fake-license"
|
|
193
|
+
license: "fake-license",
|
|
194
|
+
useBlendshapeManager: agentData.useBlendshapeManager || false
|
|
182
195
|
})
|
|
183
196
|
}),
|
|
184
197
|
!characterLoaded && /*#__PURE__*/ (0, $4gYsi$reactjsxruntime.jsx)("div", {
|
|
@@ -660,4 +673,4 @@ var $8d9a75d3aaaf531b$export$2e2bcd8739ae039 = $8d9a75d3aaaf531b$var$FaceDetecto
|
|
|
660
673
|
|
|
661
674
|
|
|
662
675
|
|
|
663
|
-
//# sourceMappingURL=ThreeJsWrapper.
|
|
676
|
+
//# sourceMappingURL=ThreeJsWrapper.ad746197.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"mappings":"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","sources":["src/components/ChatbotAndSubtitles/ThreeJsWrapper.tsx","src/components/ChatbotAndSubtitles/CalibrationScreen.tsx","src/components/Veille/FaceDetector.tsx"],"sourcesContent":["import React, { useEffect, useMemo, useState } from 'react'\r\nimport { Character, CreationTool, setCharacterState, addViseme, addBlendshape, setVisemes, flushLipSyncData, CharacterState, presets, Object3D } from '@davi-ai/react-bodyengine-three'\r\nimport { useSelector, useDispatch } from 'react-redux'\r\nimport { RootState, storeActions, RecognitionState, Source3DEngine } from '../../store'\r\n\r\nimport type { CalibrationData } from '../../store/models/types'\r\nimport MicrophoneLoader from '../Loader/MicrophoneLoader'\r\nimport CalibrationScreen from './CalibrationScreen'\r\n\r\ninterface EyeTrackingData {\r\n webcamHeight: number\r\n webcamRotation: number\r\n ratioPixelToCentimeter: number\r\n agentEyesHeight: number\r\n distanceFromDevice: number\r\n worldDistancePerDegree: number\r\n cameraX: number\r\n cameraZ: number\r\n}\r\n\r\ninterface ThreeJsWrapperAgentData {\r\n url: string\r\n animationsUrl?: string\r\n source?: string\r\n gender: 'male' | 'female' | 'other'\r\n useBlendshapeManager?: boolean\r\n}\r\n\r\ninterface ThreeJsWrapperProps {\r\n agentData: ThreeJsWrapperAgentData\r\n visible: boolean\r\n height?: string | number\r\n size?: string | number\r\n cameraPreset?: keyof typeof presets\r\n calibration?: CalibrationData\r\n centered: boolean\r\n}\r\n\r\nconst ThreeJsWrapper = ({ agentData, visible, height, size, cameraPreset, calibration, centered }: ThreeJsWrapperProps): React.JSX.Element => {\r\n const dispatch = useDispatch()\r\n const gpuData = useSelector((state: RootState) => state.retorikReducer.gpuData)\r\n const addressData = useSelector((state: RootState) => state.retorikReducer.addressData)\r\n const speaking = useSelector((state: RootState) => state.speechReducer.speaking)\r\n const loaderClosed = useSelector((state: RootState) => state.retorikReducer.loaderClosed)\r\n const recognitionState = useSelector((state: RootState) => state.speechReducer.activeRecognitionState)\r\n const lastRecognitionInterim = useSelector((state: RootState) => state.speechReducer.lastRecognitionInterim)\r\n const singleViseme = useSelector((state: RootState) => state.speechReducer.singleVisemeAdded)\r\n const singleBlendShape = useSelector((state: RootState) => state.speechReducer.singleBlendShapeAdded)\r\n const multiVisemes = useSelector((state: RootState) => state.speechReducer.multiVisemesAdded)\r\n const multiBlendShapes = useSelector((state: RootState) => state.speechReducer.multiBlendShapesAdded)\r\n const streamingQueue = useSelector((state: RootState) => state.speechReducer.streamingQueue)\r\n const characterLoaded = useSelector((state: RootState) => state.viewReducer.characterLoaded)\r\n const isMobile = useSelector((state: RootState) => state.viewReducer.isMobile)\r\n\r\n const [targets, setTargets] = useState<Array<Object3D>>([])\r\n const [dynamicData, setDynamicData] = useState<\r\n | {\r\n webcamHeight: number\r\n ratioPixelToCentimeter: number\r\n deltaAgentHeightAgentWorldHeightInCentimeters: number\r\n cameraRotationInDegrees: number\r\n distanceFromAgentToCameraInCentimeters: number\r\n }\r\n | undefined\r\n >(undefined)\r\n const [openCalibration, setOpenCalibration] = useState<boolean>(false)\r\n\r\n /**\r\n * Use model's source to get the right loader. Default to avaturn loader\r\n */\r\n const type = useMemo<CreationTool | null>(() => {\r\n if (agentData.source) {\r\n switch (agentData.source.toLowerCase()) {\r\n case Source3DEngine.avatarsdk:\r\n case Source3DEngine.avatarsdkbis:\r\n return CreationTool.avatarsdk\r\n case Source3DEngine.cc3:\r\n case Source3DEngine.cc4:\r\n return CreationTool.cc3\r\n case Source3DEngine.avaturn:\r\n default:\r\n return CreationTool.avaturn\r\n }\r\n }\r\n\r\n return CreationTool.avaturn\r\n }, [agentData])\r\n\r\n useEffect(() => {\r\n if ((!calibration?.static?.enabled && !calibration?.dynamic?.enabled) || isMobile) dispatch(storeActions.view.setCalibrationCompleted(true))\r\n }, [calibration, isMobile])\r\n\r\n useEffect(() => {\r\n // Check if we should open the calibration screen or not\r\n if ((calibration?.static?.enabled || calibration?.dynamic?.enabled) && !isMobile) {\r\n // If there are some static data in the props or the local storage, we can directly set the targets without opening the calibration screen\r\n if (calibration?.static?.enabled && calibration.static.staticTarget) {\r\n const o = new Object3D()\r\n o.position.set(calibration.static.staticTarget.x, calibration.static.staticTarget.y, calibration.static.staticTarget.z)\r\n setTargets([o])\r\n setOpenCalibration(false)\r\n dispatch(storeActions.view.setCalibrationCompleted(true))\r\n } else if (calibration?.static?.enabled && calibration.static.loadStaticTargetFromLocalStorage && localStorage.getItem('Retorik.Framework.Static.Target')) {\r\n const calibrationData = JSON.parse(localStorage.getItem('Retorik.Framework.Static.Target') || '{}') as {\r\n x: number\r\n y: number\r\n z: number\r\n }\r\n const o = new Object3D()\r\n o.position.set(calibrationData.x, calibrationData.y, calibrationData.z)\r\n setTargets([o])\r\n setOpenCalibration(false)\r\n dispatch(storeActions.view.setCalibrationCompleted(true))\r\n } else if (calibration.dynamic?.enabled && calibration.dynamic.dynamicData) {\r\n // Check if all the mandatory dynamic data are in the props\r\n if (\r\n calibration.dynamic.dynamicData.webcamHeight &&\r\n calibration.dynamic.dynamicData.ratioPixelToCentimeter &&\r\n calibration.dynamic.dynamicData.deltaAgentHeightAgentWorldHeightInCentimeters &&\r\n calibration.dynamic.dynamicData.distanceFromAgentToCameraInCentimeters\r\n ) {\r\n setDynamicData({ ...calibration.dynamic.dynamicData, cameraRotationInDegrees: calibration.dynamic.dynamicData.cameraRotationInDegrees || 0 })\r\n }\r\n\r\n setOpenCalibration(true)\r\n } else if (calibration.dynamic?.enabled && calibration.dynamic.loadDynamicDataFromLocalStorage && localStorage.getItem('Retorik.Framework.Dynamic.Data')) {\r\n // Check if the local storage data is complete\r\n const calibrationData = JSON.parse(localStorage.getItem('Retorik.Framework.Dynamic.Data') || '{}')\r\n if (\r\n calibrationData.webcamHeight &&\r\n calibrationData.ratioPixelToCentimeter &&\r\n calibrationData.deltaAgentHeightAgentWorldHeightInCentimeters &&\r\n calibrationData.distanceFromAgentToCameraInCentimeters\r\n ) {\r\n setDynamicData({ ...calibrationData, cameraRotationInDegrees: calibrationData.cameraRotationInDegrees || 0 })\r\n }\r\n\r\n setOpenCalibration(true)\r\n } else {\r\n setOpenCalibration(true)\r\n }\r\n } else {\r\n setOpenCalibration(false)\r\n dispatch(storeActions.view.setCalibrationCompleted(true))\r\n }\r\n }, [calibration, isMobile])\r\n\r\n useEffect(() => {\r\n singleViseme && addViseme(singleViseme)\r\n }, [singleViseme])\r\n\r\n useEffect(() => {\r\n singleBlendShape && addBlendshape(structuredClone(singleBlendShape))\r\n }, [singleBlendShape])\r\n\r\n useEffect(() => {\r\n multiVisemes.length && setVisemes(multiVisemes)\r\n }, [multiVisemes])\r\n\r\n useEffect(() => {\r\n if (multiBlendShapes.length) {\r\n for (const frame of multiBlendShapes) {\r\n addBlendshape(structuredClone(frame))\r\n }\r\n }\r\n }, [multiBlendShapes])\r\n\r\n useEffect(() => {\r\n if (speaking || (!addressData.livekit?.enabled && streamingQueue.length)) {\r\n setCharacterState(CharacterState.speaking)\r\n } else if (recognitionState === RecognitionState.Closed) {\r\n setCharacterState(CharacterState.idle)\r\n } else if (lastRecognitionInterim) {\r\n setCharacterState(CharacterState.listening)\r\n } else {\r\n setCharacterState(CharacterState.waiting)\r\n }\r\n }, [speaking, recognitionState, lastRecognitionInterim, streamingQueue])\r\n\r\n useEffect(() => {\r\n !speaking && flushLipSyncData()\r\n }, [speaking])\r\n\r\n return (\r\n <React.Fragment>\r\n <div\r\n style={{\r\n height: size || '100%',\r\n paddingTop: height || 0,\r\n visibility: characterLoaded && visible ? 'visible' : 'hidden'\r\n }}\r\n >\r\n {type && (\r\n <Character\r\n url={agentData.url}\r\n type={type}\r\n animationsUrl={agentData?.animationsUrl || 'https://cdn.retorik.ai/bodyengine-three/animations/cc4/female/standing/'}\r\n gender={agentData?.gender === 'male' ? 'male' : 'female'}\r\n onLoadingCompleted={() => dispatch(storeActions.view.setCharacterLoaded(true))}\r\n camera={presets[cameraPreset || 'default']}\r\n targets={targets}\r\n autoLookAt={true}\r\n detectGpuData={gpuData}\r\n license='fake-license'\r\n useBlendshapeManager={agentData.useBlendshapeManager || false}\r\n />\r\n )}\r\n </div>\r\n {!characterLoaded && (\r\n <div className='rf-absolute rf-top-0 rf-left-0 rf-w-full rf-h-full rf-flex rf-justify-center rf-items-center'>\r\n <div className='rf-w-1/4 rf-aspect-square'>\r\n <MicrophoneLoader />\r\n </div>\r\n </div>\r\n )}\r\n\r\n {openCalibration && loaderClosed && (\r\n <CalibrationScreen\r\n centered={centered}\r\n staticCalibrationEnabled={!!calibration?.static?.enabled}\r\n dynamicCalibrationEnabled={!!calibration?.dynamic?.enabled}\r\n setTargets={(targets: Array<Object3D>) => setTargets(targets)}\r\n dynamicData={dynamicData}\r\n />\r\n )}\r\n </React.Fragment>\r\n )\r\n}\r\n\r\nexport default ThreeJsWrapper\r\nexport type { EyeTrackingData }\r\n","import React, { useEffect, useRef, useState } from 'react'\r\nimport { Object3D, getCameraPosition, getCharacterHeight, setLookAtCamera, setShowFirstTarget } from '@davi-ai/react-bodyengine-three'\r\nimport type { Detection } from '@mediapipe/tasks-vision'\r\nimport { useSelector, useDispatch } from 'react-redux'\r\nimport { RootState, storeActions } from '../../store'\r\nimport FaceDetector from '../Veille/FaceDetector'\r\n\r\ninterface CalibrationScreenProps {\r\n centered: boolean\r\n staticCalibrationEnabled: boolean\r\n dynamicCalibrationEnabled: boolean\r\n dynamicData?: {\r\n webcamHeight: number\r\n ratioPixelToCentimeter: number\r\n deltaAgentHeightAgentWorldHeightInCentimeters: number\r\n cameraRotationInDegrees: number\r\n distanceFromAgentToCameraInCentimeters: number\r\n }\r\n setTargets: (targets: Array<Object3D>) => void\r\n}\r\n\r\nenum CalibrationMode {\r\n none = 1,\r\n static,\r\n dynamic\r\n}\r\n\r\nconst CalibrationScreen = ({ centered, staticCalibrationEnabled, dynamicCalibrationEnabled, dynamicData, setTargets }: CalibrationScreenProps): React.JSX.Element => {\r\n const dispatch = useDispatch()\r\n const cameraPosition = getCameraPosition()\r\n const characterHeight = getCharacterHeight()\r\n const characterLoaded = useSelector((state: RootState) => state.viewReducer.characterLoaded)\r\n const calibrationCompleted = useSelector((state: RootState) => state.viewReducer.calibrationCompleted)\r\n\r\n const [calibrationMode, setCalibrationMode] = useState<CalibrationMode>(dynamicData ? CalibrationMode.dynamic : CalibrationMode.none)\r\n const [distanceFromDevice, setDistanceFromDevice] = useState<number>(dynamicData?.distanceFromAgentToCameraInCentimeters || 0)\r\n const [webcamRotation, setWebcamRotation] = useState<number>(0)\r\n const [agentEyesHeightOnScreen, setAgentEyesHeightOnScreen] = useState<number>(0)\r\n const [worldDistancePerDegree, setWorldDistancePerDegree] = useState<number>(0)\r\n const [currentAngleInDegrees, setCurrentAngleInDegrees] = useState<number>(0)\r\n const [cameraX, setCameraX] = useState<number>(0)\r\n const [cameraY, setCameraY] = useState<number>(0)\r\n const [cameraZ, setCameraZ] = useState<number>(0)\r\n\r\n const cameraXRef = useRef<number>(0)\r\n const cameraYRef = useRef<number>(0)\r\n const cameraZRef = useRef<number>(0)\r\n const currentAngleInDegreesRef = useRef<number>(0)\r\n const webcamHeightRef = useRef<number>(dynamicData?.webcamHeight || 0)\r\n const userEyesHeightRef = useRef<number>(0)\r\n const agentEyesHeightRef = useRef<number>(0)\r\n const distanceFromDeviceRef = useRef<number>(0)\r\n const webcamRotatedRef = useRef<number>(dynamicData?.cameraRotationInDegrees || 0)\r\n const deltaAgentHeightAgentWorldHeightInCentimetersRef = useRef<number>(dynamicData?.deltaAgentHeightAgentWorldHeightInCentimeters || 0)\r\n const ratioPixelToCentimeterRef = useRef<number>(dynamicData?.ratioPixelToCentimeter || 0)\r\n const calibrationCompletedRef = useRef<boolean>(calibrationCompleted)\r\n const counterRef = useRef<number>(0)\r\n\r\n useEffect(() => {\r\n // If dynamic data are given, let's validate immediately to set calibratoin as completed\r\n dynamicData && handleValidate()\r\n }, [])\r\n\r\n useEffect(() => {\r\n characterLoaded && !dynamicData && setLookAtCamera(true)\r\n\r\n return () => {\r\n setLookAtCamera(false)\r\n }\r\n }, [characterLoaded])\r\n\r\n useEffect(() => {\r\n if (worldDistancePerDegree && !dynamicData) {\r\n const o = new Object3D()\r\n o.position.set(cameraX, cameraY + currentAngleInDegrees * worldDistancePerDegree, Math.max(cameraZ / 5, 0.3))\r\n setTargets([o])\r\n }\r\n }, [currentAngleInDegrees, worldDistancePerDegree, distanceFromDevice, cameraX, cameraY, cameraZ])\r\n\r\n useEffect(() => {\r\n if (cameraPosition && !(cameraPosition.x === 0 && cameraPosition.y === 0)) {\r\n const zDistanceCameraPlusUser = cameraPosition.z + distanceFromDevice / 100\r\n setCameraX(cameraPosition.x)\r\n setCameraY(cameraPosition.y)\r\n setCameraZ(zDistanceCameraPlusUser)\r\n cameraXRef.current = cameraPosition.x\r\n cameraYRef.current = cameraPosition.y\r\n cameraZRef.current = zDistanceCameraPlusUser\r\n // Get Y world distance for one degree using tangent. The z distance is divided by 5 with 0.3 at the lowest to show a visible height bar when calibrating\r\n setWorldDistancePerDegree(Math.tan(Math.PI / 180) * Math.max(zDistanceCameraPlusUser / 5, 0.3))\r\n }\r\n }, [cameraPosition, distanceFromDevice])\r\n\r\n useEffect(() => {\r\n if (!dynamicData) {\r\n characterHeight && agentEyesHeightOnScreen && (deltaAgentHeightAgentWorldHeightInCentimetersRef.current = (characterHeight - characterHeight / 16) * 100 - agentEyesHeightOnScreen)\r\n }\r\n }, [characterHeight, agentEyesHeightOnScreen])\r\n\r\n useEffect(() => {\r\n !dynamicData && (webcamRotatedRef.current = webcamRotation)\r\n }, [webcamRotation])\r\n\r\n useEffect(() => {\r\n calibrationCompletedRef.current = calibrationCompleted\r\n }, [calibrationCompleted])\r\n\r\n useEffect(() => {\r\n if (!dynamicData && calibrationMode === CalibrationMode.static) {\r\n setShowFirstTarget(!calibrationCompleted)\r\n }\r\n }, [calibrationMode, calibrationCompleted])\r\n\r\n const handleReset = () => {\r\n setCurrentAngleInDegrees(0)\r\n currentAngleInDegreesRef.current = 0\r\n }\r\n\r\n const handleValidate = () => {\r\n setLookAtCamera(false)\r\n if (calibrationMode === CalibrationMode.static) {\r\n // In static mode, store the target in local storage to be able to reuse it later and avoid asking the user to calibrate again if the data are valid\r\n localStorage.setItem('Retorik.Framework.Static.Target', JSON.stringify({ x: cameraX, y: cameraY + currentAngleInDegrees * worldDistancePerDegree, z: cameraZ }))\r\n } else if (calibrationMode === CalibrationMode.dynamic && ratioPixelToCentimeterRef.current) {\r\n localStorage.setItem(\r\n 'Retorik.Framework.Dynamic.Data',\r\n JSON.stringify({\r\n webcamHeight: webcamHeightRef.current,\r\n ratioPixelToCentimeter: ratioPixelToCentimeterRef.current,\r\n deltaAgentHeightAgentWorldHeightInCentimeters: deltaAgentHeightAgentWorldHeightInCentimetersRef.current,\r\n cameraRotationInDegrees: webcamRotatedRef.current,\r\n distanceFromAgentToCameraInCentimeters: distanceFromDeviceRef.current\r\n })\r\n )\r\n setTargets([])\r\n }\r\n\r\n dispatch(storeActions.view.setCalibrationCompleted(true))\r\n }\r\n\r\n const handleFaceDetected = (detections?: Array<Detection>, width?: number, height?: number): void => {\r\n counterRef.current++\r\n if (detections?.length && width && height) {\r\n // The detections are inverted in X and Y axis (the origin is the top right corner of the image)\r\n const webcamPositionY = webcamRotatedRef.current === 0 ? height / 2 : width / 2\r\n const userPositionY = webcamRotatedRef.current === 0 ? height * (1 - detections[0].keypoints[0].y) : width * (1 - detections[0].keypoints[0].x)\r\n\r\n if (calibrationCompletedRef.current) {\r\n // Check if the mandatory data have been filled (webcam / agent / user heights + distance user <-> device)\r\n if (webcamHeightRef.current && ratioPixelToCentimeterRef.current && deltaAgentHeightAgentWorldHeightInCentimetersRef.current !== 0) {\r\n const deltaHeightInPixels = webcamPositionY - userPositionY\r\n const userEyesHeightInCentimeters = webcamHeightRef.current - deltaHeightInPixels * ratioPixelToCentimeterRef.current\r\n const targetYInWorldCoordinates = (userEyesHeightInCentimeters + deltaAgentHeightAgentWorldHeightInCentimetersRef.current) / 100\r\n\r\n const o = new Object3D()\r\n o.position.set(cameraXRef.current, targetYInWorldCoordinates, cameraZRef.current)\r\n setTargets([o])\r\n }\r\n } else {\r\n // The detections are inverted in X and Y axis (the origin is the top right corner of the image)\r\n if (webcamHeightRef.current && userEyesHeightRef.current && distanceFromDeviceRef.current) {\r\n // Get the difference in height between the webcam and the user's eyes in cm, then use the detection to get the same difference in pixels on the webcam's image\r\n const deltaHeightInCentimeters = Math.abs(webcamHeightRef.current - userEyesHeightRef.current)\r\n const deltaHeightInPixels = Math.abs(webcamPositionY - userPositionY)\r\n\r\n deltaHeightInPixels && (ratioPixelToCentimeterRef.current = deltaHeightInCentimeters / deltaHeightInPixels)\r\n }\r\n }\r\n }\r\n }\r\n\r\n return (\r\n <div\r\n id='retorik-framework-animation-container-calibration'\r\n className={`rf-absolute rf-top-0 rf-h-full rf-w-full rf-grid rf-grid-cols-1 rf-grid-rows-1 ${!centered && 'landscape-retorik:rf-translate-x-1/4'}`}\r\n >\r\n {calibrationMode === CalibrationMode.dynamic && (\r\n <div className='rf-relative rf-z-1 rf-h-full rf-w-full rf-col-start-1 rf-col-span-1 rf-row-start-1 rf-row-span-1 rf-flex rf-justify-start rf-items-start'>\r\n <FaceDetector detectionThreshold={0.8} onFaceDetected={handleFaceDetected} showThumbnail={!calibrationCompleted} rotation={webcamRotation} />\r\n </div>\r\n )}\r\n\r\n {!calibrationCompleted && (\r\n <React.Fragment>\r\n {calibrationMode === CalibrationMode.none ? (\r\n <div className='rf-h-full rf-w-full rf-col-start-1 rf-col-span-1 rf-row-start-1 rf-row-span-1 rf-flex rf-flex-col rf-justify-center rf-items-center rf-gap-4 rf-bg-white rf-bg-opacity-50'>\r\n <p className='rf-text-medium-size-auto'>Choisissez un mode de calibrage :</p>\r\n <div className='rf-flex rf-flex-row rf-gap-4'>\r\n {staticCalibrationEnabled && (\r\n <div\r\n className='rf-px-4 rf-py-2 rf-border rf-border-primary rf-rounded-lg rf-bg-primary rf-bg-opacity-50 rf-cursor-pointer'\r\n onClick={() => setCalibrationMode(CalibrationMode.static)}\r\n >\r\n STATIQUE\r\n </div>\r\n )}\r\n\r\n {dynamicCalibrationEnabled && (\r\n <div\r\n className='rf-px-4 rf-py-2 rf-border rf-border-primary rf-rounded-lg rf-bg-primary rf-bg-opacity-50 rf-cursor-pointer'\r\n onClick={() => setCalibrationMode(CalibrationMode.dynamic)}\r\n >\r\n DYNAMIQUE\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n ) : (\r\n <div className='rf-relative rf-h-full rf-w-full rf-col-start-1 rf-col-span-1 rf-row-start-1 rf-row-span-1 rf-flex rf-flex-col rf-justify-center rf-gap-4'>\r\n {calibrationMode === CalibrationMode.dynamic ? (\r\n <div className='rf-absolute rf-left-32 rf-flex rf-flex-col rf-justify-center rf-items-center rf-gap-4'>\r\n <div className='rf-grid rf-grid-cols-2 rf-grid-rows-3 rf-gap-4'>\r\n <p className='rf-font-bold'>Hauteur webcam (en cm)</p>\r\n <input\r\n type='number'\r\n min={0}\r\n max={300}\r\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\r\n webcamHeightRef.current = parseInt(e.target.value!)\r\n }}\r\n />\r\n <p className='rf-font-bold'>Votre taille (en cm)</p>\r\n <input\r\n type='number'\r\n min={50}\r\n max={300}\r\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\r\n // We estimate the height of the user's eyes is 12 cm less than their total height\r\n userEyesHeightRef.current = parseInt(e.target.value!) - 12\r\n }}\r\n />\r\n <p className='rf-font-bold'>Hauteur des yeux de l'agent (en cm)</p>\r\n <input\r\n type='number'\r\n min={50}\r\n max={300}\r\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\r\n setAgentEyesHeightOnScreen(parseInt(e.target.value!))\r\n agentEyesHeightRef.current = parseInt(e.target.value!)\r\n }}\r\n />\r\n <p className='rf-font-bold'>Distance utilisateur - borne (en cm)</p>\r\n <input\r\n type='number'\r\n min={20}\r\n max={100}\r\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\r\n setDistanceFromDevice(parseInt(e.target.value!))\r\n distanceFromDeviceRef.current = parseInt(e.target.value!)\r\n }}\r\n />\r\n <p className='rf-font-bold'>Rotation de la webcam (en degrés)</p>\r\n <div className='rf-flex rf-flex-row rf-gap-2'>\r\n <button\r\n className={`rf-px-2 rf-py-1 rf-border rf-border-primary rf-rounded-lg rf-bg-primary rf-bg-opacity-50 rf-cursor-pointer ${webcamRotation === 0 && 'rf-bg-opacity-100'}`}\r\n onClick={() => setWebcamRotation(0)}\r\n >\r\n 0\r\n </button>\r\n <button\r\n className={`rf-px-2 rf-py-1 rf-border rf-border-primary rf-rounded-lg rf-bg-primary rf-bg-opacity-50 rf-cursor-pointer ${webcamRotation === 90 && 'rf-bg-opacity-100'}`}\r\n onClick={() => setWebcamRotation(90)}\r\n >\r\n 90\r\n </button>\r\n <button\r\n className={`rf-px-2 rf-py-1 rf-border rf-border-primary rf-rounded-lg rf-bg-primary rf-bg-opacity-50 rf-cursor-pointer ${webcamRotation === -90 && 'rf-bg-opacity-100'}`}\r\n onClick={() => setWebcamRotation(-90)}\r\n >\r\n -90\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div className='rf-h-16 rf-w-16 rf-flex rf-justify-center rf-items-center rf-bg-white rf-border rf-border-black rf-rounded-lg hover: rf-cursor-pointer' onClick={handleValidate}>\r\n Done\r\n </div>\r\n </div>\r\n ) : (\r\n <div className='rf-ml-4 rf-flex rf-flex-col rf-gap-4'>\r\n <div className='rf-flex rf-flex-row rf-items-center rf-gap-4'>\r\n <input\r\n type='range'\r\n min={-25}\r\n max={25}\r\n step={1}\r\n value={currentAngleInDegrees}\r\n onChange={(e) => {\r\n const val = parseInt(e.target.value)\r\n setCurrentAngleInDegrees(val)\r\n currentAngleInDegreesRef.current = val\r\n }}\r\n className='rf-range-vertical rf-w-8 rf-h-80 rf-appearance-none rf-border rf-border-black rf-rounded-lg rf-cursor-pointer'\r\n style={{ writingMode: 'vertical-lr', direction: 'rtl' }}\r\n />\r\n <div className='rf-w-fit rf-p-4 rf-flex rf-flex-col rf-justify-center rf-gap-2 rf-bg-white rf-border rf-border-black rf-rounded-lg'>\r\n <p>Position actuelle de la cible : </p>\r\n <p>{`x: ${cameraX}`}</p>\r\n <p>{`y: ${cameraY + (currentAngleInDegrees ? currentAngleInDegrees * worldDistancePerDegree : 0)}`}</p>\r\n <p>{`z: ${Math.max(cameraZ / 5, 0.3)}`}</p>\r\n <p>{`angle: ${currentAngleInDegrees}°`}</p>\r\n </div>\r\n </div>\r\n\r\n <div className='rf-flex rf-flex-row rf-gap-2'>\r\n <div className='rf-h-10 rf-px-4 rf-flex rf-justify-center rf-items-center rf-bg-white rf-border rf-border-black rf-rounded-lg rf-cursor-pointer' onClick={() => handleReset()}>\r\n Reset\r\n </div>\r\n <div className='rf-h-10 rf-px-4 rf-flex rf-justify-center rf-items-center rf-bg-white rf-border rf-border-black rf-rounded-lg rf-cursor-pointer' onClick={handleValidate}>\r\n Done\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n </React.Fragment>\r\n )}\r\n </div>\r\n )\r\n}\r\n\r\nexport default CalibrationScreen\r\n","import React, { useEffect, useState, useRef } from 'react'\r\nimport { FaceDetector as MediapipeFaceDetector, FilesetResolver, Detection } from '@mediapipe/tasks-vision'\r\n\r\ninterface FaceDetectorProps {\r\n detectionThreshold: number\r\n onFaceDetected: (detections?: Array<Detection>, imageWidth?: number, imageHeight?: number) => void\r\n showThumbnail?: boolean\r\n rotation?: number\r\n}\r\n\r\nconst runningMode = 'VIDEO'\r\nlet lastVideoTime = -1\r\nconst defaultConstraints: MediaStreamConstraints = {\r\n video: {\r\n facingMode: 'user'\r\n }\r\n}\r\n\r\nconst FaceDetector = ({ detectionThreshold, onFaceDetected, showThumbnail, rotation }: FaceDetectorProps): React.JSX.Element => {\r\n const [webcamWidth, setWebcamWidth] = useState<number>(0)\r\n const [webcamHeight, setWebcamHeight] = useState<number>(0)\r\n const [faceDetector, setFaceDetector] = useState<MediapipeFaceDetector | undefined>()\r\n const videoRef = useRef<HTMLVideoElement>(null)\r\n const rotationRef = useRef<number>(rotation || 0)\r\n\r\n useEffect(() => {\r\n rotationRef.current = rotation || 0\r\n }, [rotation])\r\n\r\n useEffect(() => {\r\n const createfaceDetector = async () => {\r\n const vision = await FilesetResolver.forVisionTasks('https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.0/wasm')\r\n const newFaceDetector = await MediapipeFaceDetector.createFromOptions(vision, {\r\n baseOptions: {\r\n modelAssetPath: `https://storage.googleapis.com/mediapipe-models/face_detector/blaze_face_short_range/float16/1/blaze_face_short_range.tflite`,\r\n delegate: 'GPU'\r\n },\r\n runningMode: runningMode\r\n })\r\n\r\n newFaceDetector && setFaceDetector(newFaceDetector)\r\n }\r\n\r\n const initializefaceDetector = async () => {\r\n navigator.mediaDevices\r\n .getUserMedia(defaultConstraints)\r\n .then((display) => {\r\n const settings = display.getVideoTracks()[0].getSettings()\r\n setWebcamWidth(settings.width || 0)\r\n setWebcamHeight(settings.height || 0)\r\n createfaceDetector()\r\n })\r\n .catch((error) => console.warn('Retorik Framework > an error occured when trying to use the webcam : ', error))\r\n }\r\n\r\n initializefaceDetector()\r\n }, [])\r\n\r\n const predictWebcam = async () => {\r\n if (faceDetector && videoRef.current) {\r\n let startTimeMs = performance.now()\r\n\r\n // Detect faces using detectForVideo\r\n if (videoRef.current.currentTime !== lastVideoTime) {\r\n lastVideoTime = videoRef.current.currentTime\r\n const detections = faceDetector.detectForVideo(videoRef.current, startTimeMs, { rotationDegrees: rotationRef.current }).detections\r\n\r\n if (detections.length) {\r\n const score = detections[0].categories[0].score\r\n score > detectionThreshold && onFaceDetected(detections, videoRef.current.videoWidth, videoRef.current.videoHeight)\r\n }\r\n }\r\n }\r\n\r\n // Call this function again to keep predicting when the browser is ready\r\n window.requestAnimationFrame(predictWebcam)\r\n }\r\n\r\n useEffect(() => {\r\n if (faceDetector && videoRef.current) {\r\n // Activate the webcam stream\r\n navigator.mediaDevices\r\n .getUserMedia(defaultConstraints)\r\n .then((stream) => {\r\n if (videoRef.current) {\r\n videoRef.current.srcObject = stream\r\n videoRef.current.addEventListener('loadeddata', predictWebcam)\r\n }\r\n })\r\n .catch((err) => {\r\n console.error(err)\r\n })\r\n }\r\n }, [faceDetector])\r\n\r\n return (\r\n <div id='retorik-framework-face-detector' className={`rf-absolute rf-top-0 rf-left-0 ${!showThumbnail && 'rf-invisible'}`}>\r\n <video\r\n ref={videoRef}\r\n src=''\r\n autoPlay\r\n style={{\r\n rotate: `${rotation}deg`,\r\n width: showThumbnail ? webcamWidth / 2 : webcamWidth,\r\n height: showThumbnail ? webcamHeight / 2 : webcamHeight\r\n }}\r\n />\r\n </div>\r\n )\r\n}\r\n\r\nexport default FaceDetector\r\n"],"names":[],"version":3,"file":"ThreeJsWrapper.ad746197.js.map","sourceRoot":"../"}
|