[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [pygame] pygame newbie



> i got a small example, which doesn't work, as i would expect:

hello kaweh, we'll step through it here...
i'll just put explanations after each block, hopefully we can
cleanup the code a little and you can get a better understanding
of what is going on :]

> 
>     import pygame
>     import pygame.mixer as mixer
>     import pygame.music as music
>     import pygame.time as time
>     import pygame.event as event
>     from pygame.locals import *

time and event modules are imported automatically with
pygame, you can import everything you need with these lines

import pygame
import pygame.music
from pygame.locals import *


>     mixer.pre_init()
>     #pygame.init() 
>     music.init()
>     if not music.get_init():
>         raise SystemExit, 'could not initialize music'

the mixer.pre_init() call is doing nothing. all this method does
is change the default frequency and datasize for sound files.
it is not needed, especially if calling it with no arguments,
it really does do nothing. calling pygame.init() will try to
initialize all imported pygame modules, so the extra call to
initialize music isn't important. this reduces down to

pygame.init()
if not pygame.music.get_init():
    raise SystemExit, 'cannot initialize music'


>     mp3 = music.load('E:/MP3/Basis - Ich Lieb Dich Immer Noch.mp3')
>     music.play(0)

just a couple notes. the pygame.music.load() routine returns None.
the reason is the music module works more like a state machine, it
only plays the currently loaded sound. also, 0 is the default looping
argument for play already, so this block can be cleanly reduced to

music.load('E:/MP3/Basis - Ich Lieb Dich Immer Noch.mp3')
music.play()


>     #while not event.peek([KEYDOWN,KEYUP]):
>     while music.get_busy(): time.delay(1000)
>     #pygame.quit()

pygame.quit() is a call that is usually not needed. pygame will always
cleanup after itself when python exits. it's already commented out here,
but i just want to make sure everyone know there is no need to worry
about it.


> well, the example works fine (and plays the desired mp3), but if i uncomment
> the commented lines, i don't hear the mp3 anymore and i can't catch the
> keyboard. do i need to create a window/surface to be able to achieve this
> effect (this is only a command line script).

pygame's events are very tied to a display window. the pygame event
handling can only work with its own input window. if you want to
interact with the shell, you are best using python's other modules
and routines to deal with that.

as for not hearing anything when all uncommented, that is strange.
when uncommenting the final two "while" lines, the python syntax
is definetely strange though.
   while not event.peek([KEYDOWN,KEYUP]):
   while music.get_busy(): time.delay(1000)
this should be a syntax error if i'm not mistaken. (although your
use of event.peek() is corrent). like i mentioned, the event routines
won't really do anything until a display window is opened, so that
is not our solution.



i've attached a sample that plays an mp3 and stops when the user
pressed a key in the shell. it includes a little crossplatform
keypress checker. it works under windows, but i've not tried it
under linux, i expect it should work (at least with a little tweaking?)



#!/usr/bin/env python
"""Play back an mp3 file in a shell, allowing the
user to stop playback. An example pygame module.
Here's also my crude attempt at getting a
crossplatform keyboard hit test from the shells"""

import sys


#using commandline args would be nicer :]
#MUSICFILE = sys.argv[1]
MUSICFILE = 'E:/MP3/Basis - Ich Lieb Dich Immer Noch.mp3'


#import pygame and the extra music module
import pygame.time, pygame.music
from pygame.locals import *


#x-platform shell keyboard press testing
keypressed = None
if sys.platform == 'win32':
    import msvcrt
    keypressed = msvcrt.kbhit
    def keypressed():
        if msvcrt.kbhit():
            msvcrt.getch()
            return 1
else: #assume unix, sorry be/mac/others
    from select import select
    def keypressed():
        return len(select([sys.stdin], [], [], 0)[0])


#initialize music, will raise exception on error
pygame.music.init()

#load and play music, raises exception on error 
pygame.music.load(MUSICFILE)
pygame.music.play()

#give a little info
print 'Playing: "' + MUSICFILE + '"'
if keypressed:
    print 'Press Any Key To Stop'

#stop when music ends or we get input
try:
    while 1:
        if not pygame.music.get_busy(): break
        if keypressed and keypressed(): break
        pygame.time.delay(500)
except KeyboardInterrupt: pass #cleanly handle ctrl-c