Component guide

San Andreas Radio

Set up the vehicle radio, scanner, Bluetooth, GTA and streamed stations, and optional pma-voice support.

Resource
San Andreas Sound Suite
Version
Sound 1.5.16 · Dispatch 1.0.0 · Radio 1.0.0
Updated
August 21, 2026
View San Andreas Sound Suite resource View files on GitHub
Guide navigationRadio
Sections
01 / Overview

What Radio controls

Radio decides which vehicles and seats may use it, then keeps the selected source, station, power, volume, timing, Bluetooth playback, and scanner power in sync. The selected audio resource plays that shared state.

SourceMedia ownerSynchronization model
Local RadioGTA VNative station, power, and track metadata are synchronized; GTA owns playback gain.
Satellite RadioExternal stream operatorVehicle state is synchronized; matching live URLs can share a provider syncGroup.
Server RadioConfigured Station PackOne deterministic program clock supplies a seekable track and offset.
BluetoothPlayer-supplied supported URLVehicle queue, URL, transport position, play state, and revision are synchronized.
ScannerLocal Dispatch or configured live profileSeparate vehicle channel, power state, public metadata, and HUD.

Before changing a shared setting, the server checks the requesting player, vehicle, seat permission, supported vehicle type, station or URL, selected source, and request rate. The on-screen interface (NUI) never decides whether a change is allowed.

New vehicle state is powered off by default. Normal entertainment restrictions and scanner eligibility are independent so emergency controls can remain available while the entertainment UI is blocked.

02 / Setup

Requirements and installation

  • Keep the exact san_andreas_radio folder name.
  • OneSync is required and declared by dependency '/onesync'.
  • Radio has no framework, database, npm-install, or build requirement.
  • Start the selected audio provider before Radio. Start optional Dispatch and Station Packs before Radio when their sources are used.
  • Without Dispatch, only scanner profiles with a non-empty URL can play. Without Station Pack, Local, Satellite, and Bluetooth remain available.
server.cfgcfg
ensure san_andreas_sound
ensure san_andreas_dispatch
ensure san_andreas_station_pack
ensure san_andreas_radio
  1. Confirm OneSync, start order, and a clean server console.
  2. Enter a normal vehicle, start the engine, and open the head unit with Q or /saradio.
  3. Confirm the radio begins powered off, then test every installed source.
  4. Confirm the mini display follows radio, engine/accessory, and pause state.
  5. Enter a restricted emergency vehicle and confirm the entertainment UI remains blocked.
  6. Enter an eligible scanner vehicle and verify its scanner power and HUD separately.
03 / Configuration

Core state, permissions, and lifecycle

KeyTypeDefaultAccepted valuesDescription
Config.OpenKeystringQ—Default player-remappable head-unit key.
Config.HoldToOpenbooleanfalse—Uses hold behavior when true and toggle/Escape behavior when false.
Config.DisableNativeWheelbooleantrue—Suppresses GTA's competing radio wheel while eligible.
Config.DisableNativeCyclingbooleantrue—Suppresses GTA next/previous station controls.
Config.PassengerControlstringalldriver | front | allSeats allowed to change shared radio state.
Config.DefaultStationstringRADIO_01_CLASS_ROCK—Initial native station for new vehicle state.
Config.DefaultVolumenumber0.200.0-1.0Initial synchronized volume intent.
Config.PoweredByDefaultbooleanfalse—Power state for new empty or player-driven vehicles.
Config.PreserveNpcRadiobooleantrue—Preserves an NPC driver's active GTA station once during takeover.
Config.MinVolume / MaxVolumenumber0.0 / 1.0—Slider bounds before managed output scaling.
Config.ServerRateLimitMsnumber75—Minimum interval between accepted state-changing requests.
KeyTypeDefaultDescription
VehicleRestrictions.DisableEmergencyVehiclesbooleantrueBlocks the normal entertainment UI for GTA class 18.
VehicleRestrictions.DisabledModelsarray{}Spawn names or model hashes that cannot use normal Radio.
AccessoryPower.EnabledbooleantrueRetains a powered radio after engine shutdown.
AccessoryPower.ResumeOnEngineStartbooleantrueRestores remembered source, station, volume, and playlist state.
AccessoryPower.DriverDoorIndexnumber0Door that releases retained accessory power.
AccessoryPower.DoorOpenThresholdnumber0.05Open ratio that triggers retained-power shutdown.
Default accessory lifecycletext
engine running + radio on
-> engine off: accessory state remains active
-> driver door opens: radio powers down and remembers state
-> later engine start: remembered source and station restore

