A self-contained Flutter package for displaying interactive audio waveform visualizations with built-in playback controls. Just provide a URL โ it handles everything.
| Feature | Description |
|---|---|
| ๐ต Auto-download & cache | Provide a network URL โ downloading and local caching is handled automatically. |
| ๐ Real waveform extraction | Powered by FFmpeg โ extracts actual audio amplitudes, not random placeholder bars. |
| ๐จ Fully customisable | Colors, bar width, bar cap shape, spacing, seek indicator, and more via WaveformStyle. |
| ๐ Seek gestures | Tap or drag anywhere on the waveform to seek. Haptic feedback included. |
Built-in button, or bring your own via playButtonBuilder, or disable it entirely. |
|
| โฑ๏ธ Time labels | Optional position / duration labels beside the waveform. |
| ๐ External controls | Use showPlayButton: false and control playback from your own buttons anywhere. |
| ๐พ Smart caching | Downloaded files and extracted waveforms are cached in memory and on disk. |
dependencies:
flutter_waveform_player: ^0.1.0This package uses FFmpeg (via ffmpeg_kit_flutter_new) for waveform extraction. You may need to set a minimum iOS deployment target of 16.0 or higher.
iOS โ In your ios/Podfile:
platform :ios, '16.0'Android โ In your android/app/build.gradle:
android {
defaultConfig {
minSdkVersion 24
}
}import 'package:flutter_waveform_player/flutter_waveform_player.dart';// 1. Create a controller
final controller = WaveformController(bars: 80);
// 2. Add the widget
WaveformPlayer(controller: controller);
// 3. Load audio (downloads, extracts waveform, and plays)
controller.load('https://example.com/audio.mp3');// Load waveform and prepare audio, but don't start playback.
// The user can tap the play button when ready.
controller.load('https://example.com/audio.mp3', autoPlay: false);WaveformPlayer(
controller: controller,
height: 64,
style: const WaveformStyle(
baseColor: Color(0xFF3D2E5C),
highlightColor: Color(0xFFBB86FC),
seekIndicatorColor: Color(0xFFBB86FC),
barWidth: 3.0,
barCap: BarCap.square,
barSpacing: 2.0,
seekIndicatorRadius: 6.0,
),
)WaveformPlayer(
controller: controller,
playButtonBuilder: (context, isPlaying) {
return Container(
width: 36,
height: 36,
decoration: BoxDecoration(
color: Colors.deepPurple,
borderRadius: BorderRadius.circular(10),
),
child: Icon(
isPlaying ? Icons.pause : Icons.play_arrow,
color: Colors.white,
),
);
},
)Disable the built-in button and control playback from anywhere:
// Waveform โ no play button
WaveformPlayer(
controller: controller,
showPlayButton: false,
showTimeLabels: false,
),
// Your own button โ placed anywhere in the widget tree
ElevatedButton(
onPressed: controller.togglePlayPause,
child: Text(controller.isPlaying ? 'Pause' : 'Play'),
),controller.load('/path/to/local/audio.mp3', isLocal: true);| Property | Type | Default | Description |
|---|---|---|---|
controller |
WaveformController |
required | The controller managing audio + waveform state. |
style |
WaveformStyle |
WaveformStyle() |
Visual configuration for bars, colors, and seek indicator. |
height |
double |
40.0 |
Height of the waveform visualization. |
showPlayButton |
bool |
true |
Whether to show the built-in play/pause button. |
showTimeLabels |
bool |
true |
Whether to show position / duration labels. |
showSeekIndicator |
bool |
true |
Whether to show the seek line + dot during drag. |
enableHapticFeedback |
bool |
true |
Whether to trigger haptic feedback on seek gestures. |
playButtonBuilder |
Widget Function(BuildContext, bool)? |
null |
Custom builder for the play/pause button. |
timeLabelStyle |
TextStyle? |
null |
Custom text style for the time labels. |
loadingPlaceholder |
Widget? |
null |
Widget shown while the waveform is loading. |
padding |
EdgeInsetsGeometry? |
null |
Padding around the entire player. |
decoration |
BoxDecoration? |
null |
Decoration for the player container. |
onSeekEnd |
ValueChanged<double>? |
null |
Callback when seek ends (receives progress 0.0โ1.0). |
| Property | Type | Default | Description |
|---|---|---|---|
baseColor |
Color |
Color(0xFFBDBDBD) |
Color of unplayed bars. |
highlightColor |
Color |
Color(0xFF2196F3) |
Color of played bars. |
seekIndicatorColor |
Color |
Color(0xFF2196F3) |
Color of the seek indicator line + dot. |
barWidth |
double |
2.0 |
Width of each bar in logical pixels. |
barSpacing |
double |
1.5 |
Spacing between bars. |
minBarHeight |
double |
2.0 |
Minimum height of a bar. |
barCap |
BarCap |
BarCap.round |
Shape of bar ends (round or square). |
seekIndicatorRadius |
double |
4.0 |
Radius of the seek indicator dot. |
seekIndicatorWidth |
double |
1.5 |
Width of the seek indicator line. |
| Method / Property | Description |
|---|---|
load(url, {isLocal, autoPlay}) |
Load audio from a URL. Downloads, extracts waveform, and optionally plays. |
togglePlayPause() |
Toggle between play and pause. |
play() / pause() / stop() |
Direct playback controls. |
seekTo(Duration) |
Seek to a specific position. |
seekToProgress(double) |
Seek to a progress value (0.0โ1.0). |
reset() |
Stop playback and clear all state. |
isPlaying |
Whether audio is currently playing. |
isLoading |
Whether audio is loading/buffering. |
position |
Current playback position (Duration). |
duration |
Total audio duration (Duration). |
playbackProgress |
Current progress (0.0โ1.0). |
playbackStatus |
Current AudioPlaybackStatus enum value. |
waveform |
The extracted amplitude data (List<double>). |
error |
Last error message, or null. |
The bars parameter on WaveformController determines how many vertical bars appear in the waveform:
WaveformController(bars: 50) // 50 bars โ balanced
WaveformController(bars: 80) // 80 bars โ more detail
WaveformController(bars: 120) // 120 bars โ very detailedInternally:
- The audio is converted to raw PCM (mono, 16-bit) via FFmpeg.
- The samples are divided into
barsequal segments. - The peak amplitude of each segment becomes one bar (normalized 0.0โ1.0).
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ WaveformPlayer (Widget) โ
โ โข Renders waveform bars via WaveformPainter โ
โ โข Handles tap/drag seek gestures โ
โ โข Shows play button + time labels โ
โโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ listens to
โโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ WaveformController (ChangeNotifier) โ
โ โข Public API: load, play, pause, seek โ
โ โข Exposes: position, duration, waveform, status โ
โโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ delegates to
โโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ WaveformAudioService (Internal) โ
โ โข Downloads & caches audio files (Dio) โ
โ โข Extracts waveform amplitudes (FFmpeg) โ
โ โข Manages playback (just_audio) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
| Platform | Minimum Version |
|---|---|
| iOS | 16.0+ |
| Android | API 24+ (Android 7.0) |
| Flutter | 3.0+ |
| Dart | 3.10+ |
MIT License โ see LICENSE for details.
Contributions are welcome! Please feel free to submit a Pull Request or open an Issue.