Skip to content

Commit

Permalink
🐛 (audioClip) Fix audio clip UI on Safari
Browse files Browse the repository at this point in the history
  • Loading branch information
baptisteArno committed Aug 21, 2024
1 parent 37ef8fe commit b2c8ef9
Show file tree
Hide file tree
Showing 9 changed files with 40 additions and 41 deletions.
2 changes: 1 addition & 1 deletion packages/embeds/js/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@typebot.io/js",
"version": "0.3.10",
"version": "0.3.11",
"description": "Javascript library to display typebots on your website",
"type": "module",
"main": "dist/index.js",
Expand Down
1 change: 0 additions & 1 deletion packages/embeds/js/src/components/Bot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,6 @@ const BotContent = (props: BotContentProps) => {

onMount(() => {
if (!botContainerElement) return
console.log('yes')
setBotContainer(botContainerElement)
resizeObserver.observe(botContainerElement)
setBotContainerHeight(`${botContainerElement.clientHeight}px`)
Expand Down
1 change: 0 additions & 1 deletion packages/embeds/js/src/components/InputChatBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ export const InputChatBlock = (props: Props) => {
})

const handleSubmit = async (content: InputSubmitContent) => {
console.log(content)
setAnswer(content)
props.onSubmit(content)
}
Expand Down
6 changes: 3 additions & 3 deletions packages/embeds/js/src/components/bubbles/GuestBubble.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,12 @@ const TextGuestBubble = (props: { answer: TextInputSubmitContent }) => {

const AudioGuestBubble = (props: { answer: RecordingInputSubmitContent }) => {
return (
<div class="flex flex-col gap-1 items-end w-full">
<div class="flex flex-col gap-1 items-end">
<div
class="p-2 w-full whitespace-pre-wrap typebot-guest-bubble flex flex-col max-w-[316px]"
class="p-2 w-full whitespace-pre-wrap typebot-guest-bubble flex flex-col"
data-testid="guest-bubble"
>
<audio controls src={props.answer.url} class="w-full h-[54px]" />
<audio controls src={props.answer.url} />
</div>
</div>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,9 @@ export const TextInput = (props: Props) => {
<div
class={clsx(
'typebot-input-form flex w-full gap-2 items-end',
props.block.options?.isLong ? 'max-w-full' : 'max-w-[350px]'
props.block.options?.isLong && recordingStatus() !== 'started'
? 'max-w-full'
: 'max-w-[350px]'
)}
onKeyDown={submitWhenEnter}
onDrop={handleDropFile}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import { defaultButtonsBackgroundColor } from '@typebot.io/schemas/features/type

const barWidth = 3
const barGap = 3
const dx = 53.5
let offset = 0
const dx = 60
const initBarsHeightPercent = 10
const minDetectedVolumePercent = 5
const maxDetectedVolumePercent = 90

type Props = {
recordingStatus: 'asking' | 'started' | 'stopped'
Expand All @@ -30,13 +31,14 @@ export const VoiceRecorder = (props: Props) => {
let stream: MediaStream | undefined
let bars: number[] = []
let recordTimeInterval: NodeJS.Timer | undefined
let lastFrameTime: DOMHighResTimeStamp | undefined
let lastFrameTime: DOMHighResTimeStamp | undefined = undefined
let offset = 0

const fillRgb = hexToRgb(
props.buttonsTheme?.backgroundColor ?? defaultButtonsBackgroundColor
).join(', ')

const animate = () => {
const draw = () => {
if (!ctx || !canvasElement || !lastFrameTime) return

const currentTime = performance.now()
Expand Down Expand Up @@ -72,25 +74,22 @@ export const VoiceRecorder = (props: Props) => {

offset += dx * (deltaTime / 1000)

animationFrameId = requestAnimationFrame(animate)
animationFrameId = requestAnimationFrame(draw)
}

const startRecording = async () => {
if (!canvasElement) return
if (!ctx) ctx = canvasElement.getContext('2d') ?? undefined

lastFrameTime = performance.now()
stream = await navigator.mediaDevices.getUserMedia({ audio: true })

animate()
props.onRecordingConfirmed(stream)

if (!ctx) ctx = canvasElement.getContext('2d') ?? undefined

recordTimeInterval = setInterval(() => {
setRecordingTime((prev) => (prev += 1))
}, 1000)

stream = await navigator.mediaDevices.getUserMedia({ audio: true })

props.onRecordingConfirmed(stream)

audioContext = new AudioContext()
volumeNode = await loadVolumeProcessorWorklet(audioContext)

Expand All @@ -100,8 +99,21 @@ export const VoiceRecorder = (props: Props) => {
volumeNode.connect(audioContext.destination)

volumeNode.port.onmessage = (event) => {
bars.push(event.data)
const initBars = (canvasElement.width + barGap) / (barWidth + barGap)
const shouldAddNewBar =
(initBars + bars.length) * (barWidth + barGap) <
canvasElement.width + offset
if (shouldAddNewBar)
bars.push(
Math.min(
Math.max(event.data, minDetectedVolumePercent),
maxDetectedVolumePercent
)
)
}

lastFrameTime = performance.now()
animationFrameId = requestAnimationFrame(draw)
}

const stopRecording = () => {
Expand Down Expand Up @@ -156,9 +168,11 @@ export const VoiceRecorder = (props: Props) => {
<div class="relative flex w-full">
<canvas ref={canvasElement} class="w-full h-[56px]" />
<div class="absolute left-gradient w-2 left-0 h-[56px]" />
<div class="absolute right-gradient w-2 right-0 h-[56px]" />
<div class="absolute right-gradient w-3 right-0 h-[56px]" />
</div>
<span class="font-bold text-sm">{formatTimeLabel(recordingTime())}</span>
<span class="time-container flex-none w-[35px] font-bold text-sm">
{formatTimeLabel(recordingTime())}
</span>
</div>
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,36 +1,21 @@
export const volumeProcessorCode = `
const throttleMs = 110;
const maxVolumePercent = 80;
const volumeMultiplier = 3;
const gainFactor = 3;
class VolumeProcessor extends AudioWorkletProcessor {
constructor() {
super();
this.lastUpdateTime = 0;
this.volumeSum = 0;
this.volumeCount = 1;
}
process(inputs) {
const input = inputs[0];
const currentTime = new Date().getTime();
if (input.length > 0) {
const channelData = input[0];
let sum = 0;
for (let i = 0; i < channelData.length; i++) {
sum += channelData[i] * channelData[i];
}
const rms = Math.sqrt(sum / channelData.length);
const volumePercent = rms * 100;
this.volumeSum += volumePercent;
this.volumeCount += 1;
}
if (currentTime - this.lastUpdateTime >= throttleMs) {
const averageVolume = 1 + this.volumeSum / this.volumeCount;
this.port.postMessage(Math.min(averageVolume * volumeMultiplier, maxVolumePercent));
this.volumeSum = 0;
this.volumeCount = 1;
this.lastUpdateTime = currentTime;
this.port.postMessage(rms * 100 * gainFactor)
}
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/embeds/nextjs/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@typebot.io/nextjs",
"version": "0.3.10",
"version": "0.3.11",
"description": "Convenient library to display typebots on your Next.js website",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
2 changes: 1 addition & 1 deletion packages/embeds/react/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@typebot.io/react",
"version": "0.3.10",
"version": "0.3.11",
"description": "Convenient library to display typebots on your React app",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down

0 comments on commit b2c8ef9

Please sign in to comment.