Bluetooth resumes from its retained position only when it had been playing before shutdown. The engine-stop and entity-resolution grace periods prevent brief native-state or network-entity flicker from destroying and recreating media.

04 / Interface

Displays and controls

KeyTypeDefaultDescription
MiniRadio.EnabledByDefaultbooleantrueDefault local compact-display preference.
MiniRadio.X / Ynumber0.88 / 0.84Default normalized screen position.
MiniRadio.Scalenumber1.0Default player scale.
MiniRadio.MinScale / MaxScalenumber0.70 / 1.50Player resize bounds.
AccentPicker.EnabledbooleantrueLets players save a fixed display accent or choose AUTO.
AccentPicker.DefaultColorhex color#41d9ffFallback accent for the display.
ScannerHud.VisibleByDefaultbooleantrueInitial local HUD preference.
ScannerHud.ToggleCommand / ToggleKeystringsascanner / JSynchronized scanner power controls.
ScannerHud.VisibilityCommandstringscannerhudLocal HUD-only visibility control.
ScannerHud.DriverOnlybooleantrueLimits scanner HUD presentation to the driver.
ScannerHud.SpectrumBandsnumber24Display band count; direct Sound sources can supply real spectrum data.
ScannerHud.ActivityThreshold / ActivityHoldMsnumber0.045 / 550Voice-style meter trigger and hold behavior.
CommandArgumentsContextDescription
/saradio—ClientToggle the main head unit.
+sanandreasradio / -sanandreasradioQ by defaultClientMapped head-unit press and release commands.
Escape—ClientClose the focused head unit without opening the native pause menu.
/saradiotrack—ClientPrint native station and track metadata to F8 when configured.
/sascanner—ClientToggle synchronized scanner power.
/scannerhud—ClientToggle only this player's scanner HUD preference.

The mini-radio position, scale, visibility, and accent are local KVP preferences. It hides while paused, powered off, or before engine/accessory state permits it.

Scanner power is shared per vehicle; scanner HUD visibility is local. When compatible spectrum data is unavailable, the HUD uses a procedural voice-style activity meter.

05 / Provider

Audio provider and managed output

KeyTypeDefaultDescription
Config.Audio.EnabledbooleantrueMaster switch for Satellite, Server Radio, Bluetooth, and scanner rendering.
Config.Audio.OutputVolumeScalenumber0.30Maps the full head-unit slider onto a safer provider range.
Config.Audio.OutputVolumeCeilingnumber0.82Soft upper guard for music and Bluetooth.
Config.Audio.ScannerStartupFadeMsnumber180Starts Dispatch muted, seeks, then fades to profile volume.
Config.Audio.SyncSatelliteStreamsbooleantrueSupplies stable syncGroup hints for matching live stations.
Config.Audio.Providerstringsan_andreas_soundSelected adapter name.
Config.Audio.Resourcesmap—Maps adapter names to installed resource folders.
Config.Audio.Resourcestringsan_andreas_soundLegacy/custom provider folder override.
Config.Audio.MaxDistancenumber28.0Normal managed-music radius.
Config.Audio.ExteriorVolumeMultipliernumber0.18Exterior music trim.
Config.Audio.ExteriorVolumeMultiplierByClass[14]number0.30Higher trim for generally open-cabin boats.
Config.Audio.ExteriorMaxDistancenumber18.0Exterior managed-music radius.
Config.Audio.EngineStopGraceMsnumber1200Avoids churn during engine-state flicker.
Config.Audio.EntityResolveGraceMsnumber1500Retains audio through brief network-entity lookup gaps.
Config.Audio.PositionUpdateMsnumber350Compatibility provider position update interval.
06 / Native source

