# Extract audio waveform data

Generate JSON waveform data for visual audio players

"BeatSync" (a music collaboration app like SoundCloud) shows waveform visualizations in its audio player. Rather than rendering waveforms client-side from raw audio, extract the data server-side and ship lightweight JSON to the browser.

## API

<CodeGroup labels={["CLI", "TypeScript", "Python", "curl"]}>
```bash
ittybit audio \
  -i https://beatsync-app.com/tracks/collab-99.wav \
  --waveform json \
  --waveform_points 200
```

```typescript
const task = {
  input: 'https://beatsync-app.com/tracks/collab-99.wav',
  kind: 'audio',
  options: {
    waveform: 'json',
    waveform_points: 200,
  },
};

const res = await fetch('https://api.ittybit.com/jobs', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.ITTYBIT_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(task),
});
const data = await res.json();
```

```python

task = {
    "input": "https://beatsync-app.com/tracks/collab-99.wav",
    "kind": "audio",
    "options": {
        "waveform": "json",
        "waveform_points": 200,
    },
}

res = requests.post(
    "https://api.ittybit.com/jobs",
    headers={"Authorization": f"Bearer {api_key}"},
    json=task,
)
data = res.json()
```

```bash
TASK='{
  "input": "https://beatsync-app.com/tracks/collab-99.wav",
  "kind": "audio",
  "options": {
    "waveform": "json",
    "waveform_points": 200
  }
}'

curl -X POST https://api.ittybit.com/jobs \
  -H "Authorization: Bearer $ITTYBIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d "$TASK"
```

</CodeGroup>

The `waveform_points` option controls resolution -- how many amplitude samples are in the output. 200 works well for most player widths. Use fewer for thumbnails, more for full-screen views.

## CLI

```bash
ittybit audio \
  -i collab-99.wav \
  -o collab-99-waveform.json \
  --waveform json \
  --waveform_points 200
```

## Output format

The JSON output is an array of normalized amplitude values between 0 and 1:

```json
{
  "duration": 245.3,
  "sample_rate": 44100,
  "points": 200,
  "data": [0.02, 0.15, 0.43, 0.87, 0.91, 0.76, 0.54, 0.22, ...]
}
```

Each value represents the peak amplitude for that time slice. A 200-point waveform of a 4-minute track gives roughly 1.2 seconds per point.

## Rendering the waveform

Use the data array to draw bars or a path in a `<canvas>` or SVG:

```typescript
const waveform = await fetch('/api/tracks/collab-99/waveform').then((r) => r.json());

waveform.data.forEach((amplitude, i) => {
  const x = (i / waveform.points) * canvas.width;
  const height = amplitude * canvas.height;
  ctx.fillRect(x, canvas.height - height, barWidth, height);
});
```

## Resolution guide

| Use case                      | Points   | Notes                                   |
| ----------------------------- | -------- | --------------------------------------- |
| Thumbnail / list view         | 50-100   | Small player, low detail                |
| Standard player               | 150-200  | Good balance of detail and payload size |
| Full-screen / timeline editor | 500-1000 | High detail for scrubbing               |