Player-agnostic A–B section looping for audio apps.
Repeat a named region of a track — a chorus, a drill, a phrase of speech — on whatever player you already use. The package holds no player of its own: you feed it position updates and it tells your player when to seek or pause.
Built for AudioMark, a practice player for dancers, and extracted so the looping logic can be reused and tested on its own.
dependencies:
section_loop: ^0.1.0import 'package:section_loop/section_loop.dart';
final engine = SectionLoopEngine(
onSeek: player.seek,
onPause: player.pause,
onPlay: player.play, // optional: resumes a paused player when looping
);
engine.section = LoopSection(
name: 'Chorus',
start: const Duration(seconds: 48),
end: const Duration(seconds: 72),
);
player.positionStream.listen((position) {
engine.handlePosition(position, trackDuration: player.duration);
});Set engine.section = null (or call clear()) to let the track play through.
engine.behavior = SectionEndBehavior.pauseAtEnd;LoopSection round-trips through JSON, so sections can be stored alongside
whatever else you keep for a track:
final stored = jsonEncode(section.toJson());
final restored = LoopSection.fromJson(jsonDecode(stored) as Map<String, Object?>);Both are easy to hit and tedious to diagnose, so they are handled here and covered by tests.
A range covering the whole track is not treated as a section. Looping one
means seeking at the final moment of playback, which suppresses the player's
completion event — so a queue above it silently stops advancing. Ranges that
reach both ends of the track are ignored. The margin is configurable through
edgeTolerance.
Positions arriving while a seek is in flight are ignored. Players keep
emitting the pre-seek position for a few frames after seek() is called.
Acting on those queues up another seek, and playback never escapes the
boundary. The engine drops positions until its own seek completes.
Anything you can seek, pause, and subscribe to positions on — just_audio,
audioplayers, a platform player behind a method channel, or a fake in a test.
The package is pure Dart and depends on no player.
MIT