I have made a simple game that I want to add sound effects to. I have the short clips and can get them

to work with the following command:

import os
os.startfile("filename")

It plays fine, but the problem is that it plays the file(s) with windows media player: effectively

taking the "focus" away from the main tk window (or any window associated with the game, for

that matter).

This is a problem because it takes away from the "flow/cohesion" of the game. I could just click

back on the tk window and resume playing, but I have spent a good amount of time enabling key

controls in my game(You can play the whole game with only the keyboard).

When each sound effect is played, the focused window is windows media player and whatever

keyboard input that is received is assigned to the newly opened program. Does anyone have any

solution of what I could do to address this?

I have identified several possible approches for a solution:
(1) Use Python modules for sound (e.g. winsound)
(2) Create multiple threads
(3) Search for method(s) on how to refocus the window (e.g. "window.grab_set()" method..??)
(4) Several program can be implemented (e.g. Pymedia, Pygame, PyAudio, Pyglet, etc.)

I think one of the main focuses here is that I may/may not want to use an external library for

sound playing? How could I embed these sound files(mostly .mp3, some .wav) in my program

without running a separate program to play them?

Any thoughts from personal experience and/or subjects that you can refer me to study up on

would be greatly appreciated, thanks.

I would recommend the Pygame Mixer. It works well with Tkinter.
In my experience modules like pySFML don't get along with Tkinter's event loop.

Here is an example ...

''' tk_pg_playmusic2.py
play a sound file with Tkinter using the module pygame
works with .wav .ogg .mid or .mp3 sound/music files
tested with Python27/Python33 and PyGame192
'''

import pygame as pg
from functools import partial
try:
    # Python2
    import Tkinter as tk
except ImportError:
    # Python3
    import tkinter as tk


def pg_play_music(music_file, volume=0.8):
    """
    stream music with mixer.music module in blocking manner
    this will stream the sound from disk while playing
    """
    # set up the mixer
    freq = 44100     # audio CD quality
    bitsize = -16    # unsigned 16 bit
    channels = 2     # 1 is mono, 2 is stereo
    buffer = 2048    # number of samples (experiment for good sound)
    pg.mixer.init(freq, bitsize, channels, buffer)

    pg.mixer.music.set_volume(volume)
    clock = pg.time.Clock()
    try:
        pg.mixer.music.load(music_file)
        print("Playing file %s" % music_file)
    except pg.error:
        print("File %s not found! (%s)" % \
            (music_file, pg.get_error()))
        return
    pg.mixer.music.play()
    # check if playback has finished
    while pg.mixer.music.get_busy():
        clock.tick(30)


root = tk.Tk()
# use width x height + x_offset + y_offset (no spaces!)
root.geometry("250x50+50+30")
root['bg'] = 'green'

# pick .wav .ogg .mid or .mp3 music/sound files you have in
# the working folder, otherwise give the full file path
#sound_file = "OhLaLa.mid"
sound_file = "Boing.mp3"
root.title(sound_file)
# set volume from 0 to 1.0
volume = 0.9
btn_text = "Play " + sound_file
cmd = partial(pg_play_music, sound_file, volume)
btn = tk.Button(root, text=btn_text, command=cmd)
btn.pack(padx=30, pady=5)

root.mainloop()

Edited 2 Years Ago by vegaseat

Another possibility ...

''' tk_SnackSound101.py
play a sound with Tkinter using tkSnack

needs Python module  tkSnack  developed at KTH in Stockholm, Sweden
free download: snack2210-py.zip  (Binary release for Windows)
from: http://www.speech.kth.se/snack/
extract then for instance copy
tkSnack.py to C:\Python27\Lib and the
folder snacklib to C:\Python27\tcl

I modified tkSnack.py to run with Python34 via utility 2to3.py
then copied the modified tkSnack.py to C:\Python34\Lib and the
original folder snacklib to C:\Python34\tcl

tested with Python27 and Python34
'''

try:
    # Python2
    import Tkinter as tk
except ImportError:
    # Python3
    import tkinter as tk
from functools import partial
import tkSnack

def play(sound_file):
    mysound = tkSnack.Sound()
    mysound.read(sound_file)
    mysound.play()


root = tk.Tk()
tkSnack.initializeSnack(root)

# pick .wav or .mp3 sound files you have in the
# working folder, otherwise give the full file path
#sound_file = 'Boing.mp3'
#sound_file = 'Boing2.wav'
sound_file = 'Bier1.mp3'

sf = ' Play {} '.format(sound_file)
tk.Button(root, text=sf, command=partial(play, sound_file)).pack()

root.mainloop()

A shorter version of the PyGame approach:

import pygame as pg
try:
    # Python2
    import Tkinter as tk
except ImportError:
    # Python3
    import tkinter as tk

def play():
    pg.mixer.music.play()

# pick .wav .ogg .mid or .mp3 music files you have in
# the working folder, otherwise give the full file path
music_file = 'Boing.wav'

pg.mixer.init()
pg.mixer.music.load(music_file)

root = tk.Tk()

tk.Button(root, text=' Play {} '.format(music_file), command=play).pack()

root.mainloop()

Let's hope that the pygame module hangs around a little longer and doesn't bite the dust like so any other third party Python modules.

Edited 2 Years Ago by HiHe

This article has been dead for over six months. Start a new discussion instead.