Local GTA Radio

Config.Stations controls which valid native GTA station IDs appear and in what tuner order. Removing an entry hides it from this UI. Radio reads GTA's active track text ID, resolves built-in labels, validates the driver as metadata publisher, and shares the result with occupants.

Optional artwork is a local JPG under san_andreas_radio/web/assets/stations. Without an explicit filename, the NUI derives a lowercase label slug. Add manifest patterns before using other artwork extensions.

KeyTypeDefaultDescription
Config.Metadata.EnabledbooleantruePublishes native track metadata.
Config.Metadata.PollMsnumber750Client native-track polling interval.
Config.Metadata.RetuneDelayMsnumber1000Delay before accepting metadata after tuning.
Config.Metadata.ServerRateLimitMsnumber400Minimum server interval for validated metadata updates.
Config.Metadata.DebugCommandstringsaradiotrackF8 diagnostic command.
Config.TrackMetadata[id]table—Optional title/artist correction for missing GTA labels.
07 / External streams

Satellite Radio and now-playing metadata

  1. Confirm permission for the intended server use and distribution of configuration and artwork.
  2. Find a direct browser-playable endpoint rather than a web-player page. Prefer stable HTTPS MP3, AAC, OGG, or browser-playable HLS without login, cookies, or expiring tokens.
  3. Test the exact endpoint in FiveM's embedded browser environment.
  4. Prepare locally hosted, authorized station artwork and add the station to the active Config.Streams table.
  5. Add JSON or SSE metadata mapping when available, or provide Config.StreamMetadata fallback text.
  6. Restart Radio, test inside/outside behavior and cleanup, and compare two vehicles on the same live station.
One Config.Streams entry
KeyTypeDefaultRequiredDescription
idstring—YesUnique synchronized identity; an uppercase SATELLITE_ prefix is recommended.
labelstring——Full station name.
shortstringSAT—Compact source label.
genrestring——Description beneath now-playing text.
accent#RRGGBB——Station display color.
artworkstring——Radio-owned JPG filename under web/assets/stations.
urlURL—YesDirect media endpoint.
metadatatable——Optional JSON polling or SSE definition.
Metadata definition fields
KeyTypeAccepted valuesRequiredDescription
typestringjson | sseYesTransport used for now-playing data.
urlHTTPS URL—YesCORS-enabled metadata endpoint.
pollMsnumber——Clamped JSON polling interval; do not use it as high-frequency telemetry.
dataPathdot path——Selects the record or list containing current data.
station / stationPathstring / dot path——Selects one station from a shared feed.
artistPath / titlePath / idPathdot path——Maps separate artist, title, and stable update ID fields.
combinedPath / separatordot path / string——Splits one combined Artist - Title field.
fallbackArtistPath / fallbackTitlePathdot path——Program-level fallback fields when song values are absent.
The stream plays but fallback text never updates.

Likely causes

  • Metadata CORS is blocked
  • The response path is wrong
  • The endpoint is not HTTPS

Checks

  1. Inspect the exact response
  2. Correct data/artist/title paths
  3. Test endpoint CORS in FiveM CEF

Expected result

Validated now-playing fields synchronize to occupants.

The feed selects the wrong station record.

Likely causes

  • station and stationPath are missing or incorrect

Checks

  1. Map the shared feed's station key

Expected result

The configured station record is selected before metadata paths are read.

Two vehicles drift on one live station.

Likely causes

  • SyncSatelliteStreams is disabled
  • The provider ignores syncGroup
  • CORS forced HTML fallback

Checks

  1. Confirm matching URL/group and webaudio diagnostics

Expected result

