fix: duration is always zero in PlayerView

This commit is contained in:
Kingkor Roy Tirtho 2023-08-02 11:12:22 +06:00
parent 6dff0996bd
commit 4885dca04f

View File

@ -1,3 +1,4 @@
import 'package:async/async.dart';
import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:spotube/services/audio_player/audio_player.dart'; import 'package:spotube/services/audio_player/audio_player.dart';
@ -11,47 +12,60 @@ import 'package:spotube/services/audio_player/audio_player.dart';
final bufferProgress = final bufferProgress =
useStream(audioPlayer.bufferedPositionStream).data?.inSeconds ?? 0; useStream(audioPlayer.bufferedPositionStream).data?.inSeconds ?? 0;
Duration audioPlayerDuration = Duration.zero; final duration = useState(Duration.zero);
Duration audioPlayerPosition = Duration.zero; final position = useState(Duration.zero);
// Duration future is needed for getting the duration of the song final sliderMax = duration.value.inSeconds;
// as stream can be null when no event occurs (Mostly needed for android)
audioPlayer.duration.then((value) {
if (value != null) {
audioPlayerDuration = value;
}
});
audioPlayer.position.then((value) {
if (value != null) {
audioPlayerPosition = value;
}
});
final position = useState<Duration>(audioPlayerPosition);
final duration =
useStream(audioPlayer.durationStream).data ?? audioPlayerDuration;
final sliderMax = duration.inSeconds;
final sliderValue = position.value.inSeconds; final sliderValue = position.value.inSeconds;
useEffect(() { useEffect(() {
final durationOperation =
CancelableOperation.fromFuture(audioPlayer.duration);
durationOperation.then((value) {
if (value != null) {
duration.value = value;
}
});
final durationSubscription = audioPlayer.durationStream.listen((event) {
duration.value = event;
});
final positionOperation =
CancelableOperation.fromFuture(audioPlayer.position);
positionOperation.then((value) {
if (value != null) {
position.value = value;
}
});
// audioPlayer.positionStream is fired every 200ms and only 1s delay is // audioPlayer.positionStream is fired every 200ms and only 1s delay is
// enough. Thus only update the position if the difference is more than 1s // enough. Thus only update the position if the difference is more than 1s
// Reduces CPU usage // Reduces CPU usage
var lastPosition = position.value; var lastPosition = position.value;
return audioPlayer.positionStream.listen((event) {
final positionSubscription = audioPlayer.positionStream.listen((event) {
if (event.inMilliseconds > 1000 && if (event.inMilliseconds > 1000 &&
event.inMilliseconds - lastPosition.inMilliseconds < 1000) return; event.inMilliseconds - lastPosition.inMilliseconds < 1000) return;
lastPosition = event; lastPosition = event;
position.value = event; position.value = event;
}).cancel; });
}, [audioPlayerPosition, audioPlayerDuration]);
return () {
positionOperation.cancel();
positionSubscription.cancel();
durationOperation.cancel();
durationSubscription.cancel();
};
}, []);
return ( return (
progressStatic: progressStatic:
sliderMax == 0 || sliderValue > sliderMax ? 0 : sliderValue / sliderMax, sliderMax == 0 || sliderValue > sliderMax ? 0 : sliderValue / sliderMax,
position: position.value, position: position.value,
duration: duration, duration: duration.value,
bufferProgress: sliderMax == 0 || bufferProgress > sliderMax bufferProgress: sliderMax == 0 || bufferProgress > sliderMax
? 0 ? 0
: bufferProgress / sliderMax, : bufferProgress / sliderMax,