@clxrity/react-audio
A react audio player component library.
npm i @clxrity/react-audio
pnpm add @clxrity/react-audio
yarn add @clxrity/react-audio
Components
Component | Controls | Customizable | Display Track Info |
---|
<JustPlayer/> | Play/pause | ✅ | ❌ |
<Waveform /> | Play/pause, volume, progress, mute/unmute | ✅ | ❌ |
<AudioPlayer/> | Play/pause, volume, progress, mute/unmute | ✅ | ✅ |
<AudioLibrary/> | Play/pause, volume, progress, mute/unmute, next/previous | ✅ | ✅ |
Waveform Images API (Experimental)
- Install with optional dependencies to use the waveform image generation API.
npm i @clxrity/react-audio --save-optional
Works ONLY with Nextjs App Router
You can generate an image of an audio file's waveform by using the setup-waveform-api
script.
npx setup-waveform-api
- This will create a
app/api/generate-waveform/route.ts
file.
import fluentFfmpeg from 'fluent-ffmpeg';
import path from 'path';
import { NextRequest, NextResponse } from 'next/server';
export async function GET(req: NextRequest) {
const url = new URL(req.url);
const audioUrl = url.searchParams.get('url');
if (!audioUrl) {
return NextResponse.json({ error: 'Missing URL query parameter' }, { status: 400 });
}
const waveformPath = path.join(process.cwd(), 'public', 'waveform.png');
const promise = new Promise((resolve, reject) => {
fluentFfmpeg(audioUrl)
.audioFilters('aformat=channel_layouts=stereo')
.outputOptions('-filter_complex', 'aformat=channel_layouts=stereo,showwavespic=s=600x120')
.output(waveformPath)
.on('end', () => {
resolve(NextResponse.json({ message: `Waveform image at ${waveformPath}` }, { status: 200 }));
})
.on('error', (err) => {
reject(NextResponse.json({ error: err }, { status: 500 }));
})
.run();
});
return promise;
}
- You can then use this route to generate waveform images.
- Note: If you are using
fetch()
to handle the API request, make sure to pass the absolute URL of the audio file.
await fetch('http://localhost:3000/api/generate-waveform?url=http://localhost:3000/audio.wav')
- This will generate a waveform image in the
public/
directory. (e.g. public/waveform.png
)
<JustPlayer />
Features
- Just a play button
- Customizable style
- Loading state
Use-case
- Best for mapping over audio files in a visually small listed component
'use client'
import { JustPlayer } from '@clxrity/react-audio'
export default function Component() {
return (
<JustPlayer
track={{
src: '/audio.wav',
}}
/>
)
}
Styling
<JustPlayer
track={tracks[0]}
size={50} {}
style={{
backgroundColor: "red",
padding: "1rem",
borderRadius: "1rem",
boxShadow: "0 0 1rem rgba(0, 0, 0, 0.1)",
display: "flex",
alignItems: "center",
justifyContent: "center"
}} {}
/>
<Waveform />
Features
- Audio wave visualizer
- Screen responsive
- Volume controls
- Progress bar
Use-case
- Best for displaying the audio wave
'use client'
import { type Track, Waveform } from '@clxrity/react-audio'
const track: Track = {
}
export default function Component() {
return (
<Waveform
track={track}
size={{
width: window.innerWidth,
height: window.innerHeight,
}}
color="#ff0000"
/>
)
}
Styling
'use client'
export default function Component() {
return (
<Waveform
track={track}
canvasStyles={{
borderRadius: '0.5rem',
border: '1px solid #333',
}}
size={{
width: 300,
height: 120,
}}
/>
)
}
<AudioPlayer />
Features
- Visualized audio player
- Screen responsive
- Volume controls
- Progress bar
Use-case
- Best for displaying a singular audio track
'use client'
import { type Track, AudioPlayer } from '@clxrity/react-audio'
const track: Track = {
src: '/audio.wav',
title: 'Track Title',
author: {
name: 'Track Author',
url: 'https://www.someurl.com',
},
thumbnail: './favicon.ico',
}
export default function Component() {
return <AudioPlayer track={track} />
}
<AudioLibrary />
Features
- A visualized audio library with multiple tracks
- Controls
- Progress bar
- Volume control
- Screen responsive
- Autoplay next song
Use-case
- Best for displaying collections of audio files
'use client'
import { AudioLibrary } from '@clxrity/react-audio'
import { tracks } from './data'
export default function Component() {
return (
<div>
<AudioLibrary tracks={tracks} />
</div>
)
}
Styling
<AudioLibrary
tracks={tracks}
styles={{
backgroundColor: 'transparent',
textColor: 'white',
boxShadow: '10px 5px 5px red',
theme: 'dark',
border: '1px solid white',
}}
/>
Construct the audio library yourself
If you'd like further customization, import the base components:
import {
LibraryPlayer,
LibraryTrackItem,
} from '@clxrity/react-audio'
'use client'
import {
type Track,
} from '@clxrity/react-audio'
import { useState } from 'react'
const tracks: Track[] = [
]
export default function Component() {
const [currentTrackIndex, setCurrentTrackIndex] = useState(-1)
const currentTrack = tracks[currentTrackIndex]
return (
<div>
<h1>My songs</h1>
<ul>
{tracks.map((track, index) => (
<LibraryTrackItem
key={index}
selected={index === currentTrackIndex}
track={track}
trackNumberLabel={index}
onClick={() => setCurrentTrackIndex(index)}
/>
))}
</ul>
<LibraryPlayer
key={currentTrackIndex}
currentTrack={currentTrack}
trackIndex={current}
trackCount={tracks.length}
onNext={() => setCurrentTrackIndex((i) => i + 1)}
onPrev={() => setCurrentTrackIndex((i) => i - 1)}
/>
</div>
)
}
Further customization
Example from clxrity.xyz
See examples for more specific usage demonstrations