A compatible provider fans one live decode into independent vehicle branches.

08 / Scanner

Scanner profiles and Dispatch mapping

Desired sourceDispatch mappingProfile URL
Local Dispatch onlyMap profile to channelMay remain empty.
External stream onlyLeave unmapped or disable DispatchRequired direct URL.
Local Dispatch with fallbackMap profile to channelRequired direct fallback URL.
YouTube live fallbackEither mapped or unmappedSupported channel /live URL with resolver enabled.
Config.ScannerProfiles entry
KeyTypeDefaultRequiredDescription
Idstring—YesStable lowercase profile ID used by power and Dispatch mapping.
Enabledbooleantrue—Profile master switch.
UrlURL——External source or fallback; may be empty for a mapped local channel.
ResolveYouTubeLivebooleanfalse—Resolve a supported YouTube channel /live page.
YouTubeRefreshMinutesnumber10—Live-page refresh interval.
Label / HudLabelstring—YesFull channel name and compact receiver heading.
HudAccent#RRGGBB—YesScanner display color.
Volumenumber0.10—In-cabin scanner source level.
RequireEnginebooleanfalse—Require an active engine.
DisableNativeScannerbooleantrue—Suppress GTA scanner for this profile.
Loopbooleantrue—Loop continuous external profiles; local Dispatch descriptors remain non-looping.
VehicleModelsarray——Explicit spawn names checked before broad classes.
VehicleClassesarray——Broad GTA class eligibility.
DisabledModelsarray——Hard exclusions applied before profile matching.
MaxDistancenumber20.0—Scanner radius.
MuffleOutsideVehiclebooleantrue—Apply provider exterior shaping.
ExteriorVolumeMultipliernumber0.30—Exterior scanner trim; marine defaults to 0.50.
ExteriorMaxDistancenumber10.0—Exterior scanner radius.
EngineStopGraceMsnumber1200—Avoid brief lifecycle churn.
GTA class or strategyTypical profile
Explicit model before broad classFire apparatus and ambulances before the class 18 emergency fallback.
18Police/general emergency fallback.
15 and 16Aviation.
14Marine.
17 and 20 plus explicit utility modelsService/commercial.

Profiles are evaluated in order. Explicit VehicleModels win before broad VehicleClasses, and a model listed in any enabled profile's DisabledModels receives no configured scanner.

For local Dispatch, Config.Dispatch.ProfileChannels maps Radio profile IDs to Dispatch channel IDs. A healthy local descriptor takes priority; a profile URL is used only when the profile is unmapped or its mapped source is unavailable.

  1. Restart Dispatch after catalog changes and Radio after profile or mapping changes.
  2. Enter an explicitly listed model and confirm it wins over a broad class profile.
  3. Verify channel, system, talkgroup, destination, frequency, and STANDBY/RECEIVING state.
  4. Toggle scanner power with the key, /sascanner, and conditional head-unit control; use /scannerhud to test local visibility only.
  5. Confirm GTA's native scanner is suppressed only where intended.
  6. Stop Dispatch temporarily only when intentionally testing a configured URL fallback.
  7. Test engine state, exit/re-entry, pause, deletion, and independent restarts.
09 / Server Radio

Register Station Packs

KeyTypeDefaultDescription
Config.ServerRadio.EnabledbooleantrueMakes Server Radio available when a valid pack is running.
Config.ServerRadio.AcousticClassstringserver_musicOptional provider hint for peak-controlled local media.
Config.ServerRadio.VolumeMultipliernumber0.70Inside-and-outside trim for locally hosted station media.
Config.ServerRadio.ExteriorVolumeMultipliernumber0.75Additional exterior trim after normal Radio exterior shaping.
Config.ServerRadio.Resourcesarray{ 'san_andreas_station_pack' }Exact installed station-pack resource names.
  1. Install each pack beside Radio and start it before Radio.
  2. Append each exact folder name to Config.ServerRadio.Resources; do not overwrite other needed packs.
  3. Confirm every pack exposes GetStations and GetSnapshot and emits the local stationPackChanged event.
  4. Restart the pack and then Radio, choose the SERVER source, and verify catalog, artwork, metadata, and audio.
  5. Tune two vehicles at different times and confirm the same program offset; restart only the pack and confirm its stable clock reconstructs the schedule.
  6. Normalize local media before adjusting the two Server Radio trims.
