增加跳过片头片尾,上一章下一章移动到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

@ -0,0 +1,86 @@
import 'dart:async';
import 'package:vaani/features/player/core/audiobook_player.dart';
class SkipStartEnd {
final Duration start;
final Duration end;
final AudiobookPlayer player;
int _index;
final List<StreamSubscription> _subscriptions = [];
final throttler = Throttler(delay: Duration(seconds: 3));
// final StreamController<PlaybackEvent> _playbackController =
// StreamController<PlaybackEvent>.broadcast();
SkipStartEnd({required this.start, required this.end, required this.player}) : _index = 0 {
if (start > Duration()) {
_subscriptions.add(
player.currentIndexStream.listen((index) {
if (_index != index && player.position.inMilliseconds < 500) {
_index = index!;
Future.microtask(() {
player.seek(start, b: false);
});
}
}),
);
}
if (end > Duration()) {
_subscriptions.add(
player.positionStream.distinct().listen((position) {
if (player.duration != null &&
player.duration!.inMilliseconds - player.position.inMilliseconds <
end.inMilliseconds) {
Future.microtask(() {
throttler.call(player.seekForward);
});
}
}),
);
}
}
/// dispose the timer
void dispose() {
for (var sub in _subscriptions) {
sub.cancel();
}
throttler.dispose();
// _playbackController.close();
}
}
class Throttler {
final Duration delay;
Timer? _timer;
DateTime? _lastRun;
Throttler({required this.delay});
void call(void Function() callback) {
//
if (_lastRun == null) {
callback();
_lastRun = DateTime.now();
return;
}
//
if (DateTime.now().difference(_lastRun!) > delay) {
callback();
_lastRun = DateTime.now();
}
//
else {
_timer?.cancel();
_timer = Timer(delay, () {
callback();
_lastRun = DateTime.now();
});
}
}
void dispose() {
_timer?.cancel();
}
}