ngx-audio-wave
v20.2.7
Published
A modern, accessible audio wave visualization component for Angular 20+ with comprehensive keyboard navigation and screen reader support.
Maintainers
Readme
ngx-audio-wave
A modern, accessible audio wave visualization component for Angular 20+ with comprehensive keyboard navigation and screen reader support.
Features
- 🎵 Audio Wave Visualization - Beautiful SVG-based audio wave display
- ⌨️ Full Keyboard Support - Complete keyboard navigation (Space, Enter, Arrow keys, Home, End)
- ♿ Accessibility First - WCAG 2.1 compliant with ARIA support
- 🎨 Highly Customizable - Colors, dimensions, gaps, and styling options
- 📱 Responsive Design - Works on all screen sizes
- 🚀 Modern Angular - Built with Angular 20+ signals and standalone components
- 🎯 TypeScript - Full type safety and IntelliSense support
Demo
🎮 Live Demo - Try the interactive demo

Quick Start
Installation
npm install ngx-audio-waveAngular 20+ (Standalone Components)
import { NgxAudioWave } from 'ngx-audio-wave';
@Component({
selector: 'app-root',
standalone: true,
imports: [NgxAudioWave],
template: `
<ngx-audio-wave
ariaLabel="My audio player"
audioSrc="path/to/your/audio.mp3"
>
</ngx-audio-wave>
`,
})
export class AppComponent {}Basic Usage
<ngx-audio-wave
ariaLabel="My podcast episode"
audioSrc="https://example.com/audio.mp3"
>
</ngx-audio-wave>With Progress Information
<ngx-audio-wave #player audioSrc="assets/audio.mp3"></ngx-audio-wave>
<div class="audio-info">
<p>Progress: {{ player.exactPlayedPercent() | number:'1.1-1' }}%</p>
<p>
Time: {{ player.exactCurrentTime() | number:'1.1-1' }}s / {{
player.exactDuration() | number:'1.1-1' }}s
</p>
<p>Status: {{ player.statusText() }}</p>
</div>Note: Use
exact*properties instead of deprecatedcurrentTime,duration, andplayedPercentfor better precision.
Examples
Custom Styling
<ngx-audio-wave
[gap]="3"
[height]="50"
[rounded]="false"
audioSrc="assets/audio.mp3"
color="#ff6b6b"
>
</ngx-audio-wave>With Custom Accessibility Labels
<ngx-audio-wave
ariaLabel="Weekly Tech Podcast Episode 42"
audioSrc="assets/podcast.mp3"
pauseButtonLabel="Pause podcast"
playButtonLabel="Start podcast"
progressBarLabel="Podcast progress - use arrow keys to navigate"
>
</ngx-audio-wave>Hide Default Button
<ngx-audio-wave [hideBtn]="true" #audioPlayer audioSrc="assets/audio.mp3">
</ngx-audio-wave>
<button (click)="audioPlayer.play()">▶️ Play</button>
<button (click)="audioPlayer.pause()">⏸️ Pause</button>
<button (click)="audioPlayer.stop()">⏹️ Stop</button>Volume Control
<ngx-audio-wave #player audioSrc="assets/audio.mp3"></ngx-audio-wave>
<div class="volume-controls">
<button (click)="player.mute()">🔇 Mute</button>
<button (click)="player.unmute()">🔊 Unmute</button>
<button (click)="player.toggleMute()">🔊/🔇 Toggle</button>
<button (click)="player.setVolume(0.5)">50% Volume</button>
<button (click)="player.setVolume(1)">100% Volume</button>
</div>
<p>Current volume: {{ player.currentVolume() | percent }}</p>Playback Speed Control
<ngx-audio-wave #player audioSrc="assets/audio.mp3"></ngx-audio-wave>
<div class="speed-controls">
<button (click)="player.decreasePlaybackRate()">⏪ Slower</button>
<button (click)="player.resetPlaybackRate()">1x Normal</button>
<button (click)="player.increasePlaybackRate()">⏩ Faster</button>
<button (click)="player.setPlaybackRate(0.5)">0.5x</button>
<button (click)="player.setPlaybackRate(1.5)">1.5x</button>
<button (click)="player.setPlaybackRate(2)">2x</button>
</div>
<p>Current speed: {{ player.currentPlaybackRate() }}x</p>Loop Control
<ngx-audio-wave #player audioSrc="assets/audio.mp3"></ngx-audio-wave>
<div class="loop-controls">
<button (click)="player.enableLoop()">🔄 Enable Loop</button>
<button (click)="player.disableLoop()">⏹️ Disable Loop</button>
<button (click)="player.toggleLoop()">🔄/⏹️ Toggle Loop</button>
</div>
<p>Looping: {{ player.isLooping() ? 'Enabled' : 'Disabled' }}</p>
<!-- Auto-loop example -->
<ngx-audio-wave
[loop]="true"
audioSrc="assets/background-music.mp3"
ariaLabel="Background music with auto-loop">
</ngx-audio-wave>Different Heights and Gaps
<!-- Different heights -->
<ngx-audio-wave [height]="25" audioSrc="assets/audio.mp3"></ngx-audio-wave>
<ngx-audio-wave [height]="50" audioSrc="assets/audio.mp3"></ngx-audio-wave>
<ngx-audio-wave [height]="100" audioSrc="assets/audio.mp3"></ngx-audio-wave>
<!-- Different gaps -->
<ngx-audio-wave [gap]="1" audioSrc="assets/audio.mp3"></ngx-audio-wave>
<ngx-audio-wave [gap]="5" audioSrc="assets/audio.mp3"></ngx-audio-wave>
<ngx-audio-wave [gap]="10" audioSrc="assets/audio.mp3"></ngx-audio-wave>Accessibility Features
This component is built with accessibility as a core feature, ensuring it works seamlessly with assistive technologies and keyboard navigation.
Keyboard Navigation
| Key | Action |
| ------------------ | ----------------------------------------- |
| Space or Enter | Play/Pause audio |
| Arrow Left | Skip backward (configurable with skip) |
| Arrow Right | Skip forward (configurable with skip) |
| Home | Jump to beginning |
| End | Jump to end |
Screen Reader Support
- ARIA Labels: All interactive elements have descriptive labels
- Live Regions: Status changes are announced automatically
- Progress Information: Detailed progress text with time and percentage
- Semantic Roles: Proper ARIA roles for all components
- Focus Management: Logical tab order and focus indicators
Testing with Screen Readers
The component has been tested with:
- NVDA (Windows)
- JAWS (Windows)
- VoiceOver (macOS/iOS)
- TalkBack (Android)
API Reference
Input Properties
| Property | Type | Default | Description |
| ------------------ | ------------------- | ---------------------- | ------------------------------------------ |
| audioSrc | string \| SafeUrl | Required | URL or SafeUrl of the audio file to play |
| color | string | '#1e90ff' | Color of the audio wave bars |
| height | number | 25 | Height of the wave visualization in pixels |
| gap | number | 5 | Gap between wave bars in pixels |
| rounded | boolean | true | Whether to round the corners of wave bars |
| hideBtn | boolean | false | Hide the play/pause button |
| skip | number | 5 | Seconds to skip when using arrow keys |
| volume | number | 1 | Initial volume level (0-1) |
| playbackRate | number | 1 | Initial playback speed (0.25-4) |
| loop | boolean | false | Whether to loop the audio |
| ariaLabel | string | 'Audio player' | Main ARIA label for the component |
| playButtonLabel | string | 'Play audio' | ARIA label for the play button |
| pauseButtonLabel | string | 'Pause audio' | ARIA label for the pause button |
| progressBarLabel | string | 'Audio progress bar' | ARIA label for the progress bar |
Output Properties (Signals)
| Property | Type | Description |
| -------------------- | ----------------- | ---------------------------------------------------------- |
| isPaused | Signal<boolean> | Whether the audio is currently paused |
| isLoading | Signal<boolean> | Whether the audio is currently loading |
| hasError | Signal<boolean> | Whether there was an error loading the audio |
| currentVolume | Signal<number> | Current volume level (0-1) |
| currentPlaybackRate| Signal<number> | Current playback speed (0.25-4) |
| isLooping | Signal<boolean> | Whether the audio is currently looping |
| exactCurrentTime | Signal<number> | Current playback time in seconds (exact) |
| exactDuration | Signal<number> | Total duration in seconds (exact) |
| exactPlayedPercent | Signal<number> | Playback progress as percentage (exact) |
| currentTime | Signal<number> | Deprecated - Current playback time rounded to seconds |
| duration | Signal<number> | Deprecated - Total duration rounded to seconds |
| playedPercent | Signal<number> | Deprecated - Playback progress as percentage (rounded) |
| progressText | Signal<string> | Human-readable progress text for screen readers |
| statusText | Signal<string> | Current status text for screen readers |
Methods
| Method | Parameters | Description |
| --------------------- | --------------- | ----------------------------------------------- |
| play(time?: number) | time?: number | Play the audio, optionally from a specific time |
| pause() | - | Pause the audio |
| stop() | - | Stop the audio and reset to beginning |
| setVolume(volume) | volume: number| Set volume level (0-1) |
| mute() | - | Mute the audio |
| unmute() | - | Unmute the audio |
| toggleMute() | - | Toggle mute state |
| setPlaybackRate(rate)| rate: number | Set playback speed (0.25-4) |
| resetPlaybackRate() | - | Reset playback speed to 1x |
| increasePlaybackRate()| - | Increase playback speed by 0.25x |
| decreasePlaybackRate()| - | Decrease playback speed by 0.25x |
| setLoop(loop) | loop: boolean| Enable or disable audio looping |
| enableLoop() | - | Enable audio looping |
| disableLoop() | - | Disable audio looping |
| toggleLoop() | - | Toggle loop state |
Contributing
We welcome contributions! Please feel free to submit issues and pull requests.
License
MIT License - see LICENSE file for details.
Support
- 📧 Email: [email protected]
- 🐛 Issues: GitHub Issues
- 💬 Discussions: GitHub Discussions
Made with ❤️ by Joldibaev Nurlan
