@pozalabs/pori
v0.6.0
Published
Audio library for React — waveform visualization, HLS streaming, and playlist management
Downloads
180
Maintainers
Readme
pori
A React audio library built for fast loading and flexible UI composition.
pori gives you optimized audio fetching out of the box and a layered API: use headless hooks for full control, or compose pre-built components to ship faster.
Features
- Optimized Audio Loading - Adaptive chunking with parallel downloads and automatic retries
- Headless Hooks -
useAudio,usePlaylist,useWaveformwork independently from any UI - Compound Components - Pick and arrange only the sub-components you need
- Waveform Visualization - Canvas and SVG renderers with line/bar variants and hover preview
- HLS Streaming - Automatic detection and playback for
.m3u8sources - TypeScript - Full type coverage
Installation
npm install @pozalabs/poriRequires React 18 or later.
For HLS streaming (.m3u8), install hls.js as well:
npm install hls.jsQuick Start
Compose an audio player
Wrap sub-components inside AudioPlayer.Provider to build the exact player you need.
import { AudioPlayer } from '@pozalabs/pori';
const playlist = [
{ id: '1', src: '/audio/track-01.mp3' },
{ id: '2', src: '/audio/track-02.mp3' },
];
function Player() {
return (
<AudioPlayer.Provider playlist={playlist}>
<AudioPlayer.PlayPauseButton />
<AudioPlayer.ProgressBar />
<AudioPlayer.CurrentTime format="MM:SS" />
<AudioPlayer.Duration format="MM:SS" />
<AudioPlayer.VolumeProgressBar />
</AudioPlayer.Provider>
);
}Go headless
Use hooks directly when you need a fully custom UI.
import { useAudio } from '@pozalabs/pori';
function CustomPlayer({ src }: { src: string }) {
const { isPlaying, currentTime, duration, togglePlayPause } = useAudio({ src });
return (
<div>
<button onClick={() => togglePlayPause()}>
{isPlaying ? 'Pause' : 'Play'}
</button>
<span>{currentTime} / {duration}</span>
</div>
);
}API Overview
Hooks
useAudio
Core audio playback, volume, playback rate, keyboard shortcuts. See Quick Start for usage.
usePlaylist
Extends useAudio with playlist management and repeat modes (none, one, all).
import { usePlaylist } from '@pozalabs/pori';
const playlist = [
{ id: '1', src: '/audio/track-01.mp3' },
{ id: '2', src: '/audio/track-02.mp3' },
];
function Player() {
const { isPlaying, togglePlayPause, playNextAudio } = usePlaylist({ playlist });
return <button onClick={() => playNextAudio()}>Next</button>;
}useWaveform
Audio visualization with Canvas/SVG rendering and interactive controls.
import { useWaveform } from '@pozalabs/pori';
function WaveformPlayer() {
const { waveform, isPlaying, play, pause } = useWaveform({ src: '/audio.mp3' });
return <div ref={(el) => el && waveform && el.appendChild(waveform)} />;
}Components
AudioPlayer
Compound component with Provider and composable sub-components. See Quick Start for usage.
AudioPlayer.Provider- Provides audio player state and controlsAudioPlayer.Playlist- Renders playlist itemsAudioPlayer.CurrentTime- Displays current playback timeAudioPlayer.Duration- Displays total durationAudioPlayer.ProgressBar- Playback position sliderAudioPlayer.VolumeProgressBar- Volume level sliderAudioPlayer.PlayButton- Starts playbackAudioPlayer.PauseButton- Pauses playbackAudioPlayer.PlayPauseButton- Toggles play/pauseAudioPlayer.StopButton- Stops and resets playbackAudioPlayer.ShiftForwardButton- Advances playback by time shiftAudioPlayer.ShiftBackwardButton- Rewinds playback by time shiftAudioPlayer.SkipStartButton- Restarts or skips to previousAudioPlayer.SkipEndButton- Skips to nextAudioPlayer.RepeatButton- Cycles repeat modeAudioPlayer.VolumeButton- Toggles mute
Waveform
Standalone waveform visualization component.
import { useRef } from 'react';
import { Waveform } from '@pozalabs/pori';
import type { WaveformHandles } from '@pozalabs/pori';
function Player() {
const ref = useRef<WaveformHandles>(null);
return <Waveform ref={ref} src="/audio.mp3" />;
}Slider
General-purpose slider for building custom progress/volume bars.
import { useState } from 'react';
import { Slider } from '@pozalabs/pori';
function VolumeControl() {
const [volume, setVolume] = useState(50);
return <Slider value={volume} onChange={setVolume} />;
}Utilities
fetchAudio
Chunked parallel download with retry.
import { fetchAudio } from '@pozalabs/pori';
const audioBuffer = await fetchAudio({ src: '/audio.mp3' });getAudioFileInformation
Retrieves audio file metadata (type, size) via a HEAD request.
Development
bun dev # Dev server (port 3000)
bun run build # Build with tsup
bun run test # Run tests
bun run lint # Lint