Changeset 800:709f86ab4573
- Timestamp:
- 07/29/16 08:39:59 (8 years ago)
- Branch:
- default
- Phase:
- public
- Location:
- src/mlx
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
src/mlx/common.py
r740 r800 27 27 pygobject = False 28 28 import gobject 29 try:30 import pygst31 pygst.require('0.10')32 import gst33 34 def gst_init():35 pass36 37 def gst_element_factory_make(what):38 return gst.element_factory_make(what)39 40 GST_STATE_PLAYING=gst.STATE_PLAYING41 GST_MESSAGE_EOS=gst.MESSAGE_EOS42 except:43 pass44 29 else: 45 30 print "Using PyGObject" … … 47 32 48 33 from gi.repository import GObject as gobject 49 50 try:51 from gi.repository import Gst as gst52 53 def gst_init():54 gst.init()55 56 def gst_element_factory_make(what):57 return gst.ElementFactory.make(what)58 59 GST_STATE_PLAYING=gst.State.PLAYING60 GST_MESSAGE_EOS=gst.MessageType.EOS61 except:62 import traceback63 traceback.print_exc()64 pass -
src/mlx/mlx.py
r573 r800 2 2 from config import Config 3 3 from i18n import setLanguage 4 from sound import initializeSound, finalizeSound4 from sound import preInitializeSound, initializeSound, finalizeSound 5 5 from util import secondaryInstallation 6 6 from const import VERSION … … 78 78 setLanguage(programDirectory, config.getLanguage()) 79 79 80 preInitializeSound() 81 80 82 from .gui.gui import GUI 81 83 gui = GUI(programDirectory, config) -
src/mlx/sound.py
r585 r800 157 157 _thread = None 158 158 159 def preInitializeSound(): 160 """Perform any-pre initialization. 161 162 This does nothing on Windows.""" 163 159 164 def initializeSound(soundsDirectory): 160 165 """Initialize the sound handling with the given directory containing … … 179 184 180 185 else: # os.name!="nt" 181 import threading 186 from multiprocessing import Process, Queue 187 from threading import Thread, Lock 188 189 COMMAND_STARTSOUND = 1 190 COMMAND_QUIT = 2 191 192 REPLY_FINISHED = 101 193 REPLY_FAILED = 102 194 REPLY_QUIT = 103 195 196 _initialized = False 197 _process = None 198 _thread = None 199 _inQueue = None 200 _outQueue = None 201 _nextReference = 1 202 _ref2Data = {} 203 _lock = Lock() 204 205 def _processFn(inQueue, outQueue): 206 """The function running in the helper process created. 207 208 It tries to load the Gst module. If successful, True is sent back, 209 otherwise False followed by the exception caught and the function 210 quits. 211 212 In case of successful initialization, the directory of the sound files 213 is read, the command reader thread is created and the gobject main loop 214 is executed.""" 215 try: 216 import gi.repository 217 gi.require_version("Gst", "1.0") 218 from gi.repository import Gst 219 from gi.repository import GObject as gobject 220 221 Gst.init(None) 222 except Exception, e: 223 outQueue.put(False) 224 outQueue.put(e) 225 return 226 227 outQueue.put(True) 228 229 soundsDirectory = inQueue.get() 230 231 _bins = set() 232 233 mainLoop = None 234 235 def _handlePlayBinMessage(bus, message, bin, reference): 236 """Handle messages related to a playback.""" 237 if bin in _bins: 238 if message.type==Gst.MessageType.EOS: 239 _bins.remove(bin) 240 if reference is not None: 241 outQueue.put((REPLY_FINISHED, (reference,))) 242 elif message.type==Gst.MessageType.ERROR: 243 _bins.remove(bin) 244 if reference is not None: 245 outQueue.put((REPLY_FAILED, (reference,))) 246 247 def _handleCommand(command, args): 248 """Handle commands sent to the server.""" 249 if command==COMMAND_STARTSOUND: 250 (name, reference) = args 251 try: 252 playBin = Gst.ElementFactory.make("playbin", "player") 253 254 bus = playBin.get_bus() 255 bus.add_signal_watch() 256 bus.connect("message", _handlePlayBinMessage, 257 playBin, reference) 258 259 path = os.path.join(soundsDirectory, name) 260 playBin.set_property( "uri", "file://%s" % (path,)) 261 262 playBin.set_state(Gst.State.PLAYING) 263 _bins.add(playBin) 264 except Exception as e: 265 if reference is not None: 266 outQueue.put((REPLY_FAILED, (reference,))) 267 elif command==COMMAND_QUIT: 268 outQueue.put((REPLY_QUIT, None)) 269 mainLoop.quit() 270 271 def _processCommands(): 272 """Process incoming commands. 273 274 It is to be executed in a separate thread and it reads the incoming 275 queue for commands. The commands with their arguments are added to the 276 idle queue of gobject so that _handleCommand will be called by them. 277 278 If COMMAND_QUIT is received, the thread exits.""" 279 280 while True: 281 (command, args) = inQueue.get() 282 283 gobject.idle_add(_handleCommand, command, args) 284 if command==COMMAND_QUIT: 285 break 286 287 commandThread = Thread(target = _processCommands) 288 commandThread.daemon = True 289 commandThread.start() 290 291 292 mainLoop = gobject.MainLoop() 293 mainLoop.run() 294 295 commandThread.join() 296 297 def _handleInQueue(): 298 """Handle the incoming queue in the main program. 299 300 It reads the replies sent by the helper process. In case of 301 REPLY_FINISHED and REPLY_FAILED the appropriate callback is called. In 302 case of REPLY_QUIT, the thread quits as well.""" 303 while True: 304 (reply, args) = _inQueue.get() 305 if reply==REPLY_FINISHED or reply==REPLY_FAILED: 306 (reference,) = args 307 callback = None 308 extra = None 309 with _lock: 310 (callback, extra) = _ref2Data.get(reference, (None, None)) 311 if callback is not None: 312 del _ref2Data[reference] 313 if callback is not None: 314 callback(reply==REPLY_FINISHED, extra) 315 elif reply==REPLY_QUIT: 316 break 317 318 def preInitializeSound(): 319 """Start the sound handling process and create the thread handling the 320 incoming queue.""" 321 global _thread 322 global _process 323 global _inQueue 324 global _outQueue 325 326 _inQueue = Queue() 327 _outQueue = Queue() 328 329 _process = Process(target = _processFn, args = (_outQueue, _inQueue)) 330 _process.start() 331 332 _thread = Thread(target = _handleInQueue) 333 _thread.daemon = True 334 335 def initializeSound(soundsDirectory): 336 """Initialize the sound handling. It reads a boolean from the incoming 337 queue indicating if the libraries could be loaded by the process. 338 339 If the boolean is True, the thread handling the incoming replies is 340 started and the directory containing the sounds file is written to the 341 output queue. 342 343 Otherwise the exception is read from the queue, and printed with an 344 error message.""" 345 global _initialized 346 _initialized = _inQueue.get() 347 348 if _initialized: 349 _thread.start() 350 _outQueue.put(soundsDirectory) 351 else: 352 exception = _inQueue.get() 353 print "The Gst library is missing from your system. It is needed for sound playback on Linux:" 354 print exception 355 356 def startSound(name, finishCallback = None, extra = None): 357 """Start playing back the given sound. 358 359 If a callback is given, a new reference is acquired and the callback is 360 registered with it. Then a COMMAND_STARTSOUND command is written to the 361 output queue""" 362 if _initialized: 363 reference = None 364 if finishCallback is not None: 365 with _lock: 366 global _nextReference 367 reference = _nextReference 368 _nextReference += 1 369 _ref2Data[reference] = (finishCallback, extra) 370 371 _outQueue.put((COMMAND_STARTSOUND, (name, reference))) 372 373 def finalizeSound(): 374 """Finalize the sound handling. 375 376 COMMAND_QUIT is sent to the helper process, and then it is joined.""" 377 if _initialized: 378 _outQueue.put((COMMAND_QUIT, None)) 379 _process.join() 380 _thread.join() 381 382 #------------------------------------------------------------------------------ 383 #------------------------------------------------------------------------------ 384 385 if __name__ == "__main__": 182 386 import time 183 try: 184 from common import gst_init, gobject, gst_element_factory_make 185 from common import GST_STATE_PLAYING, GST_MESSAGE_EOS 186 187 _soundsDirectory = None 188 _bins = set() 189 190 def initializeSound(soundsDirectory): 191 """Initialize the sound handling with the given directory containing 192 the sound files.""" 193 gst_init() 194 global _soundsDirectory 195 _soundsDirectory = soundsDirectory 196 197 def startSound(name, finishCallback = None, extra = None): 198 """Start playing back the given sound.""" 199 try: 200 playBin = gst_element_factory_make("playbin") 201 202 bus = playBin.get_bus() 203 bus.enable_sync_message_emission() 204 bus.add_signal_watch() 205 bus.connect("message", _handlePlayBinMessage, 206 playBin, finishCallback, extra) 207 208 path = os.path.join(_soundsDirectory, name) 209 playBin.set_property( "uri", "file://%s" % (path,)) 210 211 playBin.set_state(GST_STATE_PLAYING) 212 _bins.add(playBin) 213 except Exception, e: 214 print "mlx.sound.startSound: " + str(e) 215 if finishCallback is not None: 216 finishCallback(False, extra) 217 218 def finalizeSound(): 219 """Finalize the sound handling.""" 220 pass 221 222 def _handlePlayBinMessage(bus, message, bin, finishCallback, extra): 223 """Handle the end of the playback of a sound file.""" 224 225 # if message.type==GST_MESSAGE_EOS: 226 # _bins.remove(bin) 227 # if finishCallback is not None: 228 # finishCallback(True, extra) 229 230 except: 231 print "The Gst library is missing from your system. It is needed for sound playback on Linux" 232 traceback.print_exc() 233 def initializeSound(soundsDirectory): 234 """Initialize the sound handling with the given directory containing 235 the sound files.""" 236 pass 237 238 def startSound(name, finishCallback = None, extra = None): 239 """Start playing back the given sound. 240 241 FIXME: it does not do anything currently, but it should.""" 242 print "sound.startSound:", name 243 244 def finalizeSound(): 245 """Finalize the sound handling.""" 246 pass 247 248 #------------------------------------------------------------------------------ 249 #------------------------------------------------------------------------------ 250 251 if __name__ == "__main__": 387 252 388 def callback(result, extra): 253 389 print "callback", result, extra 254 390 255 initializeSound("e:\\home\\vi\\tmp") 391 preInitializeSound() 392 393 soundsPath = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), 394 "..", "..", "sounds")) 395 print "soundsPath:", soundsPath 396 initializeSound(soundsPath) 397 startSound("notam.mp3", finishCallback = callback, extra= "notam.mp3") 398 time.sleep(5) 256 399 startSound("malev.mp3", finishCallback = callback, extra="malev.mp3") 257 400 time.sleep(5) … … 261 404 time.sleep(5) 262 405 startSound("ding.wav", finishCallback = callback, extra="ding3.wav") 406 time.sleep(5) 407 startSound("dong.wav", finishCallback = callback, extra="dong3.wav") 263 408 time.sleep(50) 264 409 265 #------------------------------------------------------------------------------ 410 finalizeSound() 411 412 #------------------------------------------------------------------------------
Note:
See TracChangeset
for help on using the changeset viewer.