Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 68 additions & 40 deletions lib/src/ui/widgets/track/audio_visualizer_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,37 @@ import '../../../context/track_reference_context.dart';
import '../theme.dart';
import 'no_track_widget.dart';

class AudioVisualizerOptions {
final int count;
final double width;
final double minHeight;
final double maxHeight;
final int durationInMilliseconds;
final Color color;
final double spacing;
final double cornerRadius;
final double barMinOpacity;

const AudioVisualizerOptions({
this.count = 7,
this.width = 12,
this.minHeight = 12,
this.maxHeight = 100,
this.durationInMilliseconds = 500,
this.color = Colors.white,
this.spacing = 5,
this.cornerRadius = 9999,
this.barMinOpacity = 0.35,
});
}

class AudioVisualizerWidget extends StatelessWidget {
const AudioVisualizerWidget({Key? key}) : super(key: key);
final AudioVisualizerOptions options;

const AudioVisualizerWidget({
Key? key,
this.options = const AudioVisualizerOptions(),
}) : super(key: key);

@override
Widget build(BuildContext context) {
Expand All @@ -31,11 +60,7 @@ class AudioVisualizerWidget extends StatelessWidget {
child: Center(
child: SoundWaveformWidget(
audioTrack: audioTrack,
count: 7,
width: 12,
minHeight: 12,
maxHeight: 100,
durationInMilliseconds: 500,
options: options,
),
),
);
Expand All @@ -46,21 +71,15 @@ class AudioVisualizerWidget extends StatelessWidget {
}

class SoundWaveformWidget extends StatefulWidget {
final int count;
final double width;
final double minHeight;
final double maxHeight;
final int durationInMilliseconds;
final AudioVisualizerOptions options;
final AudioTrack? audioTrack;

const SoundWaveformWidget({
super.key,
this.audioTrack,
this.count = 7,
this.width = 5,
this.minHeight = 8,
this.maxHeight = 100,
this.durationInMilliseconds = 500,
this.options = const AudioVisualizerOptions(),
});
final AudioTrack? audioTrack;

@override
State<SoundWaveformWidget> createState() => _SoundWaveformWidgetState();
}
Expand Down Expand Up @@ -102,7 +121,7 @@ class _SoundWaveformWidgetState extends State<SoundWaveformWidget>
controller = AnimationController(
vsync: this,
duration: Duration(
milliseconds: widget.durationInMilliseconds,
milliseconds: widget.options.durationInMilliseconds,
))
..repeat();

Expand All @@ -118,35 +137,44 @@ class _SoundWaveformWidgetState extends State<SoundWaveformWidget>

@override
Widget build(BuildContext context) {
final count = widget.count;
final minHeight = widget.minHeight;
final maxHeight = widget.maxHeight;
final count = widget.options.count;
final minHeight = widget.options.minHeight;
final maxHeight = widget.options.maxHeight;
return AnimatedBuilder(
animation: controller,
builder: (c, child) {
//double t = controller.value;
//int current = (samples.length * t).floor();
return Row(
mainAxisSize: MainAxisSize.min,
children: List.generate(
count,
(i) => AnimatedContainer(
duration: Duration(
milliseconds: widget.durationInMilliseconds ~/ count),
margin: i == (samples.length - 1)
? EdgeInsets.zero
: const EdgeInsets.only(right: 5),
height: samples[i] < minHeight
? minHeight
: samples[i] > maxHeight
? maxHeight
: samples[i],
width: widget.width,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(9999),
),
),
(i) {
final heightPercent =
((samples[i] - minHeight) / (maxHeight - minHeight))
.clamp(0.0, 1.0);
final barOpacity =
(1.0 - widget.options.barMinOpacity) * heightPercent +
widget.options.barMinOpacity;

return AnimatedContainer(
duration: Duration(
milliseconds:
widget.options.durationInMilliseconds ~/ count),
margin: i == (samples.length - 1)
? EdgeInsets.zero
: EdgeInsets.only(right: widget.options.spacing),
height: samples[i] < minHeight
? minHeight
: samples[i] > maxHeight
? maxHeight
: samples[i],
width: widget.options.width,
decoration: BoxDecoration(
color: widget.options.color.withValues(alpha: barOpacity),
borderRadius:
BorderRadius.circular(widget.options.cornerRadius),
),
);
},
),
);
},
Expand Down