> For the complete documentation index, see [llms.txt](https://kazescripts.gitbook.io/kazescripts/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kazescripts.gitbook.io/kazescripts/kaze_sound/client-api.md).

# Client API

Client-side exports for local sounds that only one player hears.

Client exports create **local** sounds: only the player running the code hears them. Use them for UI sounds, phone ringtones, personal effects or anything tied to one player.

For sounds that everyone hears, use the [Server API](/kazescripts/kaze_sound/server-api.md).

## Play

```lua
local id = exports.kaze_sound:Play(options)
```

Creates and starts a sound, and returns its id. Playing again with an existing id replaces that sound.

```lua
-- A speaker in a building
local id = exports.kaze_sound:Play({
    id = 'bar_music',
    url = 'nui://kaze_sound/sounds/lounge.mp3',
    coords = vec3(-561.9, 286.8, 82.2),
    volume = 0.6,
    loop = true,
    maxDistance = 25.0,
    reverbPreset = 'bar',
})

-- A 2D notification sound (no position)
exports.kaze_sound:Play({ url = 'nui://kaze_sound/sounds/ping.ogg', volume = 0.4 })

-- Attached to a vehicle, speaker in the trunk
exports.kaze_sound:Play({
    url = 'https://cdn.example.com/track.mp3',
    entity = vehicle,
    offsetPos = vec3(0.0, -1.8, 0.4),
})
```

### Options

| Option         | Type    | Default      | Description                                                                                           |
| -------------- | ------- | ------------ | ----------------------------------------------------------------------------------------------------- |
| `url`          | string  | **required** | `nui://`, `https://` or YouTube link. See [Audio sources](/kazescripts/kaze_sound/audio-sources.md).  |
| `id`           | string  | auto         | Your own id. Reusing it replaces the old sound.                                                       |
| `coords`       | vector3 | —            | World position.                                                                                       |
| `entity`       | entity  | —            | Follow an entity (vehicle, object, ped) instead of fixed coords.                                      |
| `offsetPos`    | vector3 | —            | Offset from the entity, in the entity's local space.                                                  |
| `volume`       | number  | `0.5`        | 0.0 to 1.0.                                                                                           |
| `loop`         | boolean | `false`      | Repeat the track.                                                                                     |
| `maxDistance`  | number  | `30.0`       | Range in metres.                                                                                      |
| `refDistance`  | number  | `3.0`        | Full-volume radius in metres.                                                                         |
| `rolloff`      | number  | `1.2`        | Distance falloff speed.                                                                               |
| `spatial`      | boolean | `true`       | `false` for 2D. A sound with no `coords` or `entity` is always 2D.                                    |
| `occlusion`    | boolean | `true`       | Walls, interiors and cabins muffle it.                                                                |
| `reverb`       | boolean | `true`       | Room reverb.                                                                                          |
| `reverbPreset` | string  | `'auto'`     | Room preset name. See [Room presets](/kazescripts/kaze_sound/surround-and-acoustics.md#room-presets). |
| `reverbAmount` | number  | `1.0`        | Reverb multiplier.                                                                                    |
| `doppler`      | boolean | `false`      | Pitch shift from speed.                                                                               |
| `stream`       | boolean | `false`      | Live stream: no seeking, reconnects live.                                                             |
| `fadeIn`       | number  | —            | Fade-in length in ms.                                                                                 |
| `autoDestroy`  | boolean | `true`       | Remove when a non-looped track ends.                                                                  |
| `cone`         | table   | —            | Directional speaker: `{ inner, outer, outerGain, dir? }`.                                             |
| `offset`       | number  | `0`          | Start position in seconds.                                                                            |
| `paused`       | boolean | `false`      | Create the sound paused.                                                                              |

## Control

| Export                           | Description                                                                                                              |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `Destroy(id, fadeMs?)`           | Stop and remove a sound, optionally fading out.                                                                          |
| `Pause(id)` / `Resume(id)`       | Pause and resume at the same position.                                                                                   |
| `SetVolume(id, volume, fadeMs?)` | Change volume, optionally with a fade.                                                                                   |
| `FadeIn(id, ms?, target?)`       | Fade from silence to `target` (defaults to the current volume).                                                          |
| `FadeOut(id, ms?, destroy?)`     | Fade to silence. Pass `true` to remove the sound afterwards.                                                             |
| `SetTime(id, seconds)`           | Jump to a position in the track.                                                                                         |
| `SetUrl(id, url, offset?)`       | Switch to another track.                                                                                                 |
| `SetCoords(id, coords)`          | Move the sound to fixed coords.                                                                                          |
| `Attach(id, entity)`             | Make the sound follow an entity.                                                                                         |
| `SetOption(id, key, value)`      | Change an option live, for example `maxDistance`, `loop`, `reverbPreset`, `cone`. `spatial` can only be set at creation. |
| `SetMasterVolume(volume)`        | Set this player's master volume (0.0 to 1.0). Saved between sessions.                                                    |

## Read state

| Export                           | Returns                                                      |
| -------------------------------- | ------------------------------------------------------------ |
| `Exists(id)`                     | `true` if the sound exists.                                  |
| `IsPlaying(id)` / `IsPaused(id)` | Playback state.                                              |
| `GetTime(id)`                    | Current position in seconds.                                 |
| `GetDuration(id)`                | Track length in seconds, `0` until loaded or for streams.    |
| `GetVolume(id)`                  | Current volume.                                              |
| `GetPosition(id)`                | Current world position, or `nil` if the entity isn't nearby. |
| `GetMode(id)`                    | `'3d'`, `'2d'`, `'basic'`, or `nil` while loading.           |
| `GetAll()`                       | List of every sound id.                                      |
| `GetMasterVolume()`              | This player's master volume.                                 |

## Callbacks

Register a function for one sound:

```lua
exports.kaze_sound:OnEnd(id, function()
    print('track finished')
end)
```

| Export                       | Called when                                 |
| ---------------------------- | ------------------------------------------- |
| `OnLoaded(id, fn(duration))` | The file is loaded and its length is known. |
| `OnPlay(id, fn())`           | Audio actually starts.                      |
| `OnEnd(id, fn())`            | A non-looped track reaches the end.         |
| `OnError(id, fn(err))`       | The file can't be played.                   |
| `OnDestroy(id, fn())`        | The sound is removed.                       |

## Events

The same moments fire as client events for every sound: `kaze_sound:loaded`, `kaze_sound:play`, `kaze_sound:end`, `kaze_sound:error` and `kaze_sound:destroy`. The first argument is the sound id.

```lua
AddEventHandler('kaze_sound:end', function(id)
    print(id .. ' ended')
end)
```

{% hint style="success" %}
When your resource stops or restarts, the sounds it created are removed automatically.
{% endhint %}
