Le son joué aux 3 dernières secondes d'un chrono de step n'interrompt plus la musique de l'utilisateur en cours de lecture. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
67 lines
1.6 KiB
Dart
67 lines
1.6 KiB
Dart
import 'package:audioplayers/audioplayers.dart';
|
|
|
|
abstract interface class ExerciseStepAudioCuePlayer {
|
|
Future<void> playShortCountdownBeep();
|
|
|
|
Future<void> playLongCompletionBeep();
|
|
|
|
Future<void> dispose();
|
|
}
|
|
|
|
final class AudioplayersExerciseStepAudioCuePlayer
|
|
implements ExerciseStepAudioCuePlayer {
|
|
AudioplayersExerciseStepAudioCuePlayer();
|
|
|
|
final AudioPlayer _player = AudioPlayer();
|
|
late final Future<void> _audioContextReady = _player.setAudioContext(
|
|
_stepCueAudioContext,
|
|
);
|
|
|
|
@override
|
|
Future<void> playShortCountdownBeep() {
|
|
return _play('audio/step_countdown_short.wav');
|
|
}
|
|
|
|
@override
|
|
Future<void> playLongCompletionBeep() {
|
|
return _play('audio/step_completion_long.wav');
|
|
}
|
|
|
|
Future<void> _play(String assetPath) async {
|
|
await _audioContextReady;
|
|
await _player.stop();
|
|
await _player.play(AssetSource(assetPath));
|
|
}
|
|
|
|
@override
|
|
Future<void> dispose() {
|
|
return _player.dispose();
|
|
}
|
|
}
|
|
|
|
final _stepCueAudioContext = AudioContext(
|
|
android: const AudioContextAndroid(
|
|
contentType: AndroidContentType.sonification,
|
|
usageType: AndroidUsageType.assistanceSonification,
|
|
audioFocus: AndroidAudioFocus.none,
|
|
),
|
|
iOS: AudioContextIOS(
|
|
category: AVAudioSessionCategory.playback,
|
|
options: const {AVAudioSessionOptions.mixWithOthers},
|
|
),
|
|
);
|
|
|
|
final class NoOpExerciseStepAudioCuePlayer
|
|
implements ExerciseStepAudioCuePlayer {
|
|
const NoOpExerciseStepAudioCuePlayer();
|
|
|
|
@override
|
|
Future<void> playShortCountdownBeep() async {}
|
|
|
|
@override
|
|
Future<void> playLongCompletionBeep() async {}
|
|
|
|
@override
|
|
Future<void> dispose() async {}
|
|
}
|