Search by

pushinbr / pam-native-audio

DavidWilliamBalbino

Headless native audio player for PAM Native: queues, playback rate, audio focus, caching and proximity earpiece routing for voice notes.

Package info

github.com/push-in/pam-native-audio

Language:Kotlin

Type:pam-native-plugin

pkg:composer/pushinbr/pam-native-audio

Statistics

Installs: 13

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.2.1 2026-10-05 21:57 UTC

This package is auto-updated.

Last update: 2026-10-05 21:57:44 UTC


README

Headless native audio playback for PAM Native applications, built for chat voice notes and short media.

  • ExoPlayer (Media3) with audio focus, "becoming noisy" pause (headphones unplugged) and a 64 MiB LRU cache for remote files.
  • Native queue — queue() advances to the next voice note without a PHP round trip, even if PHP is busy.
  • Playback rate — 0.5× to 2× presets with pitch preserved.
  • Proximity earpiece routing — AudioRoute::Auto moves playback to the earpiece (voice stream, screen off) while the phone is at the ear, and back to the speaker when it is lowered; headsets are left alone.
  • Pushed events — progress (native ticker, coalesced), state, queue item, route, end and failure arrive through the module event channel; PHP never polls.
  • One current player — starting a player stops the previous one.

Android API 26+ and iOS 15+. On iOS the same contract runs on AVQueuePlayer: native queue and skip, pitch-preserving rate (timeDomain), progress from a periodic time observer, pause on interruptions and when headphones are unplugged, playback/spokenAudio on the speaker and playAndRecord/ voiceChat on the earpiece with UIDevice proximity monitoring (the screen turns off at the ear). Remote sources stream on first play and are stored in a 64 MiB LRU cache for the next one. The iOS implementation has not been validated on a device yet; see ios/Tests/AudioPlayerTests.swift.

Install

pam composer require pushinbr/pam-native-audio

Requires pushinbr/pam-native >=1.0.35 <2.0.0. Declared permissions: MODIFY_AUDIO_SETTINGS, WAKE_LOCK (plus network access).

Play a voice note

use Pam\Native\Audio\{AudioPlayer, AudioRoute, PlaybackProgress, PlaybackRate, PlaybackState};

$player = AudioPlayer::make('voice/8f1c.m4a')           // sandbox-relative path or https URL
    ->rate(PlaybackRate::X1_5)
    ->route(AudioRoute::Auto)
    ->onProgress(fn (PlaybackProgress $p) => $this->setState(['progress' => $p->fraction()]))
    ->onStateChange(fn (PlaybackState $s) => $this->setState(['playing' => $s === PlaybackState::Playing]))
    ->onEnd(fn () => $this->setState(['progress' => 0]))
    ->play();

AudioPlayer::current()?->pause();
AudioPlayer::current()?->resume();
AudioPlayer::current()?->seek(12_000);
AudioPlayer::current()?->rate(AudioPlayer::current()->playbackRate()->nextVoiceNoteRate()); // 1× → 1.5× → 2×
AudioPlayer::stopAll();

Auto-advance through consecutive voice notes

AudioPlayer::make($notes[$i]->path)
    ->queue(...array_map(fn ($n) => $n->path, array_slice($notes, $i + 1)))
    ->onItemChange(fn (int $index, string $source) => $this->highlight($i + $index))
    ->onEnd(fn () => $this->highlight(null))
    ->play();

API

Method Notes
make(string $source, ?string $id = null) https://… or a relative path inside the PAM file sandbox
queue(string ...$sources) Up to 200 items, before play()
rate(PlaybackRate) / route(AudioRoute) / volume(float) Before or during playback
startAt(int $ms) / progressInterval(int $ms) Before play(); interval 50–5000 ms
onProgress / onStateChange / onItemChange / onRouteChange / onEnd / onError Pushed natively
play() / pause() / resume() / toggle() / seek() / skipTo() / stop()
AudioPlayer::current() / AudioPlayer::stopAll()

Tests

pam tests/run.php
cd android && ANDROID_SERIAL=emulator-5558 ../../../pam-native/android/gradlew -p . connectedDebugAndroidTest

The instrumented suite plays generated WAV files through ExoPlayer: queue auto-advance with progress and end events, pause/resume/seek/rate on the live player, single current player, proximity earpiece routing (voice stream, audio mode, route events) and failure handling.

License

Apache-2.0