UNPKG

ngx-audio-wave

Version:

A modern, accessible audio wave visualization component for Angular 20+ with comprehensive keyboard navigation and screen reader support.

291 lines (224 loc) â€ĸ 11.9 kB
# 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](https://joldibaev.github.io/ngx-audio-wave/)** - Try the interactive demo ![Audio Wave Demo](https://github.com/joldibaev/ngx-audio-wave/raw/master/public/demo3.png) ## Quick Start ### Installation ```bash npm install ngx-audio-wave ``` ### Angular 20+ (Standalone Components) ```ts 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 ```html <ngx-audio-wave ariaLabel="My podcast episode" audioSrc="https://example.com/audio.mp3" > </ngx-audio-wave> ``` ### With Progress Information ```html <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 deprecated `currentTime`, `duration`, and `playedPercent` for better precision. ## Examples ### Custom Styling ```html <ngx-audio-wave [gap]="3" [height]="50" [rounded]="false" audioSrc="assets/audio.mp3" color="#ff6b6b" > </ngx-audio-wave> ``` ### With Custom Accessibility Labels ```html <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 ```html <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 ```html <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 ```html <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 ```html <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 ```html <!-- 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](LICENSE) file for details. ## Support - 📧 Email: nurlan@joldibaev.uz - 🐛 Issues: [GitHub Issues](https://github.com/joldibaev/ngx-audio-wave/issues) - đŸ’Ŧ Discussions: [GitHub Discussions](https://github.com/joldibaev/ngx-audio-wave/discussions) --- **Made with â¤ī¸ by [Joldibaev Nurlan](https://github.com/joldibaev)**