---
id: audio_recorder
title: Audio Recorder
---

import RecordingPermissionDeniedNotification from '../../assets/audio-recorder-permission-denied-notification.png';
import StartRecordingButton from '../../assets/audio-recorder-start-recording-button.png';
import AudioRecorderRecording from '../../assets/audio-recorder-recording.png';
import AudioRecorderPaused from '../../assets/audio-recorder-paused.png';
import AudioRecorderStopped from '../../assets/audio-recorder-stopped.png';

Recording voice messages is possible by enabling audio recording on `MessageInput` component.

```jsx
<MessageInput audioRecordingEnabled />
```

Once enabled, the `MessageInput` UI will render a `StartRecordingAudioButton`.

<img src={StartRecordingButton} alt='Message composer with the recording button' height='300' />

The default implementation of `StartRecordingAudioButton` button can be replaced with custom implementation through the `Channel` component context:

```jsx
<Channel StartRecordingAudioButton={CustomComponent}>
```

Click on the recording button will replace the message composer UI with `AudioRecorder` component UI.

<img src={AudioRecorderRecording} alt='AudioRecorder UI with recording in progress' height='300' />

The default `AudioRecorder` component can be replaced by a custom implementation through the `Channel` component context:

```jsx
<Channel AudioRecorder={CustomComponent}>
```

## Browser permissions

Updates in `'microphone'` browser permission are observed and handled. If a user clicks the start recording button and the `'microphone'` permission state is `'denied'`, then a notification dialog `RecordingPermissionDeniedNotification` is rendered.

<img
  src={RecordingPermissionDeniedNotification}
  alt='RecordingPermissionDeniedNotification rendered when microphone permission is denied'
  height='300'
/>

The dialog can be customized by passing own component to `Channel` component context:

```jsx
<Channel RecordingPermissionDeniedNotification={CustomComponent}>
```

## Audio recorder states

The `AudioRecorder` UI switches between the following states

**1. Recording state**

The recording can be paused or stopped.

<img src={AudioRecorderRecording} alt='AudioRecorder UI in recording state' height='300' />

**2. Paused state**

The recording can be stopped or resumed.

<img src={AudioRecorderPaused} alt='AudioRecorder UI paused state' height='300' />

**3. Stopped state**

The recording can be played back before it is sent.

<img src={AudioRecorderStopped} alt='AudioRecorder UI stopped state' height='300' />

At any time, the recorder allows to cancel the recording and return to message composer UI by clicking the button with the bin icon.

## The message sending behavior

The resulting recording is always uploaded on the recording completion. The recording is completed when user stops the recording and confirms the completion with a send button.

The behavior, when a message with the given recording attachment is sent, however, can be controlled through the `asyncMessagesMultiSendEnabled` configuration prop on `MessageInput`.

```jsx
<MessageInput asyncMessagesMultiSendEnabled audioRecordingEnabled />
```

And so the message is sent depending on `asyncMessagesMultiSendEnabled` value as follows:

| `asyncMessagesMultiSendEnabled` value | Impact                                                                                                                                                    |
| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `false` (default behavior)            | immediately after a successful upload at one step on completion. In that case as a single attachment (voice recording only), no-text message is submitted |
| `true`                                | upon clicking the `SendMessage` button if `asyncMessagesMultiSendEnabled` is enabled                                                                      |

:::note
Enabling `asyncMessagesMultiSendEnabled` would allow users to record multiple voice messages or accompany the voice recording with text or other types of attachments.
:::

## Audio recorder controller

The components consuming the `MessageInputContext` can access the recording state through the `recordingController`:

```jsx
import { useMessageInputContext } from 'stream-chat-react';

const Component = () => {
  const {
    recordingController: {
      completeRecording,
      permissionState,
      recorder,
      recording,
      recordingState,
    },
  } = useMessageInputContext();
};
```

The controller exposes the following API:

| Property            | Description                                                                                                                                   |
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `completeRecording` | A function that allows to stop the recording and upload it the back-end and submit the message if `asyncMessagesMultiSendEnabled` is disabled |
| `permissionState`   | One of the values for microphone permission: `'granted'`, `'prompt'`, `'denied'`                                                              |
| `recorder`          | Instance of `MediaRecorderController` that exposes the API to control the recording states (`start`, `pause`, `resume`, `stop`, `cancel`)     |
| `recording`         | Generated attachment of type `voiceRecording`. This is available once the recording is stopped.                                               |
| `recordingState`    | One of the values `'recording'`, `'paused'`, `'stopped'`. Useful to reflect the changes in `recorder` state in the UI.                        |
