Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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
13 changes: 10 additions & 3 deletions example/lib/chat_bubble.dart
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,18 @@ class _WaveBubbleState extends State<WaveBubble> {
if (widget.index == null && widget.path == null && file?.path == null) {
return;
}
late final WaveformExtractionType waveformExtractionType;
if (widget.index != null) {
waveformExtractionType = widget.index!.isEven
? WaveformExtractionType.extractAsync
: WaveformExtractionType.noExtraction;
} else {
waveformExtractionType = WaveformExtractionType.extractAsync;
}
// Prepare player with extracting waveform if index is even.
controller.preparePlayer(
path: widget.path ?? file!.path,
shouldExtractWaveform: widget.index?.isEven ?? true,
);
path: widget.path ?? file!.path,
waveformExtractionType: waveformExtractionType);
// Extracting waveform separately if index is odd.
if (widget.index?.isOdd ?? false) {
controller.waveformExtraction
Expand Down
1 change: 1 addition & 0 deletions lib/audio_waveforms.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ export 'src/controllers/recorder_controller.dart';
export 'src/models/android_encoder_settings.dart';
export 'src/models/ios_encoder_setting.dart';
export 'src/models/recorder_settings.dart';
export 'src/enums/waveform_extraction_type.dart';
87 changes: 74 additions & 13 deletions lib/src/audio_file_waveforms.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ class AudioFileWaveforms extends StatefulWidget {
/// If decoration is used then use color in it.
final Color? backgroundColor;

/// Duration for animation. Defaults to 500 milliseconds.
/// Duration for animation. If set to Duration.zero, no animation will occur.
/// Defaults to 500 milliseconds.
final Duration animationDuration;

/// Curve for animation. Defaults to Curves.easeIn
Expand Down Expand Up @@ -144,18 +145,26 @@ class _AudioFileWaveformsState extends State<AudioFileWaveforms>
void initState() {
super.initState();
_initialiseVariables();
_growingWaveController = AnimationController(
vsync: this,
duration: widget.animationDuration,
);
_growAnimation = CurvedAnimation(
parent: _growingWaveController,
curve: widget.animationCurve,
);

_growingWaveController
..forward()
..addListener(_updateGrowAnimationProgress);
if (widget.animationDuration == Duration.zero) {
_growAnimationProgress = 1.0;
} else {
_growingWaveController = AnimationController(
vsync: this,
duration: widget.animationDuration,
);
_growAnimation = CurvedAnimation(
parent: _growingWaveController,
curve: widget.animationCurve,
);

_growingWaveController
..forward()
..addListener(_updateGrowAnimationProgress);
}

_initializeAudioProgress();

onCurrentDurationSubscription =
playerController.onCurrentDurationChanged.listen((event) {
_seekProgress.value = event;
Expand Down Expand Up @@ -188,10 +197,50 @@ class _AudioFileWaveformsState extends State<AudioFileWaveforms>
onCurrentExtractedWaveformData?.cancel();
onCompletionSubscription.cancel();
playerController.removeListener(_addWaveformDataFromController);
_growingWaveController.dispose();

if (widget.animationDuration != Duration.zero) {
_growingWaveController.dispose();
}
Comment on lines +201 to +203
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please explain why you're only disposing when animation duration isn't zero?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because the controller is not instantiated over the duration is set to zero


super.dispose();
}

@override
void didUpdateWidget(AudioFileWaveforms oldWidget) {
super.didUpdateWidget(oldWidget);

// Vérifier si les waveformData ont changé
if (widget.waveformData != oldWidget.waveformData) {
if (widget.waveformData.isNotEmpty) {
_addWaveformData(widget.waveformData);
}
}

// Vérifier si d'autres propriétés importantes ont changé
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add comment in english

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I forgot.

if (widget.playerWaveStyle != oldWidget.playerWaveStyle ||
widget.size != oldWidget.size ||
widget.waveformType != oldWidget.waveformType) {
if (mounted) setState(() {});
}

// Mettre à jour les variables si nécessaire
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here as well, add comment in english

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I forgot.

if (widget.margin != oldWidget.margin ||
widget.padding != oldWidget.padding ||
widget.decoration != oldWidget.decoration ||
widget.backgroundColor != oldWidget.backgroundColor ||
widget.animationDuration != oldWidget.animationDuration ||
widget.animationCurve != oldWidget.animationCurve ||
widget.clipBehavior != oldWidget.clipBehavior) {
margin = widget.margin;
padding = widget.padding;
decoration = widget.decoration;
backgroundColor = widget.backgroundColor;
animationDuration = widget.animationDuration;
animationCurve = widget.animationCurve;
clipBehavior = widget.clipBehavior;
}
}

double _audioProgress = 0.0;
double _cachedAudioProgress = 0.0;

Expand Down Expand Up @@ -406,4 +455,16 @@ class _AudioFileWaveformsState extends State<AudioFileWaveforms>
}
});
}

