100 lines
2.0 KiB
Dart
100 lines
2.0 KiB
Dart
import 'dart:async' as async;
|
|
import 'dart:typed_data';
|
|
|
|
import 'package:audioplayers/audioplayers.dart';
|
|
|
|
abstract class RuntimeAudioPlayer {
|
|
Future<void> start(
|
|
Uint8List bytes, {
|
|
required double volume,
|
|
bool loop = false,
|
|
});
|
|
|
|
Future<void> pause();
|
|
|
|
Future<void> resume();
|
|
|
|
Future<void> stop();
|
|
|
|
Future<void> get done;
|
|
|
|
Future<void> dispose();
|
|
}
|
|
|
|
class AudioplayersRuntimeAudioPlayer implements RuntimeAudioPlayer {
|
|
AudioplayersRuntimeAudioPlayer({AudioPlayer? player})
|
|
: _player = player ?? AudioPlayer();
|
|
|
|
final AudioPlayer _player;
|
|
async.Completer<void> _done = async.Completer<void>();
|
|
async.StreamSubscription<void>? _completionSubscription;
|
|
bool _disposed = false;
|
|
|
|
@override
|
|
Future<void> get done => _done.future;
|
|
|
|
@override
|
|
Future<void> start(
|
|
Uint8List bytes, {
|
|
required double volume,
|
|
bool loop = false,
|
|
}) async {
|
|
if (_disposed) {
|
|
return;
|
|
}
|
|
await _completionSubscription?.cancel();
|
|
_completionSubscription = null;
|
|
if (_done.isCompleted) {
|
|
_done = async.Completer<void>();
|
|
}
|
|
_completionSubscription = _player.onPlayerComplete.listen((_) {
|
|
_completeDone();
|
|
});
|
|
await _player.setReleaseMode(loop ? ReleaseMode.loop : ReleaseMode.release);
|
|
await _player.play(BytesSource(bytes), volume: volume);
|
|
}
|
|
|
|
@override
|
|
Future<void> pause() async {
|
|
if (_disposed) {
|
|
return;
|
|
}
|
|
await _player.pause();
|
|
}
|
|
|
|
@override
|
|
Future<void> resume() async {
|
|
if (_disposed) {
|
|
return;
|
|
}
|
|
await _player.resume();
|
|
}
|
|
|
|
@override
|
|
Future<void> stop() async {
|
|
if (_disposed) {
|
|
return;
|
|
}
|
|
await _player.stop();
|
|
_completeDone();
|
|
}
|
|
|
|
@override
|
|
Future<void> dispose() async {
|
|
if (_disposed) {
|
|
return;
|
|
}
|
|
_disposed = true;
|
|
await _completionSubscription?.cancel();
|
|
_completionSubscription = null;
|
|
await _player.dispose();
|
|
_completeDone();
|
|
}
|
|
|
|
void _completeDone() {
|
|
if (!_done.isCompleted) {
|
|
_done.complete();
|
|
}
|
|
}
|
|
}
|