I'm trying to write a small app in my spare time and this app needs to include a basic audio player with play/pause functionality. But I cannot find how to implement it in a stable way. I've tried several ways and it always happens that it crashes now and then.
It is very basic stuff: play/pause audio on keypress and display current playing position.
I've extracted the culprit part of the code and included it below (if you want to test it, make sure that you change the audio file path towards the end to an existing audio file on your phone).
It works fine as long as you press the dpad center button not too fast.
The problem is that if I fire a fast sequence of say 10 key presses (pressing as fast as I can on the phone; I managed to recreate the problem even with just 3 key presses), it stops working fine: time is no longer updated during playback (main thread crashed? ao_sleep problem?) and even if you press the exit key, the app doesn't exit.
I really can't see where the issue is, I must have missed something in the documentation or is it a problem with PyS60 itself ?
BTW: I've also tried adding a lock in the canvas callback (see the lines commented out) but that didn't help. And BTW the documentation is a bit unclear about ao_sleep: from the doc it seems that you should never use it but then most of the examples included in the distribution do use it!
PS: Is there a way to test this on the emulator? My emulator doesn't seem to be able to play mp3 audio files...
Code:import sys import audio import appuifw import e32 from key_codes import * import thread def setmsg(m): global canvaslock, msg #canvaslock.acquire() msg = m #canvaslock.release() draw_state() def audiocallback(p,c,e): setmsg('callback prev='+str(p)+' new='+str(c)+' err='+str(e)) def draw_state(): global position, player, exitflag, canvaslock #canvaslock.acquire() canvas.clear() canvas.text((0,12),unicode(msg),0x008000) pos = position if player.state() == audio.EPlaying: pos = player.current_position() canvas.text((0,24),unicode(str(pos)),0x008000) if exitflag: canvas.text((0,36),u'exiting',0x008000) else: canvas.text((0,36),u'looping',0x008000) #canvaslock.release() def handler(arg): global player if arg['scancode'] == EScancodeSelect and arg['type'] == appuifw.EEventKeyDown: setmsg(".") if player.state() == audio.EPlaying: stop() else: play() def stop(): global player, position setmsg("enter Stop (state is " + str(player.state()) + ")") if player.state() == audio.EPlaying: position = player.current_position() player.stop() setmsg("sent stop (state is " + str(player.state()) + ")") while player.state() != audio.EOpen: e32.ao_sleep(.1) setmsg("Stopped (state is " + str(player.state()) + ")") def play(): global player, position setmsg("enter Play (state is " + str(player.state()) + ")") if player.state() == audio.EOpen: player.set_position(position) player.play(callback=audiocallback) while player.state() != audio.EPlaying: e32.ao_sleep(.1) setmsg("Playing (state is " + str(player.state()) + ")") def set_exit(): global exitflag exitflag = True canvaslock = thread.allocate_lock() exitflag = False position = 0 player = audio.Sound.open("E:\\Audiobooks\\test\\test.mp3") player.set_volume(player.max_volume()/2) msg="" canvas=appuifw.Canvas(event_callback=handler,redraw_callback=lambda rect:draw_state()) appuifw.app.body=canvas appuifw.app.exit_key_handler=set_exit setmsg("Ready") while not exitflag: draw_state() e32.ao_sleep(0.1)

Reply With Quote