Future<void> _initializeAudioProgress() async {
if (playerController.playerState == PlayerState.paused &&
playerController.maxDuration > 0) {
final currentPosition =
await playerController.getDuration(DurationType.current);
if (currentPosition > 0) {
_seekProgress.value = currentPosition;
_updatePlayerPercent();
}
}
}
}
21 changes: 10 additions & 11 deletions lib/src/controllers/player_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ class PlayerController extends ChangeNotifier {
Future<void> preparePlayer({
required String path,
double? volume,
bool shouldExtractWaveform = true,
WaveformExtractionType waveformExtractionType =
WaveformExtractionType.noExtraction,
int noOfSamples = 100,
}) async {
path = Uri.parse(path).path;
Expand All @@ -143,20 +144,18 @@ class PlayerController extends ChangeNotifier {
_setPlayerState(PlayerState.initialized);
}

if (shouldExtractWaveform) {
waveformExtraction
.extractWaveformData(
if (waveformExtractionType != WaveformExtractionType.noExtraction) {
var extraction = waveformExtraction.extractWaveformData(
path: path,
noOfSamples: noOfSamples,
)
.then(
(value) {
)..then((values) {
waveformExtraction.waveformData
..clear()
..addAll(value);
notifyListeners();
},
);
..addAll(values);
});
if (waveformExtractionType == WaveformExtractionType.extractSync) {
await extraction;
}
Comment on lines +147 to +158
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add some comment above this to explain the logic here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've changed the verifiable shouldExtractWaveform to enum, to allow for different cases. Don't extract waveforms, extract but don't wait for extraction to finish and finally extract and wait for extraction to finish.

}
notifyListeners();
}
Expand Down
2 changes: 1 addition & 1 deletion lib/src/controllers/waveform_extraction_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class WaveformExtractionController {

/// This returns waveform data which can be used by [AudioFileWaveforms]
/// to display waveforms.
List<double> get waveformData => _waveformData.toList();
List<double> get waveformData => _waveformData;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't want to allow users to modify the list but if you had any reason to remove it then can please mention it here

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've changed it because this part of the code you've written isn't working properly any more.
if (shouldExtractWaveform) { waveformExtraction .extractWaveformData( path: path, noOfSamples: noOfSamples, ) .then( (value) { waveformExtraction.waveformData ..clear() ..addAll(value); notifyListeners(); }, ); }
Since you return a newly created list every time you call waveformData, what you do in the PlayerController cannot work and be made persistent.


/// A stream to get current extracted waveform data. This stream will emit
/// list of doubles which are waveform data point.
Expand Down
10 changes: 10 additions & 0 deletions lib/src/enums/waveform_extraction_type.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
enum WaveformExtractionType {
/// No waveform extraction will be performed.
noExtraction,

/// Extract waveform data asynchronously without waiting for the result.
extractAsync,

/// Extract waveform data and wait until it's completed before continuing.
extractSync,
}