| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- // // puzzleweave/audio/audio_controller.dart
- // import 'package:flutter/widgets.dart';
- // import 'package:audioplayers/audioplayers.dart';
- // import 'package:puzzleweave/settings/settings_controller.dart';
- // import 'package:logging/logging.dart';
- // enum SfxType { drop, click, tap, pop, appear, alert, star, success, flip, card, cardShort, panstart, panend, panend2 }
- // /// 允许播放音乐和声音效果。
- // class AudioControllerX {
- // static final _log = Logger('AudioController');
- // SettingsController? _settings;
- // ValueNotifier<AppLifecycleState>? _lifecycleNotifier;
- // // 1. BGM 播放器 (使用常规模式进行流式传输,专用于音乐)
- // final AudioPlayer _musicPlayer = AudioPlayer();
- // // 2. 音效音频池 (用于低延迟播放 SFX)
- // // Key: SfxType, Value: AudioPool 实例
- // final Map<SfxType, AudioPool> _sfxPools = {};
- // // 预加载的 BGM 文件路径
- // final String _bgmAsset = 'audio/bgm/canon.mp3';
- // // 所有音效文件映射
- // static const Map<SfxType, String> _sfxPaths = {
- // SfxType.drop: 'audio/sfx/button_click8.mp3',
- // SfxType.click: 'audio/sfx/click2.mp3',
- // SfxType.tap: 'audio/sfx/tap.mp3',
- // SfxType.pop: 'audio/sfx/pop.mp3',
- // SfxType.appear: 'audio/sfx/appear.mp3',
- // SfxType.alert: 'audio/sfx/alert.mp3',
- // SfxType.star: 'audio/sfx/star.mp3',
- // SfxType.success: 'audio/sfx/win.mp3',
- // SfxType.card: 'audio/sfx/card.mp3',
- // SfxType.cardShort: 'audio/sfx/card2.mp3',
- // SfxType.flip: 'audio/sfx/flip.mp3',
- // SfxType.panstart: 'audio/sfx/pan_start.mp3',
- // SfxType.panend: 'audio/sfx/pan_end.mp3',
- // SfxType.panend2: 'audio/sfx/pan_end2.mp3',
- // };
- // AudioControllerX() {
- // // 配置 BGM 播放器:设置为循环模式
- // _musicPlayer.setReleaseMode(ReleaseMode.loop);
- // }
- // /// 在应用启动时异步调用,用于预加载所有音乐和音效。
- // Future<void> initialize() async {
- // // 1. 预加载 BGM
- // await _musicPlayer.setSource(AssetSource(_bgmAsset));
- // // 2. 预加载所有 SFX 到 AudioPool 中 (实现真正的低延迟)
- // final futures = _sfxPaths.entries.map((entry) async {
- // final type = entry.key;
- // final path = entry.value;
- // // ⚠️ 修复:使用 AudioPool.createFromAssetSource 替换 fromAsset
- // final pool = await AudioPool.createFromAsset(
- // path: path, // 直接传入 String 路径
- // maxPlayers: type == SfxType.card ? 10 : 3,
- // );
- // _sfxPools[type] = pool;
- // }).toList();
- // await Future.wait(futures);
- // _log.info('All sounds and music preloaded successfully via AudioPool.');
- // }
- // void dispose() {
- // _lifecycleNotifier?.removeListener(_handleAppLifecycle);
- // stopMusic();
- // // 停止并清理所有的音频池,释放原生资源
- // for (final pool in _sfxPools.values) {
- // pool.dispose();
- // }
- // _sfxPools.clear();
- // _musicPlayer.dispose();
- // }
- // /// Enables the [AudioController] to listen to [AppLifecycleState] events...
- // void attachLifecycleNotifier(ValueNotifier<AppLifecycleState> lifecycleNotifier) {
- // _lifecycleNotifier?.removeListener(_handleAppLifecycle);
- // lifecycleNotifier.addListener(_handleAppLifecycle);
- // _lifecycleNotifier = lifecycleNotifier;
- // }
- // /// Enables the [AudioController] to track changes to settings...
- // void attachSettings(SettingsController settingsController) {
- // if (_settings == settingsController) return;
- // final oldSettings = _settings;
- // if (oldSettings != null) {
- // oldSettings.music.removeListener(_musicOnHandler);
- // oldSettings.sound.removeListener(_soundOnHandler);
- // }
- // _settings = settingsController;
- // settingsController.music.addListener(_musicOnHandler);
- // settingsController.sound.addListener(_soundOnHandler);
- // }
- // /// Plays a single sound effect, defined by [type].
- // /// 使用 AudioPool 实现极低延迟播放。
- // void playSfx(SfxType type, {Duration? duration}) async {
- // final soundsOn = _settings?.sound.value ?? false;
- // if (!soundsOn) {
- // _log.info(() => 'Ignoring playing sound ($type) because sounds are turned off.');
- // return;
- // }
- // final pool = _sfxPools[type];
- // if (pool == null) {
- // _log.severe('Missing audio pool for SFX type: $type');
- // return;
- // }
- // // 核心优化:从 AudioPool 快速启动播放。
- // await pool.start(volume: 1.0);
- // if (duration != null) {
- // _log.warning('Duration control is complex with AudioPool; generally SFX should be short.');
- // }
- // }
- // void _handleAppLifecycle() {
- // switch (_lifecycleNotifier!.value) {
- // case AppLifecycleState.paused:
- // case AppLifecycleState.detached:
- // case AppLifecycleState.hidden:
- // case AppLifecycleState.inactive:
- // pauseMusic();
- // break;
- // case AppLifecycleState.resumed:
- // startMusic();
- // break;
- // }
- // }
- // void _musicOnHandler() {
- // if (_settings!.music.value) {
- // startMusic();
- // } else {
- // stopMusic();
- // }
- // }
- // void _soundOnHandler() {
- // // 声音设置关闭时,不需要特殊处理 AudioPool 播放的短音效
- // }
- // void setMusicVolume(double volume) {
- // _musicPlayer.setVolume(volume);
- // _log.info('Music volume set to $volume');
- // }
- // void startMusic() async {
- // _log.info('starting music');
- // final musicOn = _settings?.music.value ?? false;
- // if (!musicOn) {
- // _log.info(() => 'Ignoring playing music because music are turned off.');
- // return;
- // }
- // // 假设我们希望 BGM 默认音量为 0.5
- // const double defaultBGMVolume = 0.1;
- // final state = _musicPlayer.state;
- // if (state == PlayerState.playing) return;
- // // 如果音乐已经停止或未播放,则重新设置源并播放
- // if (state == PlayerState.stopped || state == PlayerState.disposed) {
- // await _musicPlayer.setSource(AssetSource(_bgmAsset));
- // await _musicPlayer.setVolume(defaultBGMVolume);
- // await _musicPlayer.resume();
- // } else {
- // // 从暂停状态恢复
- // await _musicPlayer.resume();
- // }
- // }
- // void stopMusic() {
- // _log.info('Stopping music');
- // _musicPlayer.stop();
- // }
- // void pauseMusic() {
- // _log.info('pause music');
- // _musicPlayer.pause();
- // }
- // Future<void> resumeMusic() async {
- // _log.info('Resuming music');
- // final musicOn = _settings?.music.value ?? false;
- // if (musicOn) {
- // _musicPlayer.resume();
- // }
- // }
- // void _stopSound() {
- // // AudioPool 播放的短音效不需要手动停止
- // }
- // }
|