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
|
#!/usr/bin/env python
"""A simple music player.
Use pygame.mixer.music to play an audio file. A window is
created to handle keyboard events for playback commands.
"""
from __future__ import print_function
import pygame
import pygame.freetype
from pygame.locals import *
import sys
import os
class Window(object):
"""The application's Pygame window
A Window instance manages the creation of and drawing to a
window. It is a singleton class. Only one instance can exist.
"""
instance = None
def __new__(cls, *args, **kwds):
"""Return an open Pygame window"""
if Window.instance is not None:
return Window.instance
self = object.__new__(cls)
pygame.display.init()
self.screen = pygame.display.set_mode((600, 400))
Window.instance = self
return self
def __init__(self, title):
pygame.display.set_caption(title)
self.screen.fill(Color('white'))
pygame.display.flip()
pygame.freetype.init()
self.font = pygame.freetype.Font(None, 20)
self.font.origin = True
self.ascender = int(self.font.get_sized_ascender() * 1.5)
self.descender = int(self.font.get_sized_descender() * 1.5)
self.line_height = self.ascender - self.descender
self.write_lines("'q', ESCAPE or close this window to quit\n"
"SPACE to play/pause\n"
"'r' to rewind\n"
"'f' to faid out over 5 seconds\n", 0)
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.close()
return False
def close(self):
pygame.display.quit()
Window.instance = None
def write_lines(self, text, line=0):
w, h = self.screen.get_size()
line_height = self.line_height
nlines = h // line_height
if line < 0:
line = nlines + line
for i, text_line in enumerate(text.split('\n'), line):
y = i * line_height + self.ascender
# Clear the line first.
self.screen.fill(Color('white'),
(0, i * line_height, w, line_height))
# Write new text.
self.font.render_to(self.screen, (15, y), text_line, Color('blue'))
pygame.display.flip()
def show_usage_message():
print("Usage: python playmus.py <file>")
print(" python -m pygame.examples.playmus <file>")
def main(file_path):
"""Play an audio file with pygame.mixer.music"""
with Window(file_path) as win:
win.write_lines('Loading ...', -1)
pygame.mixer.init(frequency=44100)
try:
paused = False
pygame.mixer.music.load(file_path)
# Make sure the event loop ticks over at least every 0.5 seconds.
pygame.time.set_timer(USEREVENT, 500)
pygame.mixer.music.play()
win.write_lines("Playing ...\n", -1)
while pygame.mixer.music.get_busy():
e = pygame.event.wait()
if e.type == pygame.KEYDOWN:
key = e.key
if key == K_SPACE:
if paused:
pygame.mixer.music.unpause()
paused = False
win.write_lines("Playing ...\n", -1)
else:
pygame.mixer.music.pause()
paused = True
win.write_lines("Paused ...\n", -1)
elif key == K_r:
pygame.mixer.music.rewind()
if paused:
win.write_lines("Rewound.", -1)
elif key == K_f:
win.write_lines("Faiding out ...\n", -1)
pygame.mixer.music.fadeout(5000)
# when finished get_busy() will return 0.
elif key in [K_q, K_ESCAPE]:
pygame.mixer.music.stop()
# get_busy() will now return 0.
elif e.type == QUIT:
pygame.mixer.music.stop()
# get_busy() will now return 0.
pygame.time.set_timer(USEREVENT, 0)
finally:
pygame.mixer.quit()
if __name__ == '__main__':
# Check the only command line argument, a file path
if len(sys.argv) != 2:
show_usage_message()
else:
main(sys.argv[1])
|