116 lines
2.6 KiB
Dart
116 lines
2.6 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:audioplayers/audioplayers.dart';
|
|
import 'package:yumi/shared/data_sources/sources/local/data_persistence.dart';
|
|
|
|
class SCLuckyGiftWinSoundPlayer {
|
|
static const String assetPath =
|
|
"sc_images/room/anim/luck_gift/lucky_gift_win.mp3";
|
|
static const Duration _stopDelay = Duration(milliseconds: 3200);
|
|
static const double _volume = 0.75;
|
|
|
|
static final AudioPlayer _player = AudioPlayer();
|
|
static bool _loaded = false;
|
|
static bool _playing = false;
|
|
static Future<void>? _loadFuture;
|
|
static Future<void>? _startFuture;
|
|
static Timer? _stopTimer;
|
|
|
|
static String buildEventKey({
|
|
String? giftId,
|
|
String? userId,
|
|
String? toUserId,
|
|
num? awardAmount,
|
|
}) {
|
|
return [
|
|
(giftId ?? '').trim(),
|
|
(userId ?? '').trim(),
|
|
(toUserId ?? '').trim(),
|
|
_formatNum(awardAmount),
|
|
].join('|');
|
|
}
|
|
|
|
static Future<void> play({String? eventKey}) async {
|
|
if (DataPersistence.getPlayGiftMusic()) {
|
|
unawaited(stop());
|
|
return;
|
|
}
|
|
|
|
try {
|
|
await _ensureLoaded();
|
|
_extendStopWindow();
|
|
|
|
if (_playing || _startFuture != null) {
|
|
return;
|
|
}
|
|
|
|
_startFuture = _startPlayback();
|
|
await _startFuture;
|
|
} catch (error) {
|
|
_startFuture = null;
|
|
}
|
|
_startFuture = null;
|
|
}
|
|
|
|
static Future<void> stop() async {
|
|
_stopTimer?.cancel();
|
|
_stopTimer = null;
|
|
try {
|
|
if (_player.state != PlayerState.stopped) {
|
|
await _player.stop();
|
|
}
|
|
} catch (error) {
|
|
_playing = false;
|
|
return;
|
|
}
|
|
_playing = false;
|
|
}
|
|
|
|
static Future<void> _ensureLoaded() {
|
|
if (_loaded) {
|
|
return Future<void>.value();
|
|
}
|
|
final loadFuture = _loadFuture;
|
|
if (loadFuture != null) {
|
|
return loadFuture;
|
|
}
|
|
_loadFuture = _load();
|
|
return _loadFuture!;
|
|
}
|
|
|
|
static Future<void> _load() async {
|
|
try {
|
|
await _player.setReleaseMode(ReleaseMode.loop);
|
|
await _player.setVolume(_volume);
|
|
await _player.setSource(AssetSource(assetPath));
|
|
_loaded = true;
|
|
} catch (error) {
|
|
_loadFuture = null;
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
static Future<void> _startPlayback() async {
|
|
await _player.seek(Duration.zero);
|
|
await _player.resume();
|
|
_playing = true;
|
|
}
|
|
|
|
static void _extendStopWindow() {
|
|
_stopTimer?.cancel();
|
|
_stopTimer = Timer(_stopDelay, () {
|
|
unawaited(stop());
|
|
});
|
|
}
|
|
|
|
static String _formatNum(num? value) {
|
|
if (value == null) {
|
|
return '';
|
|
}
|
|
if (value % 1 == 0) {
|
|
return value.toInt().toString();
|
|
}
|
|
return value.toString();
|
|
}
|
|
}
|