diff --git a/lib/features/player/core/audiobook_player.dart b/lib/features/player/core/audiobook_player.dart index d06ef11..043bc5b 100644 --- a/lib/features/player/core/audiobook_player.dart +++ b/lib/features/player/core/audiobook_player.dart @@ -204,6 +204,22 @@ class AudiobookPlayer extends AudioPlayer { }); } + /// a convenience getter for slow position stream + Stream get slowPositionStream { + final superPositionStream = createPositionStream( + steps: 100, + minPeriod: const Duration(milliseconds: 500), + maxPeriod: const Duration(seconds: 1), + ); + // now we need to map the position to the book instead of the current track + return superPositionStream.map((position) { + if (_book == null) { + return Duration.zero; + } + return position + _book!.tracks[sequenceState!.currentIndex].startOffset; + }); + } + /// get current chapter BookChapter? get currentChapter { if (_book == null) { diff --git a/lib/features/player/providers/currently_playing_provider.dart b/lib/features/player/providers/currently_playing_provider.dart index 607b823..d8329f0 100644 --- a/lib/features/player/providers/currently_playing_provider.dart +++ b/lib/features/player/providers/currently_playing_provider.dart @@ -14,7 +14,7 @@ BookExpanded? currentlyPlayingBook(CurrentlyPlayingBookRef ref) { @riverpod BookChapter? currentPlayingChapter(CurrentPlayingChapterRef ref) { final player = ref.watch(audiobookPlayerProvider); - player.positionStream.listen((_) { + player.slowPositionStream.listen((_) { ref.invalidateSelf(); }); diff --git a/lib/features/player/providers/currently_playing_provider.g.dart b/lib/features/player/providers/currently_playing_provider.g.dart index afcbb8c..617a6f5 100644 --- a/lib/features/player/providers/currently_playing_provider.g.dart +++ b/lib/features/player/providers/currently_playing_provider.g.dart @@ -24,7 +24,7 @@ final currentlyPlayingBookProvider = typedef CurrentlyPlayingBookRef = AutoDisposeProviderRef; String _$currentPlayingChapterHash() => - r'91ca01ee93e0d556c77237ceebb3f9281d2d2b3f'; + r'a084da724e3d8bb1b1475e867ab3200d7d61d827'; /// provided the current chapter of the book being played /// diff --git a/lib/features/player/view/audiobook_player.dart b/lib/features/player/view/audiobook_player.dart index 4b3bcb7..d4bf1f5 100644 --- a/lib/features/player/view/audiobook_player.dart +++ b/lib/features/player/view/audiobook_player.dart @@ -56,9 +56,6 @@ class AudiobookPlayer extends HookConsumerWidget { } }); - const progressBar = AudiobookTotalProgressBar(); - const chapterProgressBar = AudiobookChapterProgressBar(); - // theme from image final imageTheme = ref.watch( themeOfLibraryItemProvider( @@ -189,78 +186,6 @@ class AudiobookPlayerPlayPauseButton extends HookConsumerWidget { } } -/// A progress bar that shows the total progress of the audiobook -/// -/// for chapter progress, use [AudiobookChapterProgressBar] -class AudiobookTotalProgressBar extends HookConsumerWidget { - const AudiobookTotalProgressBar({ - super.key, - this.barHeight = 5.0, - this.barCapShape = BarCapShape.round, - this.thumbRadius = 10.0, - this.thumbGlowRadius = 30.0, - this.thumbCanPaintOutsideBar = true, - this.timeLabelLocation, - this.timeLabelType, - this.timeLabelTextStyle, - this.timeLabelPadding = 0.0, - }); - - final double barHeight; - final BarCapShape barCapShape; - final double thumbRadius; - final double thumbGlowRadius; - final bool thumbCanPaintOutsideBar; - final TimeLabelLocation? timeLabelLocation; - final TimeLabelType? timeLabelType; - final TextStyle? timeLabelTextStyle; - final double timeLabelPadding; - - @override - Widget build(BuildContext context, WidgetRef ref) { - final player = ref.watch(audiobookPlayerProvider); - final position = useStream( - player.positionStream, - initialData: const Duration(seconds: 0), - ); - final buffered = useStream( - player.bufferedPositionStream, - initialData: const Duration(seconds: 0), - ); - final currentIndex = useStream( - player.currentIndexStream, - initialData: 0, - ); - var durationOfPreviousTracks = - player.book?.tracks.sublist(0, currentIndex.data).fold( - const Duration(seconds: 0), - (previousValue, element) => previousValue + element.duration, - ) ?? - const Duration(seconds: 0); - final totalProgress = durationOfPreviousTracks + - (position.data ?? const Duration(seconds: 0)); - final totalBuffered = durationOfPreviousTracks + - (buffered.data ?? const Duration(seconds: 0)); - - return ProgressBar( - progress: totalProgress, - total: player.book?.duration ?? const Duration(seconds: 0), - onSeek: player.seek, - buffered: totalBuffered, - bufferedBarColor: Theme.of(context).colorScheme.secondary, - thumbRadius: thumbRadius, - thumbGlowRadius: thumbGlowRadius, - thumbCanPaintOutsideBar: thumbCanPaintOutsideBar, - barHeight: barHeight, - barCapShape: barCapShape, - timeLabelLocation: timeLabelLocation, - timeLabelType: timeLabelType, - timeLabelTextStyle: timeLabelTextStyle, - timeLabelPadding: timeLabelPadding, - ); - } -} - class AudiobookChapterProgressBar extends HookConsumerWidget { const AudiobookChapterProgressBar({ super.key, @@ -281,13 +206,11 @@ class AudiobookChapterProgressBar extends HookConsumerWidget { // now find the chapter that corresponds to the current time // and calculate the progress of the current chapter - final currentChapterProgress = - currentChapter == null + final currentChapterProgress = currentChapter == null ? null : (player.positionInBook - currentChapter.start); - final currentChapterBuffered = - currentChapter == null + final currentChapterBuffered = currentChapter == null ? null : (player.bufferedPositionInBook - currentChapter.start); diff --git a/lib/features/player/view/player_when_expanded.dart b/lib/features/player/view/player_when_expanded.dart index 1719bce..dfa0d12 100644 --- a/lib/features/player/view/player_when_expanded.dart +++ b/lib/features/player/view/player_when_expanded.dart @@ -279,9 +279,9 @@ class AudiobookPlayerSeekButton extends HookConsumerWidget { ), onPressed: () { if (isForward) { - player.seek(player.position + const Duration(seconds: 30)); + player.seek(player.positionInBook + const Duration(seconds: 30)); } else { - player.seek(player.position - const Duration(seconds: 30)); + player.seek(player.positionInBook - const Duration(seconds: 30)); } }, ); @@ -318,7 +318,7 @@ class AudiobookPlayerSeekChapterButton extends HookConsumerWidget { player.seek( player.book!.chapters[index + 1].start + const Duration( - microseconds: 50, + milliseconds: 10, ), // add a small offset so the display does not show the previous chapter for a split second ); } else { @@ -327,18 +327,18 @@ class AudiobookPlayerSeekChapterButton extends HookConsumerWidget { } else { // if player position is less than 5 seconds into the chapter, go to the previous chapter final chapterPosition = - player.position - player.currentChapter!.start; + player.positionInBook - player.currentChapter!.start; if (chapterPosition < const Duration(seconds: 5)) { final index = player.book!.chapters.indexOf(player.currentChapter!); if (index > 0) { player.seek( player.book!.chapters[index - 1].start + - const Duration(microseconds: 50), + const Duration(milliseconds: 10), ); } } else { player.seek( - player.currentChapter!.start + const Duration(microseconds: 50), + player.currentChapter!.start + const Duration(milliseconds: 10), ); } } diff --git a/lib/features/player/view/player_when_minimized.dart b/lib/features/player/view/player_when_minimized.dart index a18462c..d82c9c7 100644 --- a/lib/features/player/view/player_when_minimized.dart +++ b/lib/features/player/view/player_when_minimized.dart @@ -33,7 +33,7 @@ class PlayerWhenMinimized extends HookConsumerWidget { final player = ref.watch(audiobookPlayerProvider); final vanishingPercentage = 1 - percentageMiniplayer; final progress = - useStream(player.positionStream, initialData: Duration.zero); + useStream(player.slowPositionStream, initialData: Duration.zero); final bookMetaExpanded = ref.watch(currentBookMetadataProvider);