yumi-flutter/lib/shared/tools/sc_lucky_gift_win_sound_player.dart
2026-06-02 13:57:50 +08:00

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();
}
}