PrankSoundboard/lib/managers/sound_manager.dart

110 lines
3.5 KiB
Dart

import 'package:flutter/material.dart';
import 'package:audioplayers/audioplayers.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../models/prank_sound.dart';
class SoundManager {
static final SoundManager _instance = SoundManager._internal();
factory SoundManager() => _instance;
SoundManager._internal();
final AudioPlayer audioPlayer = AudioPlayer();
// 播放状态 Notifiers
final ValueNotifier<PrankSound?> currentSoundNotifier = ValueNotifier(null);
final ValueNotifier<bool> isPlayingNotifier = ValueNotifier(false);
final ValueNotifier<Duration> positionNotifier = ValueNotifier(Duration.zero);
final ValueNotifier<Duration> durationNotifier = ValueNotifier(Duration.zero);
// 设置状态 Notifiers (支持 UI 监听)
final ValueNotifier<double> volumeNotifier = ValueNotifier(1.0); // 默认 100%
final ValueNotifier<bool> loopNotifier = ValueNotifier(false); // 默认不循环
static const String KEY_VOLUME = 'app_volume';
static const String KEY_LOOP = 'app_loop';
Future<void> init() async {
// 监听播放器事件
audioPlayer.onPlayerStateChanged.listen((state) {
isPlayingNotifier.value = state == PlayerState.playing;
});
audioPlayer.onDurationChanged.listen((d) {
durationNotifier.value = d;
});
audioPlayer.onPositionChanged.listen((p) {
positionNotifier.value = p;
});
audioPlayer.onPlayerComplete.listen((_) {
// 只有在非循环模式下,播放结束才停止
if (!loopNotifier.value) {
isPlayingNotifier.value = false;
positionNotifier.value = Duration.zero;
}
});
// 加载本地设置
final prefs = await SharedPreferences.getInstance();
final double savedVolume = prefs.getDouble(KEY_VOLUME) ?? 1.0;
final bool savedLoop = prefs.getBool(KEY_LOOP) ?? false;
// 更新内存状态
volumeNotifier.value = savedVolume;
loopNotifier.value = savedLoop;
// 应用到播放器
await audioPlayer.setVolume(savedVolume);
await audioPlayer.setReleaseMode(savedLoop ? ReleaseMode.loop : ReleaseMode.stop);
}
// 设置音量并保存
Future<void> setVolume(double volume) async {
volumeNotifier.value = volume;
await audioPlayer.setVolume(volume);
final prefs = await SharedPreferences.getInstance();
await prefs.setDouble(KEY_VOLUME, volume);
}
// 设置循环并保存
Future<void> setLooping(bool loop) async {
loopNotifier.value = loop;
await audioPlayer.setReleaseMode(loop ? ReleaseMode.loop : ReleaseMode.stop);
final prefs = await SharedPreferences.getInstance();
await prefs.setBool(KEY_LOOP, loop);
}
Future<void> play(PrankSound sound) async {
try {
if (currentSoundNotifier.value == sound) {
if (isPlayingNotifier.value) {
await audioPlayer.pause();
} else {
await audioPlayer.resume();
}
} else {
await audioPlayer.stop();
currentSoundNotifier.value = sound;
// 播放前确保应用了当前的设置
await audioPlayer.setVolume(volumeNotifier.value);
await audioPlayer.setReleaseMode(loopNotifier.value ? ReleaseMode.loop : ReleaseMode.stop);
if (sound.mp3Url.isNotEmpty) {
await audioPlayer.play(UrlSource(sound.mp3Url));
}
}
} catch (e) {
debugPrint("Play Error: $e");
}
}
Future<void> stop() async {
await audioPlayer.stop();
currentSoundNotifier.value = null;
isPlayingNotifier.value = false;
positionNotifier.value = Duration.zero;
}
}