fix: disable play when loading track and buffering event

This commit is contained in:
Kingkor Roy Tirtho 2023-04-30 18:08:12 +06:00
parent 8f9303bc0f
commit 30c933cdf3
2 changed files with 38 additions and 9 deletions

View File

@ -45,6 +45,7 @@ class PlayerControls extends HookConsumerWidget {
final playlistNotifier = ref.watch(PlaylistQueueNotifier.notifier); final playlistNotifier = ref.watch(PlaylistQueueNotifier.notifier);
final playing = useStream(PlaylistQueueNotifier.playing).data ?? final playing = useStream(PlaylistQueueNotifier.playing).data ??
PlaylistQueueNotifier.isPlaying; PlaylistQueueNotifier.isPlaying;
final buffering = useStream(playlistNotifier.buffering).data ?? true;
final theme = Theme.of(context); final theme = Theme.of(context);
final isDominantColorDark = ThemeData.estimateBrightnessForColor( final isDominantColorDark = ThemeData.estimateBrightnessForColor(
@ -140,7 +141,7 @@ class PlayerControls extends HookConsumerWidget {
// there's an edge case for value being bigger // there's an edge case for value being bigger
// than total duration. Keeping it resolved // than total duration. Keeping it resolved
value: progress.value.toDouble(), value: progress.value.toDouble(),
onChanged: playlist?.isLoading == true onChanged: playlist?.isLoading == true || buffering
? null ? null
: (v) { : (v) {
progress.value = v; progress.value = v;
@ -188,7 +189,7 @@ class PlayerControls extends HookConsumerWidget {
style: playlist?.isShuffled == true style: playlist?.isShuffled == true
? activeButtonStyle ? activeButtonStyle
: buttonStyle, : buttonStyle,
onPressed: playlist == null onPressed: playlist == null || playlist.isLoading
? null ? null
: () { : () {
if (playlist.isShuffled == true) { if (playlist.isShuffled == true) {
@ -221,7 +222,9 @@ class PlayerControls extends HookConsumerWidget {
playing ? SpotubeIcons.pause : SpotubeIcons.play, playing ? SpotubeIcons.pause : SpotubeIcons.play,
), ),
style: resumePauseStyle, style: resumePauseStyle,
onPressed: Actions.handler<PlayPauseIntent>( onPressed: playlist?.isLoading == true
? null
: Actions.handler<PlayPauseIntent>(
context, context,
PlayPauseIntent(ref), PlayPauseIntent(ref),
), ),

View File

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:audioplayers/audioplayers.dart'; import 'package:audioplayers/audioplayers.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
@ -138,6 +140,8 @@ class PlaylistQueueNotifier extends PersistedStateNotifier<PlaylistQueue?> {
late AudioServices audioServices; late AudioServices audioServices;
final StreamController<bool> _bufferingController;
static final provider = static final provider =
StateNotifierProvider<PlaylistQueueNotifier, PlaylistQueue?>( StateNotifierProvider<PlaylistQueueNotifier, PlaylistQueue?>(
(ref) => PlaylistQueueNotifier._(ref), (ref) => PlaylistQueueNotifier._(ref),
@ -145,7 +149,9 @@ class PlaylistQueueNotifier extends PersistedStateNotifier<PlaylistQueue?> {
static final notifier = provider.notifier; static final notifier = provider.notifier;
PlaylistQueueNotifier._(this.ref) : super(null, "playlist") { PlaylistQueueNotifier._(this.ref)
: _bufferingController = StreamController.broadcast(),
super(null, "playlist") {
configure(); configure();
} }
@ -166,6 +172,7 @@ class PlaylistQueueNotifier extends PersistedStateNotifier<PlaylistQueue?> {
audioPlayer.onPositionChanged.listen((pos) async { audioPlayer.onPositionChanged.listen((pos) async {
if (!isLoaded) return; if (!isLoaded) return;
_bufferingController.add(false);
final currentDuration = await audioPlayer.getDuration() ?? Duration.zero; final currentDuration = await audioPlayer.getDuration() ?? Duration.zero;
// skip all the activeTrack.skipSegments // skip all the activeTrack.skipSegments
@ -178,7 +185,8 @@ class PlaylistQueueNotifier extends PersistedStateNotifier<PlaylistQueue?> {
in (state!.activeTrack as SpotubeTrack).skipSegments) { in (state!.activeTrack as SpotubeTrack).skipSegments) {
if ((pos.inSeconds >= segment["start"]! && if ((pos.inSeconds >= segment["start"]! &&
pos.inSeconds < segment["end"]!)) { pos.inSeconds < segment["end"]!)) {
await audioPlayer.seek(Duration(seconds: segment["end"]!)); await audioPlayer.pause();
await seek(Duration(seconds: segment["end"]!));
} }
} }
} }
@ -199,6 +207,10 @@ class PlaylistQueueNotifier extends PersistedStateNotifier<PlaylistQueue?> {
isPreSearching = false; isPreSearching = false;
} }
}); });
audioPlayer.onSeekComplete.listen((event) {
_bufferingController.add(false);
});
} }
// properties // properties
@ -210,6 +222,18 @@ class PlaylistQueueNotifier extends PersistedStateNotifier<PlaylistQueue?> {
bool get isLoaded => state != null; bool get isLoaded => state != null;
Stream<bool> get buffering =>
_bufferingController.stream.asyncMap((bufferEvent) async {
final duration = await audioPlayer.getDuration();
final position = await audioPlayer.getCurrentPosition();
final isBuffering = state?.activeTrack is! SpotubeTrack &&
audioPlayer.state == PlayerState.playing &&
(bufferEvent || (duration == null && position == null));
return isBuffering;
});
Future<bool> get isBuffering => buffering.first;
// redirectors // redirectors
static bool get isPlaying => audioPlayer.state == PlayerState.playing; static bool get isPlaying => audioPlayer.state == PlayerState.playing;
static bool get isPaused => audioPlayer.state == PlayerState.paused; static bool get isPaused => audioPlayer.state == PlayerState.paused;
@ -336,6 +360,7 @@ class PlaylistQueueNotifier extends PersistedStateNotifier<PlaylistQueue?> {
Future<void> play() async { Future<void> play() async {
if (!isLoaded) return; if (!isLoaded) return;
_bufferingController.add(true);
await pause(); await pause();
await audioServices.addTrack(state!.activeTrack); await audioServices.addTrack(state!.activeTrack);
if (state!.activeTrack is LocalTrack) { if (state!.activeTrack is LocalTrack) {
@ -362,7 +387,7 @@ class PlaylistQueueNotifier extends PersistedStateNotifier<PlaylistQueue?> {
); );
} }
audioServices.addTrack(state!.activeTrack); await audioServices.addTrack(state!.activeTrack);
final cached = final cached =
await DefaultCacheManager().getFileFromCache(state!.activeTrack.id!); await DefaultCacheManager().getFileFromCache(state!.activeTrack.id!);
@ -450,6 +475,7 @@ class PlaylistQueueNotifier extends PersistedStateNotifier<PlaylistQueue?> {
Future<void> seek(Duration position) async { Future<void> seek(Duration position) async {
if (!isLoaded) return; if (!isLoaded) return;
_bufferingController.add(true);
await audioPlayer.seek(position); await audioPlayer.seek(position);
await resume(); await resume();
} }