Voice UI Kit

Bot Audio Control

Control for adjusting the bot's audio output volume

The BotAudioControl component provides a button with a popover-mounted volume slider for controlling the bot's audio output level. It integrates with the kit's bot audio store so any number of instances stay in sync, and it drives the <audio> element rendered by BotAudioOutput (used automatically by PipecatAppBase).

import { BotAudioControl } from "@pipecat-ai/voice-ui-kit";

<BotAudioControl />

Mute is intentionally not provided as its own control yet. For now, sliding volume to 0 silences the bot locally. A dedicated mute affordance is being designed separately because it requires a decision about whether muting should also pause the user's microphone (to avoid the bot's LLM receiving user speech that references something the user never actually heard).

PropTypeDefault
variant?
"primary" | "secondary" | "outline" | "destructive" | "ghost" | "link" | "active" | "inactive"
"secondary"
size?
"sm" | "md" | "lg" | "xl"
"md"
state?
"default" | "active" | "inactive"
undefined
buttonProps?
Partial<ButtonProps>
undefined
popoverProps?
Partial<React.ComponentProps<typeof Popover>>
undefined
popoverContentProps?
Partial<React.ComponentProps<typeof PopoverContent>>
{ align: "end" }
volumeSliderProps?
Partial<Omit<BotVolumeSliderComponentProps, 'volume' | 'onVolumeChange'>>
undefined
classNames?
{ button?: string; popoverContent?: string; slider?: string; }
undefined
noIcon?
boolean
false
label?
string
undefined
children?
React.ReactNode
undefined

BotAudioComponent

The BotAudioComponent is the headless variant. It accepts volume and onVolumeChange directly, so you can drive it from any state source (tests, custom stores, etc.).

import { BotAudioComponent } from "@pipecat-ai/voice-ui-kit";

function Demo() {
  const [volume, setVolume] = React.useState(0.8);
  return (
    <BotAudioComponent
      volume={volume}
      onVolumeChange={setVolume}
    />
  );
}

render(<Demo />);
PropTypeDefault
volume?
number
1
onVolumeChange?
(volume: number) => void
undefined
variant?
"primary" | "secondary" | "outline" | "destructive" | "ghost" | "link" | "active" | "inactive"
"secondary"
size?
"sm" | "md" | "lg" | "xl"
"md"
state?
"default" | "active" | "inactive"
undefined
buttonProps?
Partial<ButtonProps>
undefined
popoverProps?
Partial<React.ComponentProps<typeof Popover>>
undefined
popoverContentProps?
Partial<React.ComponentProps<typeof PopoverContent>>
{ align: "end" }
volumeSliderProps?
Partial<Omit<BotVolumeSliderComponentProps, 'volume' | 'onVolumeChange'>>
undefined
classNames?
{ button?: string; popoverContent?: string; slider?: string; }
undefined
noIcon?
boolean
false
label?
string
undefined
children?
React.ReactNode
undefined

Adjusting placement

Pass popoverContentProps to override placement defaults:

<BotAudioControl
  popoverContentProps={{
    align: "center",
    side: "top",
    sideOffset: 8,
  }}
/>

Pass popoverProps to control open state (e.g. for a controlled popover):

<BotAudioControl
  popoverProps={{ open, onOpenChange: setOpen }}
/>

Integration

The connected BotAudioControl reads and writes volume through the useBotAudioOutput hook, and uses usePipecatClientTransportState to disable the control while the transport is disconnected or initializing. It must be used within a PipecatClientProvider context (typically provided by PipecatAppBase).

Volume is applied to the <audio> element rendered by BotAudioOutput, which PipecatAppBase mounts automatically unless noAudioOutput is true.

Visual States

The icon inside the trigger button reflects the current volume level (muted, low, medium, high). This is purely cosmetic and does not represent a separate mute state.

Also see

  • BotVolumeSlider — the inline slider rendered inside this control's popover, usable standalone.
  • useBotAudioOutput for reading or driving the bot volume from anywhere in your app.
  • BotAudioPanel — renders a BotAudioControl in its header by default; pass noControls to hide it.