Player Music API (apiplayermusic)

SkillMedia

Helps with Player Music API usage for MP3 music playback with automatic duration detection, pause/resume, and activity detection.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Player Music API (apiplayermusic) skill

What this skill tells your AI

The instructions your AI receives, as published by hedgefog/amxx-modding-kit in .agents/skills/amxx-modding-kit/api/player-music/SKILL.md and read by ahel’s review.

The Player Music API provides sophisticated MP3 music management with automatic duration detection, pause/resume functionality, activity detection, and event forwarding.

Reference: See README.md for complete documentation and examples.


Overview

This API allows you to:

  • Load and play MP3 tracks with automatic duration detection
  • Pause and resume playback
  • Handle player activity (game minimization)
  • Track playback events via forwards
  • Loop tracks automatically

Track Loading

Load Tracks in Precache

All tracks MUST be loaded during plugin_precache:

new PlayerMusic_Track:g_track;

public plugin_precache() {
  g_track = PlayerMusic_LoadTrack("media/Half-Life01.mp3");
}

Load Multiple Tracks

new const g_rgszMusicList[][] = {
  "media/ambient01.mp3",
  "media/ambient02.mp3",
  "media/ambient03.mp3"
};

new PlayerMusic_Track:g_rgTracks[sizeof(g_rgszMusicList)];

public plugin_precache() {
  for (new i = 0; i < sizeof(g_rgszMusicList); ++i) {
    g_rgTracks[i] = PlayerMusic_LoadTrack(g_rgszMusicList[i]);
  }
}

Playback Control

Play Track

// Play immediately
PlayerMusic_Player_PlayTrack(pPlayer, g_track);

// Play with delay
PlayerMusic_Player_PlayTrack(pPlayer, g_track, 5.0); // 5 second delay

// Play looped
PlayerMusic_Player_PlayTrack(pPlayer, g_track, 0.0, true);

Stop/Pause/Resume

// Stop current track
PlayerMusic_Player_StopTrack(pPlayer);

// Pause current track
PlayerMusic_Player_PauseTrack(pPlayer);

// Resume paused track
PlayerMusic_Player_ResumeTrack(pPlayer);

Query State

// Check if track is paused
if (PlayerMusic_Player_IsTrackPaused(pPlayer)) {
  // Handle paused state
}

// Check if track is looped
if (PlayerMusic_Player_IsTrackLooped(pPlayer)) {
  // Handle looped state
}

// Check if track has started playing
if (PlayerMusic_Player_IsTrackStarted(pPlayer)) {
  // Track is actively playing
}

// Get remaining time
new Float:flTimeLeft = PlayerMusic_Player_GetTrackTimeLeft(pPlayer);

Get Current Track

new PlayerMusic_Track:track = PlayerMusic_Player_GetTrack(pPlayer);
if (track == PlayerMusic_Track_Invalid) {
  // No track playing
}

Track Information

new szTitle[64]; PlayerMusic_GetTrackTitle(track, szTitle, charsmax(szTitle));
new szArtist[64]; PlayerMusic_GetTrackArtist(track, szArtist, charsmax(szArtist));
new szAlbum[64]; PlayerMusic_GetTrackAlbum(track, szAlbum, charsmax(szAlbum));
new iYear = PlayerMusic_GetTrackYear(track);

Event Forwards

Hook into playback events:

// Called when track is scheduled
public PlayerMusic_OnTrackScheduled(pPlayer, PlayerMusic_Track:track, bool:bLoop, Float:flStartTime) {
  // Track scheduled for playback
}

// Called when track starts playing
public PlayerMusic_OnTrackStart(pPlayer, PlayerMusic_Track:track) {
  // Track playback started
}

// Called when track ends
public PlayerMusic_OnTrackEnd(pPlayer, PlayerMusic_Track:track, bool:bStopped) {
  // bStopped = true if manually stopped, false if ended naturally

  if (!bStopped) {
    // Play next track in queue
    PlayNextTrack(pPlayer);
  }
}

// Called when track is paused
public PlayerMusic_OnTrackPause(pPlayer, PlayerMusic_Track:track) {
  // Handle pause
}

// Called when track is resumed
public PlayerMusic_OnTrackResume(pPlayer, PlayerMusic_Track:track) {
  // Handle resume
}

// Called when looped track restarts
public PlayerMusic_OnTrackLoop(pPlayer, PlayerMusic_Track:track) {
  // Track looped to beginning
}

Common Patterns

Auto-Play on Connect

public client_putinserver(pPlayer) {
  // Schedule random track with delay
  new iTrackIndex = random(sizeof(g_rgTracks));
  PlayerMusic_Player_PlayTrack(pPlayer, g_rgTracks[iTrackIndex], 5.0);
}

Continuous Playlist

public PlayerMusic_OnTrackEnd(pPlayer, PlayerMusic_Track:track, bool:bStopped) {
  if (bStopped) return;

  // Play next random track
  new iNext = random(sizeof(g_rgTracks));
  PlayerMusic_Player_PlayTrack(pPlayer, g_rgTracks[iNext], 2.0);
}

Round-Based Music

public Round_OnStart() {
  for (new pPlayer = 1; pPlayer <= MaxClients; ++pPlayer) {
    if (!is_user_connected(pPlayer)) continue;

    PlayerMusic_Player_PlayTrack(pPlayer, g_trackRoundStart);
  }
}

public Round_OnEnd(iTeam) {
  new PlayerMusic_Track:track = (iTeam == TEAM_WIN) ? g_trackVictory : g_trackDefeat;

  for (new pPlayer = 1; pPlayer <= MaxClients; ++pPlayer) {
    if (!is_user_connected(pPlayer)) continue;

    PlayerMusic_Player_StopTrack(pPlayer);
    PlayerMusic_Player_PlayTrack(pPlayer, track);
  }
}

Display Track Info HUD

new g_pHudObj;

public plugin_init() {
  g_pHudObj = CreateHudSyncObj();
  set_task(1.0, "Task_ShowTrackInfo", 0, _, _, "b");
}

public Task_ShowTrackInfo() {
  for (new pPlayer = 1; pPlayer <= MaxClients; ++pPlayer) {
    if (!is_user_connected(pPlayer)) continue;

    new PlayerMusic_Track:track = PlayerMusic_Player_GetTrack(pPlayer);
    if (track == PlayerMusic_Track_Invalid) continue;

    static szTitle[64]; PlayerMusic_GetTrackTitle(track, szTitle, charsmax(szTitle));
    static Float:flTimeLeft; flTimeLeft = PlayerMusic_Player_GetTrackTimeLeft(pPlayer);

    set_hudmessage(255, 255, 255, 0.02, 0.9, 0, 0.0, 1.1, 0.0, 0.0);
    ShowSyncHudMsg(pPlayer, g_pHudObj, "Now Playing: %s (%.0fs)", szTitle, flTimeLeft);
  }
}

Automatic Features

The API automatically handles:

  • Game Minimization: Pauses music when player minimizes game
  • Volume Changes: Responds to MP3 volume setting changes
  • Resume Logic: Intelligently resumes at correct position
  • Timing Accuracy: Maintains precise timing through pauses

Checklist

  • Load all tracks in plugin_precache
  • Handle PlayerMusic_OnTrackEnd for playlists
  • Check PlayerMusic_Track_Invalid when getting current track
  • Consider delayed start for connect music
  • Use forwards to react to playback events

Signals

GitHub stars
32
Forks
4
Last commit
Aug 2026
Advanced
Catalog kind
skill
Gateway key
amxx-modding-kit-api-player-music
Source
github.com/hedgefog/amxx-modding-kit