From a3a9d58be9afabe39aaa7a02bd11af5eb659d546 Mon Sep 17 00:00:00 2001 From: Baptiste Arnaud Date: Sat, 31 Aug 2024 11:37:52 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20(audioClips)=20Fix=20empty=20met?= =?UTF-8?q?adata=20on=20recorded=20file?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #1753 --- apps/docs/editor/blocks/inputs/text.mdx | 4 +++ packages/embeds/js/package.json | 3 +- .../inputs/textInput/components/TextInput.tsx | 28 ++++++++++++++++--- packages/embeds/nextjs/package.json | 2 +- packages/embeds/react/package.json | 2 +- pnpm-lock.yaml | 18 ++++++++++++ 6 files changed, 50 insertions(+), 7 deletions(-) diff --git a/apps/docs/editor/blocks/inputs/text.mdx b/apps/docs/editor/blocks/inputs/text.mdx index d96bb227de..4a6f784ce9 100644 --- a/apps/docs/editor/blocks/inputs/text.mdx +++ b/apps/docs/editor/blocks/inputs/text.mdx @@ -62,3 +62,7 @@ The generated URL will be stored in the defined variable. ## Allow audio clips This option, if enabled, displays a microphone button when the text input is empty. This allows users to record a voice message and send it to the bot. + + +If supported, the recorded file will be a WebM file. If not, it will be an MP4 file (i.e. Safari). + diff --git a/packages/embeds/js/package.json b/packages/embeds/js/package.json index 188a651184..cfe5fc4048 100644 --- a/packages/embeds/js/package.json +++ b/packages/embeds/js/package.json @@ -1,6 +1,6 @@ { "name": "@typebot.io/js", - "version": "0.3.11", + "version": "0.3.12", "description": "Javascript library to display typebots on your website", "type": "module", "main": "dist/index.js", @@ -15,6 +15,7 @@ "dependencies": { "@ai-sdk/ui-utils": "0.0.36", "@ark-ui/solid": "3.3.0", + "@fix-webm-duration/fix": "1.0.1", "@stripe/stripe-js": "1.54.1", "@udecode/plate-common": "30.4.5", "dompurify": "3.0.6", diff --git a/packages/embeds/js/src/features/blocks/inputs/textInput/components/TextInput.tsx b/packages/embeds/js/src/features/blocks/inputs/textInput/components/TextInput.tsx index 56eb96a449..8d144c3342 100644 --- a/packages/embeds/js/src/features/blocks/inputs/textInput/components/TextInput.tsx +++ b/packages/embeds/js/src/features/blocks/inputs/textInput/components/TextInput.tsx @@ -26,6 +26,7 @@ import { guessApiHost } from '@/utils/guessApiHost' import { VoiceRecorder } from './VoiceRecorder' import { Button } from '@/components/Button' import { MicrophoneIcon } from '@/components/icons/MicrophoneIcon' +import { fixWebmDuration } from '@fix-webm-duration/fix' type Props = { block: TextInputBlock @@ -163,20 +164,39 @@ export const TextInput = (props: Props) => { } const handleRecordingConfirmed = (stream: MediaStream) => { - mediaRecorder = new MediaRecorder(stream) + let startTime: number + const mimeType = MediaRecorder.isTypeSupported('audio/webm') + ? 'audio/webm' + : 'video/mp4' + + mediaRecorder = new MediaRecorder(stream, { mimeType }) mediaRecorder.ondataavailable = (event) => { if (event.data.size === 0) return recordedChunks.push(event.data) } + mediaRecorder.onstart = () => { + startTime = Date.now() + } mediaRecorder.onstop = async () => { if (recordingStatus() !== 'started' || recordedChunks.length === 0) return + + const duration = Date.now() - startTime + + const blob = await fixWebmDuration( + new Blob(recordedChunks, { type: mimeType }), + duration + ) + const audioFile = new File( - recordedChunks, - `rec-${props.block.id}-${Date.now()}.mp3`, + [blob], + `rec-${props.block.id}-${Date.now()}.${ + mimeType === 'audio/webm' ? 'webm' : 'mp4' + }`, { - type: 'audio/mp3', + type: mimeType, } ) + setUploadProgress(undefined) const urls = ( await uploadFiles({ diff --git a/packages/embeds/nextjs/package.json b/packages/embeds/nextjs/package.json index 4dd431a0e5..bca8effd5c 100644 --- a/packages/embeds/nextjs/package.json +++ b/packages/embeds/nextjs/package.json @@ -1,6 +1,6 @@ { "name": "@typebot.io/nextjs", - "version": "0.3.11", + "version": "0.3.12", "description": "Convenient library to display typebots on your Next.js website", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/embeds/react/package.json b/packages/embeds/react/package.json index 9101b035f3..406f76403a 100644 --- a/packages/embeds/react/package.json +++ b/packages/embeds/react/package.json @@ -1,6 +1,6 @@ { "name": "@typebot.io/react", - "version": "0.3.11", + "version": "0.3.12", "description": "Convenient library to display typebots on your React app", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8d92608d7a..f094a4a398 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1033,6 +1033,9 @@ importers: '@ark-ui/solid': specifier: 3.3.0 version: 3.3.0(@internationalized/date@3.5.4)(solid-js@1.7.8) + '@fix-webm-duration/fix': + specifier: ^1.0.1 + version: 1.0.1 '@stripe/stripe-js': specifier: 1.54.1 version: 1.54.1 @@ -4084,6 +4087,12 @@ packages: react: ^16.0.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 + '@fix-webm-duration/fix@1.0.1': + resolution: {integrity: sha512-rRN4CpWQaXRbCXYqKIxnsUq8OSWSGq/SVlnxxkx0HxMZZ1u0qnB24P766o8QS5YaMMqAOFAzmsMmfZ2OWucOLQ==} + + '@fix-webm-duration/parser@1.0.1': + resolution: {integrity: sha512-Z6el7ohBBpym4iOmxDxumN715cHzLcAbtOtYfIbvoyToVtAuxvHt3ELXGff83iAXEU1Yj7g+obQBdiKJYVhbWw==} + '@floating-ui/core@1.6.7': resolution: {integrity: sha512-yDzVT/Lm101nQ5TCVeK65LtdN7Tj4Qpr9RTXJ2vPFLqtLxwOrpoxAHAJI8J3yYWUc40J0BDBheaitK5SJmno2g==} @@ -15886,6 +15895,15 @@ snapshots: react: 18.2.0 react-dom: 18.2.0(react@18.2.0) + '@fix-webm-duration/fix@1.0.1': + dependencies: + '@fix-webm-duration/parser': 1.0.1 + tslib: 2.6.0 + + '@fix-webm-duration/parser@1.0.1': + dependencies: + tslib: 2.6.0 + '@floating-ui/core@1.6.7': dependencies: '@floating-ui/utils': 0.2.7