Skip to content

Commit

Permalink
fix: disable play when loading track and buffering event
Browse files Browse the repository at this point in the history
  • Loading branch information
Kingkor Roy Tirtho committed Apr 30, 2023
1 parent 8f9303b commit 30c933c
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 9 deletions.
15 changes: 9 additions & 6 deletions lib/components/player/player_controls.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class PlayerControls extends HookConsumerWidget {
final playlistNotifier = ref.watch(PlaylistQueueNotifier.notifier);
final playing = useStream(PlaylistQueueNotifier.playing).data ??
PlaylistQueueNotifier.isPlaying;
final buffering = useStream(playlistNotifier.buffering).data ?? true;
final theme = Theme.of(context);

final isDominantColorDark = ThemeData.estimateBrightnessForColor(
Expand Down Expand Up @@ -140,7 +141,7 @@ class PlayerControls extends HookConsumerWidget {
// there's an edge case for value being bigger
// than total duration. Keeping it resolved
value: progress.value.toDouble(),
onChanged: playlist?.isLoading == true
onChanged: playlist?.isLoading == true || buffering
? null
: (v) {
progress.value = v;
Expand Down Expand Up @@ -188,7 +189,7 @@ class PlayerControls extends HookConsumerWidget {
style: playlist?.isShuffled == true
? activeButtonStyle
: buttonStyle,
onPressed: playlist == null
onPressed: playlist == null || playlist.isLoading
? null
: () {
if (playlist.isShuffled == true) {
Expand Down Expand Up @@ -221,10 +222,12 @@ class PlayerControls extends HookConsumerWidget {
playing ? SpotubeIcons.pause : SpotubeIcons.play,
),
style: resumePauseStyle,
onPressed: Actions.handler<PlayPauseIntent>(
context,
PlayPauseIntent(ref),
),
onPressed: playlist?.isLoading == true
? null
: Actions.handler<PlayPauseIntent>(
context,
PlayPauseIntent(ref),
),
),
IconButton(
tooltip: context.l10n.next_track,
Expand Down
32 changes: 29 additions & 3 deletions lib/provider/playlist_queue_provider.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:async';

import 'package:audioplayers/audioplayers.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
Expand Down Expand Up @@ -138,14 +140,18 @@ class PlaylistQueueNotifier extends PersistedStateNotifier<PlaylistQueue?> {

late AudioServices audioServices;

final StreamController<bool> _bufferingController;

static final provider =
StateNotifierProvider<PlaylistQueueNotifier, PlaylistQueue?>(
(ref) => PlaylistQueueNotifier._(ref),
);

static final notifier = provider.notifier;

PlaylistQueueNotifier._(this.ref) : super(null, "playlist") {
PlaylistQueueNotifier._(this.ref)
: _bufferingController = StreamController.broadcast(),
super(null, "playlist") {
configure();
}

Expand All @@ -166,6 +172,7 @@ class PlaylistQueueNotifier extends PersistedStateNotifier<PlaylistQueue?> {

audioPlayer.onPositionChanged.listen((pos) async {
if (!isLoaded) return;
_bufferingController.add(false);
final currentDuration = await audioPlayer.getDuration() ?? Duration.zero;

// skip all the activeTrack.skipSegments
Expand All @@ -178,7 +185,8 @@ class PlaylistQueueNotifier extends PersistedStateNotifier<PlaylistQueue?> {
in (state!.activeTrack as SpotubeTrack).skipSegments) {
if ((pos.inSeconds >= segment["start"]! &&
pos.inSeconds < segment["end"]!)) {
await audioPlayer.seek(Duration(seconds: segment["end"]!));
await audioPlayer.pause();
await seek(Duration(seconds: segment["end"]!));
}
}
}
Expand All @@ -199,6 +207,10 @@ class PlaylistQueueNotifier extends PersistedStateNotifier<PlaylistQueue?> {
isPreSearching = false;
}
});

audioPlayer.onSeekComplete.listen((event) {
_bufferingController.add(false);
});
}

// properties
Expand All @@ -210,6 +222,18 @@ class PlaylistQueueNotifier extends PersistedStateNotifier<PlaylistQueue?> {

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
static bool get isPlaying => audioPlayer.state == PlayerState.playing;
static bool get isPaused => audioPlayer.state == PlayerState.paused;
Expand Down Expand Up @@ -336,6 +360,7 @@ class PlaylistQueueNotifier extends PersistedStateNotifier<PlaylistQueue?> {

Future<void> play() async {
if (!isLoaded) return;
_bufferingController.add(true);
await pause();
await audioServices.addTrack(state!.activeTrack);
if (state!.activeTrack is LocalTrack) {
Expand All @@ -362,7 +387,7 @@ class PlaylistQueueNotifier extends PersistedStateNotifier<PlaylistQueue?> {
);
}

audioServices.addTrack(state!.activeTrack);
await audioServices.addTrack(state!.activeTrack);

final cached =
await DefaultCacheManager().getFileFromCache(state!.activeTrack.id!);
Expand Down Expand Up @@ -450,6 +475,7 @@ class PlaylistQueueNotifier extends PersistedStateNotifier<PlaylistQueue?> {

Future<void> seek(Duration position) async {
if (!isLoaded) return;
_bufferingController.add(true);
await audioPlayer.seek(position);
await resume();
}
Expand Down

0 comments on commit 30c933c

Please sign in to comment.