🚧 VeloxKit is pre-release software. APIs may change before v1.0. Get started →
Documentation
APIs & Bindings
audio

audio Stable WINMACLNX

Play audio files from disk via the OS audio stack (rodio + symphonia). Supports MP3, FLAC, OGG Vorbis, and WAV.

Capability

veloxkit.config.json
{
  "capabilities": ["audio"]
}

Import

import { audio } from 'veloxkit'

audio.play(src, opts?)

Starts playback and returns a player handle for all subsequent control.

const player = await audio.play('/path/to/track.mp3', {
  volume: 0.8,        // 0.0 – 1.0, default 1.0
  onEnded: () => {    // optional: fires when playback finishes naturally
    console.log('done')
  },
})

Player handle

MethodReturnsDescription
player.pause()voidPause playback
player.resume()voidResume from pause
player.play()voidAlias for resume()
player.stop()voidStop and release the sink
player.setVolume(v)voidSet volume 0.0 – 1.0
player.getVolume()numberCurrent volume
player.getTime()numberPlayback position in seconds
player.getDuration()Promise<number>Total duration in seconds; -1 if unknown
player.seek(secs)Promise<void>Jump to position
player.onEnded(cb)voidRegister an additional end callback

Supported formats

FormatExtensions
MP3.mp3
FLAC.flac
OGG Vorbis.ogg
WAV / PCM.wav

Examples

Basic play / stop

import { audio } from 'veloxkit'
import { View, Pressable, Text } from 'veloxkit'
import { useRef } from 'react'
 
function SoundButton() {
  const playerRef = useRef(null)
 
  return (
    <View style={{ flexDirection: 'row', gap: 8 }}>
      <Pressable
        onPress={async () => {
          playerRef.current = await audio.play('/assets/sounds/click.wav', { volume: 0.6 })
        }}
        style={{ padding: 12, backgroundColor: '#3a3a5e', borderRadius: 8 }}
      >
        <Text>Play</Text>
      </Pressable>
      <Pressable
        onPress={() => playerRef.current?.stop()}
        style={{ padding: 12, backgroundColor: '#3a3a5e', borderRadius: 8 }}
      >
        <Text>Stop</Text>
      </Pressable>
    </View>
  )
}

Music player with live progress

import { audio } from 'veloxkit'
import { useState, useRef, useEffect } from 'react'
 
function MusicPlayer({ src }: { src: string }) {
  const playerRef = useRef(null)
  const [playing, setPlaying]   = useState(false)
  const [position, setPosition] = useState(0)
  const [duration, setDuration] = useState(0)
 
  const handlePlay = async () => {
    const p = await audio.play(src, {
      onEnded: () => { setPlaying(false); setPosition(0) },
    })
    playerRef.current = p
    setPlaying(true)
    setDuration(await p.getDuration())
  }
 
  // Poll position every 250 ms while playing
  useEffect(() => {
    if (!playing) return
    const id = setInterval(() => {
      setPosition(playerRef.current?.getTime() ?? 0)
    }, 250)
    return () => clearInterval(id)
  }, [playing])
 
  return (
    <View style={{ gap: 12, padding: 16 }}>
      <Text>
        {playing ? `${position.toFixed(1)} / ${duration.toFixed(1)} s` : 'Stopped'}
      </Text>
      <Pressable
        onPress={playing ? () => playerRef.current?.pause() : handlePlay}
        style={{ padding: 12, backgroundColor: '#4a4a7e', borderRadius: 8 }}
      >
        <Text>{playing ? 'Pause' : 'Play'}</Text>
      </Pressable>
    </View>
  )
}

Auto-advance playlist

function playPlaylist(tracks: string[], index = 0) {
  if (index >= tracks.length) return
  audio.play(tracks[index], {
    onEnded: () => playPlaylist(tracks, index + 1),
  })
}
 
playPlaylist(['/music/intro.mp3', '/music/loop.mp3', '/music/outro.mp3'])

Fade out before stopping

async function fadeOut(player, durationMs = 1000) {
  const steps = 20
  const stepMs = durationMs / steps
  const start = player.getVolume()
  for (let i = steps; i >= 0; i--) {
    player.setVolume((start * i) / steps)
    await new Promise(r => setTimeout(r, stepMs))
  }
  player.stop()
}

The audio device is opened lazily on the first audio.play() call. If no audio output is available the Promise rejects with a descriptive error.

⚠️

File paths must be absolute. The audio subsystem reads the file directly without the fs capability — but the file must exist at the given path.