# Audio Recorder

*Enable audio recording with a flexible [interface](../../01_Onboarding/02_Concepts/02_Views.md) for capturing user audio input with automatic upload support.*

The `AudioRecorder` [widget](../../01_Onboarding/02_Concepts/03_Widgets.md) allows users to record audio using their microphone. It provides an audio recording interface with options for audio formats, automatic uploads, and chunked streaming. This widget is for recording audio, not playing it.

## Basic Usage

Here's a simple example of an `AudioRecorder` that uploads audio to the server and stores it in [state](../../03_Hooks/02_Core/03_UseState.md):

```csharp
public class BasicAudioRecorderDemo : ViewBase
{
    public override object? Build()
    {
        var audioFile = UseState<FileUpload<byte[]>?>();
        var upload = UseUpload(
            MemoryStreamUploadHandler.Create(audioFile),
            defaultContentType: "audio/webm"
        );

        return Layout.Vertical()
               | new AudioRecorder(upload.Value, "Start recording", "Recording audio...")
               | (audioFile.Value != null
                   ? Text.P($"Recorded: {audioFile.Value.FileName} ({Utils.FormatBytes(audioFile.Value.Length)})")
                   : null);
   }
}
```

### Chunked Upload (Streaming)

Upload audio in chunks while recording. Use `ChunkedMemoryStreamUploadHandler` to accumulate chunks into a single file:

```csharp
public class ChunkedUploadDemo : ViewBase
{
    public override object? Build()
    {
        var client = UseService<IClientProvider>();
        var audioFile = UseState<FileUpload<byte[]>?>();
        var chunkCount = UseState(0);

        // Use ChunkedMemoryStreamUploadHandler to accumulate chunks into a single file
        var upload = UseUpload(
            ChunkedMemoryStreamUploadHandler.Create(audioFile),
            defaultContentType: "audio/webm"
        );

        return Layout.Vertical().Gap(4)
               | Text.P("Records audio and uploads in 2-second chunks while recording. Each chunk is accumulated into a single file.")
               | new AudioRecorder(upload.Value, "Start chunked recording", "Recording (uploading every 2s)...")
                   .ChunkInterval(2000)
               | Text.P($"Chunks received: {chunkCount.Value}").Small()
               | (audioFile.Value != null
                   ? Text.P($"Total accumulated: {Utils.FormatBytes(audioFile.Value.Length)}").Small()
                   : null);
    }
}
```

> **tip:** Use `MemoryStreamUploadHandler` for complete file uploads (uploads when recording stops) and `ChunkedMemoryStreamUploadHandler` for streaming uploads (uploads chunks during recording).

## Audio Format

Specify the audio format using MIME type:

```csharp
public class AudioFormatDemo : ViewBase
{
    public override object? Build()
    {
        var audioFile = UseState<FileUpload<byte[]>?>();

        // Use webm format (most compatible)
        var upload = UseUpload(
            MemoryStreamUploadHandler.Create(audioFile),
            defaultContentType: "audio/webm"
        );

        return Layout.Vertical()
               | new AudioRecorder(upload.Value, "Record WebM", "Recording WebM...")
                   .MimeType("audio/webm")
               | (audioFile.Value != null
                   ? Text.P($"Format: {audioFile.Value.ContentType}, Size: {Utils.FormatBytes(audioFile.Value.Length)}").Small()
                   : null);
    }
}
```

> **tip:** Use `audio/webm` for best browser compatibility. Other formats like `audio/mp4` or `audio/wav` may work depending on the browser.

## Styling

### Custom Labels

Customize the labels shown when idle and recording:

```csharp
public class CustomLabelsDemo : ViewBase
{
    public override object? Build()
    {
        var audioFile = UseState<FileUpload<byte[]>?>();
        var upload = UseUpload(
            MemoryStreamUploadHandler.Create(audioFile),
            defaultContentType: "audio/webm"
        );

        return Layout.Vertical()
               | new AudioRecorder(upload.Value)
                   .Label("Click to start voice memo")
                   .RecordingLabel("Recording your voice...")
               | (audioFile.Value != null
                   ? audioFile.Value.ToDetails()
                   : null);
    }
}
```

### Disabled State

Disable the audio recorder:

```csharp
public class AudioRecorderDisabledDemo : ViewBase
{
    public override object? Build()
    {
        var audioFile = UseState<FileUpload<byte[]>?>();
        var upload = UseUpload(
            MemoryStreamUploadHandler.Create(audioFile),
            defaultContentType: "audio/webm"
        );

        return new AudioRecorder(upload.Value, "Recording disabled", disabled: true);
    }
}
```


## API

[View Source: AudioRecorder.cs](https://github.com/Ivy-Interactive/Ivy-Framework/blob/main/src/Ivy/Widgets/AudioRecorder.cs)

### Constructors

| Signature |
|-----------|
| `new AudioRecorder(UploadContext upload, string label = null, string recordingLabel = null, string mimeType = "audio/webm", int? chunkInterval = null, bool disabled = false)` |


### Properties

| Name | Type | Setters |
|------|------|---------|
| `ChunkInterval` | `int?` | `ChunkInterval` |
| `Disabled` | `bool` | `Disabled` |
| `Height` | `Size` | - |
| `Label` | `string` | `Label` |
| `MimeType` | `string` | `MimeType` |
| `RecordingLabel` | `string` | `RecordingLabel` |
| `Scale` | `Scale?` | - |
| `UploadUrl` | `string` | `UploadUrl` |
| `Visible` | `bool` | - |
| `Width` | `Size` | - |