-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsound_manager.py
More file actions
184 lines (149 loc) · 5.37 KB
/
Copy pathsound_manager.py
File metadata and controls
184 lines (149 loc) · 5.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
"""
声音管理模块
提供界面音效播放功能,支持跨平台兼容性
"""
import sys
import os
import threading
from typing import Optional
import json
try:
import pygame
PYGAME_AVAILABLE = True
except ImportError:
PYGAME_AVAILABLE = False
def get_resource_path(relative_path):
"""获取资源文件的绝对路径,支持开发环境和打包后的exe环境"""
try:
# PyInstaller创建临时文件夹,并将路径存储在_MEIPASS中
base_path = sys._MEIPASS
except Exception:
# 如果不是打包环境,使用当前脚本目录
base_path = os.path.dirname(os.path.abspath(__file__))
return os.path.join(base_path, relative_path)
class SoundManager:
"""声音管理器 - 单例模式"""
_instance: Optional['SoundManager'] = None
_lock = threading.Lock()
def __new__(cls):
if cls._instance is None:
with cls._lock:
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def __init__(self):
if hasattr(self, '_initialized'):
return
self._initialized = True
self.enabled = True # 默认开启音效
self.sounds_dir = get_resource_path(os.path.join("assets", "sounds"))
self.sounds = {}
self.mixer_initialized = False
# 初始化音频系统
self._init_mixer()
# 预加载声音文件
self._load_sounds()
def _init_mixer(self):
"""初始化pygame mixer"""
if not PYGAME_AVAILABLE:
return
try:
pygame.mixer.pre_init(frequency=22050, size=-16, channels=2, buffer=512)
pygame.mixer.init()
self.mixer_initialized = True
except Exception as e:
self.mixer_initialized = False
def _load_sounds(self):
"""预加载所有声音文件"""
if not self.mixer_initialized:
return
sound_files = {
'check': 'check.wav',
'uncheck': 'uncheck.wav',
'buzz': 'buzz.wav',
'success': 'success.wav',
'complete': 'complete.wav',
'cancel': 'cancel.wav',
'test': 'test.wav'
}
for sound_name, filename in sound_files.items():
sound_path = os.path.join(self.sounds_dir, filename)
try:
if os.path.exists(sound_path):
self.sounds[sound_name] = pygame.mixer.Sound(sound_path)
except Exception as e:
pass # 静默处理加载失败
def play_sound(self, sound_name: str, volume: float = 0.7):
"""
播放指定的声音
Args:
sound_name: 声音名称 ('check', 'uncheck', 'buzz', 'success')
volume: 音量 (0.0 - 1.0)
"""
if not self.enabled or not self.mixer_initialized:
return
if sound_name not in self.sounds:
return
try:
sound = self.sounds[sound_name]
sound.set_volume(volume)
sound.play()
except Exception as e:
pass # 静默处理播放失败
def play_check(self):
"""播放选择音效"""
self.play_sound('check')
def play_uncheck(self):
"""播放取消选择音效"""
self.play_sound('uncheck')
def play_buzz(self):
"""播放边界提示音效"""
self.play_sound('buzz')
def play_success(self):
"""播放成功完成音效"""
self.play_sound('success')
def play_complete(self):
"""播放OCR完成音效"""
self.play_sound('complete')
def play_cancel(self):
"""播放取消音效"""
self.play_sound('cancel')
def play_test(self):
"""播放测试音效"""
self.play_sound('test')
def set_enabled(self, enabled: bool):
"""设置音效开关状态"""
self.enabled = enabled
def is_enabled(self) -> bool:
"""获取音效开关状态"""
return self.enabled
def load_settings(self, settings_path: str = "settings.json"):
"""从设置文件加载音效配置"""
try:
if os.path.exists(settings_path):
with open(settings_path, 'r', encoding='utf-8') as f:
settings = json.load(f)
self.enabled = settings.get('sound_enabled', True)
except Exception as e:
pass
def save_settings(self, settings_path: str = "settings.json"):
"""保存音效配置到设置文件"""
try:
settings = {}
if os.path.exists(settings_path):
with open(settings_path, 'r', encoding='utf-8') as f:
settings = json.load(f)
settings['sound_enabled'] = self.enabled
with open(settings_path, 'w', encoding='utf-8') as f:
json.dump(settings, f, ensure_ascii=False, indent=2)
except Exception as e:
pass
def cleanup(self):
"""清理资源"""
if self.mixer_initialized:
try:
pygame.mixer.quit()
except Exception as e:
pass
# 全局声音管理器实例
sound_manager = SoundManager()