增加跳过片头片尾,上一章下一章移动到AudioPlayer对象中

This commit is contained in:
rang 2025-10-24 11:47:50 +08:00
parent e06c834d0e
commit 620a1eb7a2
29 changed files with 1080 additions and 179 deletions

View file

@ -17,42 +17,42 @@ class AudiobookPlayerSeekChapterButton extends HookConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final player = ref.watch(audiobookPlayerProvider);
// add a small offset so the display does not show the previous chapter for a split second
const offset = Duration(milliseconds: 10);
// // add a small offset so the display does not show the previous chapter for a split second
// const offset = Duration(milliseconds: 10);
/// time into the current chapter to determine if we should go to the previous chapter or the start of the current chapter
const doNotSeekBackIfLessThan = Duration(seconds: 5);
// /// time into the current chapter to determine if we should go to the previous chapter or the start of the current chapter
// const doNotSeekBackIfLessThan = Duration(seconds: 5);
/// seek forward to the next chapter
void seekForward() {
final index = player.book!.chapters.indexOf(player.currentChapter!);
if (index < player.book!.chapters.length - 1) {
player.seek(
player.book!.chapters[index + 1].start + offset,
);
} else {
player.seek(player.currentChapter!.end);
}
}
// /// seek forward to the next chapter
// void seekForward() {
// final index = player.book!.chapters.indexOf(player.currentChapter!);
// if (index < player.book!.chapters.length - 1) {
// player.seek(
// player.book!.chapters[index + 1].start + offset,
// );
// } else {
// player.seek(player.currentChapter!.end);
// }
// }
/// seek backward to the previous chapter or the start of the current chapter
void seekBackward() {
final currentPlayingChapterIndex =
player.book!.chapters.indexOf(player.currentChapter!);
final chapterPosition =
player.positionInBook - player.currentChapter!.start;
BookChapter chapterToSeekTo;
// if player position is less than 5 seconds into the chapter, go to the previous chapter
if (chapterPosition < doNotSeekBackIfLessThan &&
currentPlayingChapterIndex > 0) {
chapterToSeekTo = player.book!.chapters[currentPlayingChapterIndex - 1];
} else {
chapterToSeekTo = player.currentChapter!;
}
player.seek(
chapterToSeekTo.start + offset,
);
}
// /// seek backward to the previous chapter or the start of the current chapter
// void seekBackward() {
// final currentPlayingChapterIndex =
// player.book!.chapters.indexOf(player.currentChapter!);
// final chapterPosition =
// player.positionInBook - player.currentChapter!.start;
// BookChapter chapterToSeekTo;
// // if player position is less than 5 seconds into the chapter, go to the previous chapter
// if (chapterPosition < doNotSeekBackIfLessThan &&
// currentPlayingChapterIndex > 0) {
// chapterToSeekTo = player.book!.chapters[currentPlayingChapterIndex - 1];
// } else {
// chapterToSeekTo = player.currentChapter!;
// }
// player.seek(
// chapterToSeekTo.start + offset,
// );
// }
return IconButton(
icon: Icon(
@ -69,9 +69,9 @@ class AudiobookPlayerSeekChapterButton extends HookConsumerWidget {
return;
}
if (isForward) {
seekForward();
player.seekForward();
} else {
seekBackward();
player.seekBackward();
}
},
);

View file

@ -1,17 +1,14 @@
import 'package:flutter/material.dart';
import 'package:flutter_animate/flutter_animate.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:vaani/features/player/providers/audiobook_player.dart'
show audiobookPlayerProvider;
import 'package:vaani/features/player/providers/audiobook_player.dart' show audiobookPlayerProvider;
import 'package:vaani/features/player/providers/currently_playing_provider.dart'
show currentPlayingChapterProvider, currentlyPlayingBookProvider;
import 'package:vaani/features/player/view/player_when_expanded.dart'
show pendingPlayerModals;
import 'package:vaani/features/player/view/player_when_expanded.dart' show pendingPlayerModals;
import 'package:vaani/features/player/view/widgets/playing_indicator_icon.dart';
import 'package:vaani/main.dart' show appLogger;
import 'package:vaani/shared/extensions/chapter.dart' show ChapterDuration;
import 'package:vaani/shared/extensions/duration_format.dart'
show DurationFormat;
import 'package:vaani/shared/extensions/duration_format.dart' show DurationFormat;
import 'package:vaani/shared/hooks.dart' show useTimer;
class ChapterSelectionButton extends HookConsumerWidget {
@ -70,7 +67,7 @@ class ChapterSelectionModal extends HookConsumerWidget {
);
}
useTimer(scrollToCurrentChapter, 500.ms);
useTimer(scrollToCurrentChapter, 100.ms);
// useInterval(scrollToCurrentChapter, 500.ms);
final theme = Theme.of(context);
return Column(
@ -84,19 +81,18 @@ class ChapterSelectionModal extends HookConsumerWidget {
Expanded(
child: Scrollbar(
child: SingleChildScrollView(
primary: true,
child: currentBook?.chapters == null
? const Text('No chapters found')
: Column(
children: currentBook!.chapters.map(
(chapter) {
final isCurrent = currentChapterIndex == chapter.id;
final isPlayed = currentChapterIndex != null &&
chapter.id < currentChapterIndex;
final isPlayed =
currentChapterIndex != null && chapter.id < currentChapterIndex;
return ListTile(
autofocus: isCurrent,
iconColor: isPlayed && !isCurrent
? theme.disabledColor
: null,
iconColor: isPlayed && !isCurrent ? theme.disabledColor : null,
title: Text(
chapter.title,
style: isPlayed && !isCurrent