2
0

🐛 (audioClips) Fix empty metadata on recorded file

Closes #1753
This commit is contained in:
Baptiste Arnaud
2024-08-31 11:37:52 +02:00
parent 97a3212356
commit a3a9d58be9
6 changed files with 50 additions and 7 deletions

View File

@ -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.
<Note>
If supported, the recorded file will be a WebM file. If not, it will be an MP4 file (i.e. Safari).
</Note>

View File

@ -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",

View File

@ -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({

View File

@ -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",

View File

@ -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",

18
pnpm-lock.yaml generated
View File

@ -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