10 / Bluetooth

Bluetooth playlists and URL security

KeyTypeDefaultAccepted valuesDescription
Config.Bluetooth.Enabledbooleantrue—Enables player-supported URL playback.
FetchVideoTitlesbooleantrue—Uses YouTube oEmbed to resolve presentation titles.
AllowDirectUrlsbooleanfalse—When false, restricts URLs to the configured host allowlist.
AllowHttpbooleanfalse—Rejects insecure HTTP by default.
MaxUrlLengthnumber512—Maximum accepted submitted URL length.
AllowedHostsarray——Approved YouTube and youtube-nocookie hosts in the release config.
Playlist.Enabledbooleantrue—Enables saved multi-link lists.
Playlist.MaxTracksnumber30—Player saved-list cap; Radio's effective safety maximum is 100.
Playlist.AllowDuplicatesbooleanfalse—Controls repeated URLs.
Playlist.AutoAdvancebooleantrue—Advances after provider-reported natural completion.
Playlist.RepeatModestringalloff | all | oneDefault repeat behavior.
Playlist.ShuffleByDefaultbooleanfalse—Default local shuffle preference.

The full saved playlist remains in the player's local KVP. The server receives a validated transient queue for the active vehicle; other occupants receive only current media and the queue summary needed for synchronization.

The server rejects credentials, whitespace, control characters, unsupported schemes, overlong values, and unapproved hosts. Client or NUI validation is only feedback; the server revalidates every request and the real vehicle/seat authority.

Natural completion advances the queue once. A changing Bluetooth revision rejects duplicate completion reports from multiple listeners; intentional destroy or replacement must not invoke auto-advance.

11 / Voice integration

PMA live-player scanner bridge

The optional bridge rebroadcasts selected pma-voice radio channels into powered vehicle scanners without joining listeners to the talker's channel or modifying their PMA radio/call state.

KeyTypeDefaultAccepted valuesRequiredDescription
LiveVoiceScanner.Enabledbooleanfalse——Leave disabled until mappings and privacy behavior pass a multiplayer test.
Provider / Resourcestringpma_voice / pma-voice——Selected internal voice adapter and resource folder.
VoiceTargetnumber11-32—PMA receive target used by the adapter.
Volumenumber0.22——Scanner voice level.
UseSubmixbooleantrue——Requests the configured PMA voice treatment.
NaturalVoiceDistancenumber4.0——Avoids duplicate scanner routing when the talker is naturally audible.
DispatchDuckMultipliernumber0.20——Lowers scheduled Dispatch while live voice is active.
MaxTransmissionMsnumber120000——Releases a stuck transmission.
ShowPlayerNamebooleanfalse——Privacy-preserving default; true sends the current server name to eligible listeners.
ProfileChannelsmap——YesMaps scanner profile IDs to positive PMA channel definitions with labels, frequency, and priority.
  • Start pma-voice before Radio when the bridge is enabled.
  • A talker must actively transmit on a configured PMA channel; a listener must occupy a powered matching scanner vehicle.
  • Radio avoids a duplicate path when listener and talker share the PMA radio channel, share a call, or are within NaturalVoiceDistance.
  • One talker is selected per vehicle. Higher profile priority wins; optional Range can constrain reach. Keep channel numbers unique because the first duplicate definition wins.
  • Set UseSubmix=false temporarily when isolating provider or submix behavior.
  1. Put client A on one mapped PMA radio channel.
  2. Put client B in an eligible powered scanner vehicle, on a different PMA channel or none, and move beyond natural voice range.
  3. Transmit from A and confirm B hears the scanner route and sees the configured metadata.
  4. Move B onto A's channel, then within natural range, and confirm no obvious duplicate path.
  5. Test Dispatch ducking, scanner off, exit, deletion, talker disconnect, timeout, and independent resource restarts.
  6. Test player-name display both ways, then restore the intended privacy setting.
