> 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/examples.md).

# Examples

{% hint style="info" %}
**In general, examples are given on the client side. Because playing on the server side works in the same way. Only the first parameter is must be a source id**
{% endhint %}

### Play sound via file

```lua
local coords = GetEntityCoords(PlayerPedId())
local soundId = exports['mx-surround']:Play(nil, '/ui/sounds/beltalarm.ogg', coords)
```

***

### Play sound via url (Youtube, Spotify, SoundCloud)

```lua
local coords = GetEntityCoords(PlayerPedId())
local url = 'https://www.youtube.com/watch?v=RP0_8J7uxhs&ab_channel=RHINO'
local soundId = exports['mx-surround']:Play(nil, url, coords)
```

***

### Play sound via another resource

```lua
local path = 'https://cfx-nui-qs-smartphone-pro/'
local sound_path = path .. 'html/sounds/test.mp3'
local soundId = exports['mx-surround']:Play(nil, sound_path, coords)
```

***

### Play sound in an interior (with special 3d properties)

{% hint style="info" %}
What we do is that the sound gets more out and the sound behavior changes. So you don't need to specify whether a sound is interior or not. S**cript detects it directly**.
{% endhint %}

```lua
local url = 'https://www.youtube.com/watch?v=r2LpOUwca94&ab_channel=MajorLazerOfficial'
local unicornLocation = vec(108.65, -1288.81, 28.86) -- Vanilla Unicorn' location
local panner = {
    panningModel = 'HRTF',                           -- https://developer.mozilla.org/en-US/docs/Web/API/PannerNode
    refDistance = 20.0,                              -- Distance of the volume dropoff start
    rolloffFactor = 1.8,                             -- How fast the volume drops off 
    distanceModel = 'exponential',                   -- How the volume drops off (linear, inverse, exponential)
    coneInnerAngle = 360.0,                          -- https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/coneInnerAngle
    coneOuterAngle = 0.0,                            -- https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/coneOuterAngle
}
exports['mx-surround']:Play(nil, url, unicornLocation, false, 1.0, panner)
```

{% hint style="info" %}
Don't think this complicated. You can do it without special panner.
{% endhint %}

```lua
local url = 'https://www.youtube.com/watch?v=OiC1rgCPmUQ&ab_channel=DuaLipa'
local unicornLocation = vec(108.65, -1288.81, 28.86) -- Vanilla Unicorn' location
exports['mx-surround']:Play(nil, url, unicornLocation)
```

***

### Attach a sound to an entity

```lua
local url = 'https://www.youtube.com/watch?v=AMYWaWYQp6I'
local ped = PlayerPedId()
local coords = GetEntityCoords(ped)
local vehicle = GetVehiclePedIsIn(ped, false)

local soundId = exports['mx-surround']:Play(nil, url, coords)
if not soundId then return end
if vehicle then
    local networkId = VehToNet(vehicle)
    exports['mx-surround']:attachEntity(soundId, networkId)
end
```

***

### Attach a sound to a player

{% hint style="info" %}
The difference from `attachEntity` is that it detects whether the player is getting into the car or not. And performs filtering.
{% endhint %}

```lua
local url = 'https://www.youtube.com/watch?v=AMYWaWYQp6I'
local coords = GetEntityCoords(PlayerPedId())
local soundId = exports['mx-surround']:Play(nil, url, coords)
local playerId = GetPlayerServerId(PlayerId())
exports['mx-surround']:attachPlayer(soundId, playerId)
```

***

### Add handler to a sound

```lua
local coords = GetEntityCoords(PlayerPedId())
local url = 'https://www.youtube.com/watch?v=AMYWaWYQp6I'

local soundId = exports['mx-surround']:createUniqueId()
exports['mx-surround']:onStop(soundId, function(soundData)
    print('stopped', soundId)
end)
exports['mx-surround']:onPause(soundId, function(soundData)
    print('paused', soundId)
end)
exports['mx-surround']:onResume(soundId, function(soundData)
    print('resumed', soundId)
end)
exports['mx-surround']:onDestroy(soundId, function(soundData)
    print('destroyed', soundId)
end)
exports['mx-surround']:Play(soundId, url, coords)
print('Started', soundId)
Wait(1000)
exports['mx-surround']:Stop(soundId)
Wait(1000)
exports['mx-surround']:Resume(soundId)
Wait(1500)
exports['mx-surround']:Pause(soundId)
Wait(2000)
exports['mx-surround']:Resume(soundId)
Wait(5000)
exports['mx-surround']:Destroy(soundId)
```

### Another way to add handler to a sound

```lua
local coords = GetEntityCoords(PlayerPedId())
local url = 'https://www.youtube.com/watch?v=AMYWaWYQp6I'

local soundId = exports['mx-surround']:createUniqueId()
exports['mx-surround']:setSoundHandler(soundId, {
    loading = function()
        print('loading', soundId)
    end,
    stop = function()
        print('stopped', soundId)
    end,
    pause = function()
        print('paused', soundId)
    end,
    resume = function()
        print('resumed', soundId)
    end,
    destroy = function()
        print('destroyed', soundId)
    end
})
exports['mx-surround']:Play(soundId, url, coords)
print('Started', soundId)
Wait(1000)
exports['mx-surround']:Stop(soundId)
Wait(1000)
exports['mx-surround']:Resume(soundId)
Wait(1500)
exports['mx-surround']:Pause(soundId)
Wait(2000)
exports['mx-surround']:Resume(soundId)
Wait(5000)
exports['mx-surround']:Destroy(soundId)
```

***

### **Play Async (Server Side)**

```lua
RegisterCommand('asset', function(source, args)
    local sound = 'beltalarm'
    local player = GetPlayerPed(source)
    local vehicle = GetVehiclePedIsIn(player, true)
    local vehNetId = NetworkGetNetworkIdFromEntity(vehicle)
    local coords = GetEntityCoords(vehicle)
    exports['mx-surround']:PlayAsync(-1, nil, '/ui/sounds/' .. sound .. '.ogg', coords, false, 1.0, nil, {
        attachEntity = vehNetId
    })
end, false)
```
