PMMS API and exports
PMMS server and client exports checked in the archive — start, stop and lock players, manage models and default players, create entities — with the playback options format.
Goal: drive PMMS from your own resources.
Where: in the code of your resources, started after pmms.
Handles
Each active media player is identified by a handle:
- networked entity: its network ID (
NetworkGetNetworkIdFromEntity); - local entity or position: a hash computed from the coordinates rounded to a tenth.
Start exports return this handle; keep it for stop, pause, lock… pmms_ctl list (server console) shows the active handles.
Server exports
| Signature | Returns | Effect |
|---|---|---|
exports.pmms:startByNetworkId(netId, options) | handle (= netId) | Starts a media on a networked entity. |
exports.pmms:startByCoords(x, y, z, options) | handle (coordinate hash) | Starts a media on a non-networked entity identified by its coordinates. |
exports.pmms:startScaleform(scaleform, options) | handle | Starts a media on a free-standing scaleform screen: { name, position, rotation, scale } (vector3). |
exports.pmms:stop(handle) | nothing | Stops the player and frees its handle. |
exports.pmms:pause(handle) | nothing | Pauses or resumes. |
exports.pmms:lock(handle) | nothing | Locks an active player. |
exports.pmms:unlock(handle) | nothing | Unlocks an active player. |
exports.pmms:mute(handle) | nothing | Mutes an active player. |
exports.pmms:unmute(handle) | nothing | Unmutes it. |
exports.pmms:addModel(modelHash, data) | nothing | Adds or edits a model until restart (Config.models fields). |
exports.pmms:addModelPermanently(modelHash, data) | nothing | Same, and saves to models.json. |
exports.pmms:addEntity(coords, data) | nothing | Adds or edits a default media player until restart. For a new player, data must contain position. |
exports.pmms:addEntityPermanently(coords, data) | nothing | Same, sets position = coords and saves to defaultMediaPlayers.json. |
exports.pmms:removeModel(modelHash) | removed data or nil | Removes a model until restart. |
exports.pmms:removeModelPermanently(modelHash) | removed data or nil | Same, and removes it from models.json. |
exports.pmms:removeEntity(coords) | removed data or nil | Removes a default media player until restart. |
exports.pmms:removeEntityPermanently(coords) | removed data or nil | Same, and removes it from defaultMediaPlayers.json. |
exports.pmms:getMediaPlayerInfo(handle) | table or nil | Options and state of the active player. |
exports.pmms:getAllMediaPlayers() | table handle → options | Every active player, keyed by handle. |
Server exports check no permission and are not subject to Config.oneMediaPerPlayer. Every export start is sent to the Discord logs as “Lancement serveur/export”. stop, pause, lock, unlock, mute and unmute expect an active handle: check it with getMediaPlayerInfo before calling.
getAllMediaPlayers and getMediaPlayerInfo return the tables the server uses: read them without modifying them.
Playback options
options table of the start exports, presets and default media players:
| Field | Type | Effect |
|---|---|---|
url | string | Media URL, preset name or random. A name without http(s):// is looked up in pmms/http/media. |
title | string | Displayed title; a preset imposes its own. |
volume | number | 0 to 100, 100 by default. |
offset | number | Start position in seconds, 0 by default. |
duration | number | Duration in seconds. Absent, false or 0: treated as a live stream, which never ends by itself nor moves to the next queued item. |
loop | boolean | Restarts at the end; requires duration. |
filter | boolean | Immersive filter; absent: Config.enableFilterByDefault on the server. |
locked | boolean | Only players with pmms.manage can control it. |
video | boolean | Shows the video (DUI screen when the model has a renderTarget, otherwise NUI screen above the entity). |
videoSize | number | 10 to 100, Config.defaultVideoSize by default. |
muted | boolean | Starts muted. |
attenuation | { sameRoom, diffRoom } | Each value 0 to 10; config.lua defaults. |
diffRoomVolume | number | 0 to 1. |
range | number | 0 to Config.maxRange, Config.defaultRange by default. |
visualization | string | Key of Config.audioVisualizations. |
Example: vehicle radio
Server side, in your resource (my_garage is an example):
RegisterNetEvent('my_garage:radio', function(netId, url)
local src = source
if not IsPlayerAceAllowed(src, 'pmms.interact') then
return
end
local entity = NetworkGetEntityFromNetworkId(netId)
if entity == 0 or #(GetEntityCoords(GetPlayerPed(src)) - GetEntityCoords(entity)) > 5.0 then
return
end
local current = exports.pmms:getMediaPlayerInfo(netId)
if current then
exports.pmms:stop(netId)
end
exports.pmms:startByNetworkId(netId, {
url = url,
title = 'Radio',
volume = 70,
filter = false,
range = 25
})
end)
Result: the vehicle radio plays the URL for every player within 25 m. The permission and distance checks are done by your event, since the export does none. Also validate url according to your rules.
Example: personal speaker
Client side:
local speaker
RegisterCommand('speaker', function()
if speaker then
exports.pmms:deleteMediaPlayer(speaker)
speaker = nil
return
end
local ped = PlayerPedId()
speaker = exports.pmms:createMediaPlayer({
model = `prop_boombox_01`,
position = GetOffsetFromEntityInWorldCoords(ped, 0.0, 0.8, -0.95),
rotation = vector3(0.0, 0.0, GetEntityHeading(ped))
})
end)
Result: /speaker drops a speaker in front of the player; it shows in their panel even without pmms.anyEntity, and disappears when pmms stops or on the second call.
Client exports
| Signature | Returns | Effect |
|---|---|---|
exports.pmms:enableEntity(entity) | nothing | Lets this player use this entity even without pmms.anyEntity. |
exports.pmms:disableEntity(entity) | nothing | Removes this permission and requests the media playing on it to stop. |
exports.pmms:createMediaPlayer({ model, position, rotation }) | entity | Creates a networked entity this player can use; model absent: Config.defaultModel. Deleted when pmms stops. |
exports.pmms:deleteMediaPlayer(entity) | nothing | Deletes an entity created by createMediaPlayer. |
Events
The pmms:* events are used for internal communication between client, server and interface. They are not a public API: use the exports.
Common mistakes
- “No such export”:
pmmsis not started, or your resource starts before it. - Lua error on
stoporlock: the handle matches no active player. - Media that never stops:
durationabsent, the media is treated as a live stream; loop and queue do not work either. - Unexpected radio effect:
filtermissing from the options (see Troubleshooting).