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? _loadFuture; static Future? _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 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 stop() async { _stopTimer?.cancel(); _stopTimer = null; try { if (_player.state != PlayerState.stopped) { await _player.stop(); } } catch (error) { _playing = false; return; } _playing = false; } static Future _ensureLoaded() { if (_loaded) { return Future.value(); } final loadFuture = _loadFuture; if (loadFuture != null) { return loadFuture; } _loadFuture = _load(); return _loadFuture!; } static Future _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 _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(); } }