> For the complete documentation index, see [llms.txt](https://docs.moxha.dev/documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.moxha.dev/documentation/paid-scripts/surround-spatial-audio/api/client/handlers.md).

# Handlers

These are handlers

### Start

```lua
exports['mx-surround']:onPlayStart(soundId, fn)
```

#### Parameters

* > **soundId:** `string`
* > **fn:** `function`

***

### Stop

```lua
exports['mx-surround']:onPlayEnd(soundId, fn)
```

#### Parameters

* > **soundId:** `string`
* > **fn:** `function`

***

### Pause

```lua
exports['mx-surround']:onPlayPause(soundId, fn)
```

#### Parameters

* > **soundId:** `string`
* > **fn:** `function`

***

### Resume

```lua
exports['mx-surround']:onPlayResume(soundId, fn)
```

#### Parameters

* > **soundId:** `string`
* > **fn:** `function`

***

### Loading

```lua
exports['mx-surround']:onLoading(soundId, fn)
```

#### Parameters

* > **soundId:** `string`
* > **fn:** `function`

***

### Attach

```lua
exports['mx-surround']:onAttachEntity(soundId, fn)
```

#### Parameters

* > **soundId:** `string`
* > **fn:** `function`

***

### Detach

```lua
exports['mx-surround']:onDetachEntity(soundId, fn)
```

#### Parameters

* > **soundId:** `string`
* > **fn:** `function`

***

### Destroy

```lua
exports['mx-surround']:onDestroy(soundId, fn)
```

#### Parameters

* > **soundId:** `string`
* > **fn:** `function`

### Time Update

```lua
exports['mx-surround']:onTimeUpdate(soundId, fn)
```

{% hint style="info" %}
This handler is triggered when the current time changed
{% endhint %}

#### Parameters

* > **soundId:** `string`
* > **fn:** `function`

***

#### Play Error

```lua
exports['mx-surround']:onPlayError(soundId, function(info, reason)
    print(('Sound %s failed: %s'):format(info.soundId, reason))
end)
```

{% hint style="info" %}
Triggered when the sound could not be played on this client: a YouTube error code, a dead link, an unsupported format or a load that timed out.
{% endhint %}

**Parameters**

* **soundId**: `string | number`
* **fn**: `function(info: table, reason: string)`

***

#### Error

```lua
exports['mx-surround']:onError(soundId, fn)
```

Same moment as `onPlayError`. `fn` gets `(info, reason)`.

**Parameters**

* **soundId**: `string | number`
* **fn**: `function(info: table, reason: string)`

***

#### Rate Change

```lua
exports['mx-surround']:onRateChange(soundId, function(info, rate, preservePitch) end)
```

{% hint style="info" %}
Triggered when the playback rate of the sound changes.
{% endhint %}

**Parameters**

* **soundId**: `string | number`
* **fn**: `function(info: table, rate: number, preservePitch: boolean)`

***

#### Loop

```lua
exports['mx-surround']:onLoop(soundId, fn)
```

{% hint style="info" %}
Triggered each time a looping sound wraps back to the start.
{% endhint %}

**Parameters**

* **soundId**: `string | number`
* **fn**: `function`

***

### Directly Set

```lua
exports['mx-surround']:setSoundHandler(soundId, data)
```

#### Parameters

* > **soundId:** `string`
* > **data:** `table`
  >
  > > * **destroy:** `function`
  > > * **start**: `function`
  > > * **stop**: `function`
  > > * **pause**: `function`
  > > * **resume**: `function`
  > > * **loading**: `function`
  > > * **attach**: `function`
  > > * **detach**: `function`
  > > * **timeupdate:** `function`
  > > * **end:** `function`
  >
  > > > * **loop:** `function`
  > > > * **error:** `function`
  > > > * **playError:** `function`
  > > > * **rate:** `function`