12 / API

Public cross-resource contract

GetVehicleRadioState

exportServer

Return the suite-managed raw state for one networked vehicle. Copy needed fields immediately and never mutate or retain the returned table.

Signaturelua
GetVehicleRadioState(vehicleNetId)
Returns
nil or raw read-only state table
  • State includes station, mode, volume, powered, accessory, spatial, track, Bluetooth, and revision.
  • Radio exposes no supported external setter, callback, or outward state-change event.
  • Internal san_andreas_radio network events are validated player-action implementation details, not public automation APIs.
State areaFields
Corestation, mode, volume, powered, accessory, spatial, revision
Trackfalse or { id, title, artist, source }
Bluetoothurl, label, playing, base position, startedAt, and revision
13 / Operations

Diagnostics and troubleshooting

The head unit will not open.

Likely causes

  • OneSync or lifecycle state
  • Vehicle restriction
  • Seat permission
  • Key mapping

Checks

  1. Confirm current vehicle/seat
  2. Check engine/accessory state and restrictions
  3. Try /saradio

Expected result

An eligible occupant opens the UI and the server accepts validated state requests.

The mini display stays hidden.

Likely causes

  • Radio power off
  • Engine/accessory state
  • Pause state
  • Local MINI preference

Checks

  1. Power on the radio
  2. Restore engine/accessory eligibility
  3. Check the local preference

Expected result

The display appears only while its lifecycle allows it.

A Satellite station is silent.

Likely causes

  • Not a direct media URL
  • HTTPS/codec/provider failure
  • Browser embedding or CORS behavior

Checks

  1. Test the exact endpoint
  2. Inspect F8 and Sound diagnostics

Expected result

The provider confirms playback through webaudio, html, or documented YouTube fallback.

A scanner never appears or uses the wrong source.

Likely causes

  • Profile order or disabled model
  • Missing mapping with blank URL
  • Class/model spelling
  • Dispatch unavailable

Checks

  1. Inspect selected profile and mapping
  2. Test explicit model precedence
  3. Check channel state and fallback URL

Expected result

The intended eligible profile supplies local Dispatch or its configured external source.

GTA and replacement scanners both play.

Likely causes

  • DisableNativeScanner is false on the selected profile

Checks

  1. Correct the matching profile, not a different profile

Expected result

Native chatter is suppressed only for intended replacement profiles.

Server Radio starts from zero or is too loud.

Likely causes

  • Incorrect final duration or seek path
  • Hot local mastering
  • Trims too high

Checks

  1. Verify Station Pack snapshot and duration
  2. Inspect Sound start confirmation
  3. Normalize media and lower both Server Radio trims

Expected result

Late listeners seek to the current offset at a balanced level.

Bluetooth stops after one track.

Likely causes

  • AutoAdvance disabled
  • Provider does not report natural completion
  • Intentional replacement incorrectly calls onPlayEnd

Checks

  1. Inspect Playlist.AutoAdvance and provider callback semantics

Expected result

Exactly one natural completion advances the queue.

Audio duplicates after restart.

Likely causes

  • More than one provider instance
  • Provider or caller cleanup does not own names correctly

Checks

  1. Run one selected provider
  2. Restart each resource separately and inspect remaining diagnostics

Expected result

Resource restart removes only owned playback and leaves no duplicate.

  • Complete the full control, source, tuner, playlist, permission, lifecycle, UI, and scanner pass with at least two clients and two vehicles.
  • Test same and different Satellite stations, every installed Dispatch profile, Station Pack late joining, and PMA routing when enabled.
  • Restart Sound, Dispatch, Station Pack, and Radio independently and confirm unrelated vehicle resources continue running.