110

What's the easiest way to play a sound file (.wav) in Python? By easiest I mean both most platform independent and requiring the least dependencies. pygame is certainly an option, but it seems overkill for just sound.

Claudiu
  • 206,738
  • 150
  • 445
  • 651

10 Answers10

115

For Windows, you can use winsound. It's built in

import winsound

winsound.PlaySound('sound.wav', winsound.SND_FILENAME)

You should be able to use ossaudiodev for linux:

from wave import open as waveOpen
from ossaudiodev import open as ossOpen
s = waveOpen('tada.wav','rb')
(nc,sw,fr,nf,comptype, compname) = s.getparams( )
dsp = ossOpen('/dev/dsp','w')
try:
  from ossaudiodev import AFMT_S16_NE
except ImportError:
  from sys import byteorder
  if byteorder == "little":
    AFMT_S16_NE = ossaudiodev.AFMT_S16_LE
  else:
    AFMT_S16_NE = ossaudiodev.AFMT_S16_BE
dsp.setparameters(AFMT_S16_NE, nc, fr)
data = s.readframes(nf)
s.close()
dsp.write(data)
dsp.close()

(Credit for ossaudiodev: Bill Dandreta http://mail.python.org/pipermail/python-list/2004-October/288905.html)

Basj
  • 29,668
  • 65
  • 241
  • 451
orestis
  • 13,845
  • 4
  • 23
  • 24
  • this is good - it seems easy to build a wrapper that would at least work for these two platforms – Claudiu Nov 22 '08 at 21:02
  • 2
    Avoid oss, it's old. I don't think I even have it installed anymore. – Jeffrey Aylesworth Jan 30 '10 at 19:47
  • 8
    OSS isn't old. It's just that the Linux people have chosen to replace it with ALSA for reasons that have more to do with politics and ego than with software development. Regardless, OSS remains the only cross-platforn UNIX sound system, and will probably remain to be in the foreseeable future. – Martin Tournoij Jul 13 '11 at 21:08
  • I think this is the most straightforward approach. I still use Windows, and I think this solution acceptable – swdev Oct 26 '13 at 15:26
  • this answer continues to work on Python 3 on Windows and on Linux (if you load `snd-pcm-oss` kernel module: `sudo modprobe snd-pcm-oss`) – jfs Jul 02 '15 at 12:47
  • 4
    I started with this answer, added in a variant that also works on OS X, and uploaded it as a pure python, cross platform, single function module to pypi, called [playsound](https://pypi.python.org/pypi/playsound/1.0.0). `pip install playsound`. Enjoy! – ArtOfWarfare Jan 25 '16 at 04:42
  • 2
    I got a FileNotFoundError: [Errno 2] No such file or directory: '/dev/dsp', should this answer be opening another file on /dev? – lapisdecor Feb 24 '17 at 03:41
30

The Snack Sound Toolkit can play wav, au and mp3 files.

s = Sound() 
s.read('sound.wav') 
s.play()
csexton
  • 21,619
  • 15
  • 51
  • 53
29

This seems ridiculous and far fetched but you could always use Windows (or whatever OS you prefer) to manage the sound for you!

import os
os.system("start C:/thepathyouwant/file")

Simple, no extensions, somewhat slow and junky, but working.

Matthew Murdoch
  • 28,946
  • 26
  • 89
  • 125
Fillip
  • 379
  • 3
  • 2
  • 2
    Nice. Opening a whole lot of possibility knowing python had this feature – swdev Oct 26 '13 at 15:12
  • 14
    this isn't a feature of python, it is a call to a process in the OS. it isn't cross platform, and it is terribly expensive – ealfonso May 19 '14 at 01:03
  • 21
    Cross platform: `import sys` `from subprocess import call` `if sys.platform == 'linux2':` `call(["xdg-open","sound.mp3"])` `elif sys.platform == 'darwin':` `call(["afplay","sound.mp3"])` What's expensive is wasting time on all these malfunctioning sound libraries tbh. Substituting `xdg-open` for `mpg123` will give `afplay` functionality on Linux – Louis Maddox Jul 09 '14 at 12:00
  • 1
    yeah, not working osx: `sh: start: command not found` – Julio Marins Mar 22 '16 at 02:11
  • 10
    This is really bad because (under windows) I could have made the default action for audio files be open in audio editor. The sound would never play and for some odd reason my audio editor would open all the time... – RedX Nov 06 '16 at 22:28
  • 1
    This is terrible advice. It's slow, possibly insecure, and poor form. – Woodrow Douglass Jul 09 '18 at 15:40
  • @Julio Marins You can also use `os.system('afplay yourfilehere.mp3')` on Mac. – Nosrep Mar 15 '19 at 18:07
  • Please, PLEASE dont do this! It is the worst practice you could do. 1. Not cross-platform 2. subprocess.call 3. Just dont – Niwla23 Jun 13 '20 at 11:47
18

Definitely use Pyglet for this. It's kind of a large package, but it is pure python with no extension modules. That will definitely be the easiest for deployment. It's also got great format and codec support.

import pyglet

music = pyglet.resource.media('music.mp3')
music.play()

pyglet.app.run()
Peter Shinners
  • 3,466
  • 22
  • 23
  • 2
    only one problem with this example: the media file needs to be on the (python-) path – Steen Jun 02 '09 at 10:12
  • 2
    That's fine - so long as you don't mind pyglet taking over the python process. – Tom Jun 20 '14 at 00:09
  • `pyglet.media.sources.riff.WAVEFormatException: Not a WAVE file ` – Schütze Aug 09 '18 at 01:50
  • @Steen you can specify the absolute path of the file when using `music=pyglet.media.load(path)` instead of `music = pyglet.resource.media(path)` – Sayyor Y Jan 25 '21 at 06:07
8

After the play() command add a delay of say 10 secs or so, it'll work

import pygame

import time

pygame.init()

pygame.mixer.music.load("test.wav")

pygame.mixer.music.play()

time.sleep(10)

This also plays .mp3 files.

Bo Persson
  • 86,087
  • 31
  • 138
  • 198
ramkumar
  • 89
  • 1
  • 1
6

pyMedia's sound example does just that. This should be all you need.

import time, wave, pymedia.audio.sound as sound
f= wave.open( 'YOUR FILE NAME', 'rb' )
sampleRate= f.getframerate()
channels= f.getnchannels()
format= sound.AFMT_S16_LE
snd= sound.Output( sampleRate, channels, format )
s= f.readframes( 300000 )
snd.play( s )
Rizwan Kassim
  • 7,421
  • 3
  • 22
  • 33
  • hehe, that works fine, but the snack example takes much less lines of code! i'm sure pymedia is more flexible – Claudiu Nov 22 '08 at 20:07
3

I like pygame, and the command below should work:

pygame.init()
pygame.mixer.Sound('sound.wav').play()

but it doesn't on either of my computers, and there is limited help on the subject out there. edit: I figured out why the pygame sound isn't working for me, it's not loading most sounds correctly, the 'length' attribute is ~0.0002 when I load them. maybe loading them using something other than mygame will get it morking more generally.

with pyglet I'm getting a resource not found error Using the above example, wigh both relative and full paths to the files.

using pyglet.media.load() instead of pyglet.resource.media() lets me load the files.

but sound.play() only plays the first fraction of a second of the file, unless I run pyglet.app.run() which blocks everything else...

MatrixFrog
  • 20,873
  • 10
  • 56
  • 88
suki
  • 39
  • 2
  • 1
    From the manual: "The mixer module must be initialized like other pygame modules, but it has some extra conditions. The pygame.mixer.init - initialize the mixer module function takes several optional arguments to control the playback rate and sample size. Pygame will default to reasonable values, but pygame cannot perform Sound resampling, so the mixer should be initialized to match the values of your audio resources." - that might be why your resources load incorrectly... – Dominic Scheirlinck Mar 13 '12 at 08:42
2

I just released a simple python wrapper around sox that will play a sound with Python. It's very easy to install as you need Python 2.6 or greater, sox (easy to get binaries for most architectures) and the wrapper ( https://github.com/standarddeviant/sound4python ). If you don't have sox, go here: http://sourceforge.net/projects/sox/files/sox/

You would play audio with it by:

from sound4python import sound
import random
a = []
for idx in xrange(1*16000):
    a.append(random.randint(-16384,16384))
sound(a)

Keep in mind, the only parts actually involved in playing audio are just these:

from sound4python import sound
...
sound(a)    
Dave C
  • 945
  • 10
  • 13
2

wxPython has support for playing wav files on Windows and Unix - I am not sure if this includes Macs. However it only support wav files as far as I can tell - it does not support other common formats such as mp3 or ogg.

Dave Kirby
  • 23,068
  • 5
  • 60
  • 79
1

For Linux user, if low level pcm data manipulation is needed, try alsaaudio module. There is a playwav.py example inside the package too.

GBY
  • 1,010
  • 1
  • 10
  • 12