Browse docs
Exports
Use exports["sky_dj"] and add dependency "sky_dj" to your resource's manifest. Names are case-sensitive. These are audio exports; they do not open /djadmin, create clubs or operate the mixer/FOH.
Playback, control and callback-registration exports return nil, not a playback acknowledgement. Before controlling or querying an existing sound, check soundExists(name): streamer mode can prevent creation, and finished sounds may have been removed.
The examples use your own sound ID, my_audio:entrance. Resource my_audio must publish sounds/intro.ogg in its manifest. See the argument and lifecycle notes below.
Client exports
Call these from a client script; they affect only the local player.
PlayUrl(name, url, volume, loop?, options?)
Starts non-spatial playback. loop defaults to false; optional options accepts playback callbacks.
exports["sky_dj"]:PlayUrl("my_audio:entrance",
"https://cfx-nui-my_audio/sounds/intro.ogg", 0.25, false)
PlayUrlPos(name, url, volume, position, loop?, options?)
Starts spatial playback at a world position, initially with a 10 m radius.
exports["sky_dj"]:PlayUrlPos("my_audio:entrance",
"https://cfx-nui-my_audio/sounds/intro.ogg", 0.25,
vector3(215.0, -810.0, 30.0), false)
Distance(name, distance)
Sets the spatial playback radius in metres.
exports["sky_dj"]:Distance("my_audio:entrance", 25.0)
Position(name, position)
Moves an existing spatial sound.
exports["sky_dj"]:Position("my_audio:entrance", vector3(216.0, -810.0, 30.0))
Pause(name)
Pauses playback.
exports["sky_dj"]:Pause("my_audio:entrance")
Resume(name)
Resumes playback.
exports["sky_dj"]:Resume("my_audio:entrance")
Destroy(name)
Removes playback and local metadata; also invokes an assigned end callback.
exports["sky_dj"]:Destroy("my_audio:entrance")
setVolume(name, volume)
Sets playback volume. For a spatial sound's attenuation ceiling, use setVolumeMax instead.
exports["sky_dj"]:setVolume("my_audio:entrance", 0.2)
setVolumeMax(name, volume)
Sets the spatial sound's maximum volume before distance attenuation.
exports["sky_dj"]:setVolumeMax("my_audio:entrance", 0.2)
setTimeStamp(name, seconds)
Requests a seek to a position in seconds.
exports["sky_dj"]:setTimeStamp("my_audio:entrance", 30.0)
destroyOnFinish(name, enabled)
Chooses whether natural completion removes the sound.
exports["sky_dj"]:destroyOnFinish("my_audio:entrance", true)
setSoundLoop(name, enabled)
Changes looping without changing the destroyOnFinish setting.
exports["sky_dj"]:setSoundLoop("my_audio:entrance", true)
repeatSound(name)
Restarts the existing sound from the beginning.
exports["sky_dj"]:repeatSound("my_audio:entrance")
setSoundURL(name, url)
Replaces the sound's media URL.
exports["sky_dj"]:setSoundURL("my_audio:entrance",
"https://cfx-nui-my_audio/sounds/intro.ogg")
setSoundDynamic(name, enabled)
Toggles spatial attenuation. Set a valid position before enabling it on a non-positioned sound.
exports["sky_dj"]:Position("my_audio:entrance", vector3(215.0, -810.0, 30.0))
exports["sky_dj"]:setSoundDynamic("my_audio:entrance", true)
setPlaybackRate(name, rate)
Requests a playback rate of 0.5–2.0; the media provider may restrict supported rates.
exports["sky_dj"]:setPlaybackRate("my_audio:entrance", 1.1)
setVolumeSmoothing(name, milliseconds)
Sets volume smoothing, clamped to 0–2000 ms.
exports["sky_dj"]:setVolumeSmoothing("my_audio:entrance", 100)
soundExists(name)
Returns boolean: whether this client's sound record exists.
local exists = exports["sky_dj"]:soundExists("my_audio:entrance")
getInfo(name)
Returns a metadata table, or nil if absent. Treat it as read-only.
local info = exports["sky_dj"]:getInfo("my_audio:entrance")
getLink(name)
Returns the media URL as a string.
local url = exports["sky_dj"]:getLink("my_audio:entrance")
getPosition(name)
Returns the sound's vector3 position, or nil for a non-positioned sound.
local position = exports["sky_dj"]:getPosition("my_audio:entrance")
getDistance(name)
Returns the configured radius in metres as a number.
local metres = exports["sky_dj"]:getDistance("my_audio:entrance")
getVolume(name)
Returns the configured volume as a number, not the listener's attenuated level.
local volume = exports["sky_dj"]:getVolume("my_audio:entrance")
getTimeStamp(name)
Returns cached playback seconds as a number, or -1 if unavailable.
local seconds = exports["sky_dj"]:getTimeStamp("my_audio:entrance")
getMaxDuration(name)
Returns duration in seconds as a number; it may be 0 before loading or -1 if unavailable.
local duration = exports["sky_dj"]:getMaxDuration("my_audio:entrance")
isPlaying(name)
Returns the local playing flag as a boolean.
local playing = exports["sky_dj"]:isPlaying("my_audio:entrance")
isPaused(name)
Returns the local paused flag as a boolean.
local paused = exports["sky_dj"]:isPaused("my_audio:entrance")
isLooped(name)
Returns the loop flag as a boolean.
local looped = exports["sky_dj"]:isLooped("my_audio:entrance")
isDynamic(name)
Returns whether spatial playback is enabled as a boolean.
local spatial = exports["sky_dj"]:isDynamic("my_audio:entrance")
isPlayerInStreamerMode()
Returns boolean: whether this player has disabled the audio engine through streamer mode.
local muted = exports["sky_dj"]:isPlayerInStreamerMode()
onLoading(name, callback)
Replaces the loading callback; receives the sound's metadata table.
exports["sky_dj"]:onLoading("my_audio:entrance", function(info)
print("Loading:", info.id)
end)
onPlayStart(name, callback)
Replaces the start callback; receives metadata. To observe the first loading/start, pass callbacks in the original play call's options table instead.
exports["sky_dj"]:onPlayStart("my_audio:entrance", function(info)
print("Started:", info.id)
end)
onPlayEnd(name, callback)
Replaces the end callback; receives metadata on playback end or explicit destruction.
exports["sky_dj"]:onPlayEnd("my_audio:entrance", function(info)
print("Ended:", info.id)
end)
onPlayPause(name, callback)
Replaces the local pause callback; receives metadata.
exports["sky_dj"]:onPlayPause("my_audio:entrance", function(info)
print("Paused:", info.id)
end)
onPlayResume(name, callback)
Replaces the local resume callback; receives metadata.
exports["sky_dj"]:onPlayResume("my_audio:entrance", function(info)
print("Resumed:", info.id)
end)
Server exports
Call these from a server script, after your own gameplay authorization. target is an online player's server ID; -1 sends to all currently connected clients without bucket, job or permission filtering. Later controls need the same recipients; controls for an absent sound are ignored.
These calls return no client status and accept no callbacks. In the examples, player_source is the intended player's server-owned source.
PlayUrl(target, name, url, volume, loop?)
Starts non-spatial playback for the recipients.
exports["sky_dj"]:PlayUrl(player_source, "my_audio:entrance",
"https://cfx-nui-my_audio/sounds/intro.ogg", 0.25, false)
PlayUrlPos(target, name, url, volume, position, loop?)
Starts spatial playback for the recipients.
exports["sky_dj"]:PlayUrlPos(player_source, "my_audio:entrance",
"https://cfx-nui-my_audio/sounds/intro.ogg", 0.25,
vector3(215.0, -810.0, 30.0), false)
Distance(target, name, distance)
Sets the existing sound's radius in metres.
exports["sky_dj"]:Distance(player_source, "my_audio:entrance", 25.0)
Position(target, name, position)
Moves the existing spatial sound.
exports["sky_dj"]:Position(player_source, "my_audio:entrance",
vector3(216.0, -810.0, 30.0))
Pause(target, name)
Pauses playback on the recipients.
exports["sky_dj"]:Pause(player_source, "my_audio:entrance")
Resume(target, name)
Resumes playback on the recipients.
exports["sky_dj"]:Resume(player_source, "my_audio:entrance")
Destroy(target, name)
Removes playback and metadata on the recipients.
exports["sky_dj"]:Destroy(player_source, "my_audio:entrance")
setVolume(target, name, volume)
Sets volume; for spatial sounds it updates the attenuation ceiling.
exports["sky_dj"]:setVolume(player_source, "my_audio:entrance", 0.2)
setTimeStamp(target, name, seconds)
Requests a seek to a position in seconds.
exports["sky_dj"]:setTimeStamp(player_source, "my_audio:entrance", 30.0)
destroyOnFinish(target, name, enabled)
Changes automatic removal on natural completion.
exports["sky_dj"]:destroyOnFinish(player_source, "my_audio:entrance", true)
Arguments and metadata
| Argument | Type / unit |
|---|---|
name, url | Sound-ID string and browser-playable media URL |
volume | number, 0.0–1.0 |
position | FiveM vector3(x, y, z), not a plain table |
distance, seconds | Positive metres / non-negative playback seconds |
loop, enabled | boolean; omitted loop means false |
options, callback | Client-only callback table / function |
The play-call options table accepts onLoading, onPlayStart, onPlayEnd, onPlayPause, onPlayResume and onPlayError. The first five receive metadata; onPlayError receives the player's error value. There is no separate onPlayError export.
Status getters describe cached local state, not audible output or cross-player synchronization. URLs must point to playable media; OS paths, Spotify pages and arbitrary video links are not direct audio files.
Lifecycle and security
Use unique IDs prefixed for your resource. Ownership is not assigned automatically; never reuse Sky DJ's sky_dj_club_ or sky_dj_boombox_ IDs. Playing an existing name replaces its local state.
New non-looping sounds remove themselves on completion; looping sounds keep their state. If you change looping, update destroyOnFinish separately. Clean up sounds when your activity or resource stops: they are not attached to the caller's lifecycle.
Export calls do not create clubs, persist SQL playback or maintain the shared club clock. Late joins, reconnects and Sky DJ restarts do not replay previous calls. Streamer mode, loading errors and distance can suppress output. Never forward unrestricted client-selected recipients, IDs or URLs to these server exports.
See Installation, Configuration and Troubleshooting.