Play a Sound with Python [duplicate]
Asked Answered
S

10

118

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.

Spithead answered 20/11, 2008 at 23:40 Comment(2)
Very similar question to https://mcmap.net/q/120185/-play-audio-with-python.Paperback
Or this: #276766Sibella
H
30

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

s = Sound() 
s.read('sound.wav') 
s.play()
Houghton answered 21/11, 2008 at 1:11 Comment(4)
Snack doesn't seem to work with some embeded system environmentAugur
it also isn't available on Pypi :-(Huxham
Snack seems to be dead (latest update 2005 - ten years ago).Fritter
You can use 2to3.py to convert tkSnack.py to Python 3. Place tkSnack.py into the "Lib" folder in your Python directory. Then place the snacklib folder into the "tcl" folder in your Python directory. Tested on Python 3.2.Lesbos
I
121

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)

Indogermanic answered 22/11, 2008 at 18:43 Comment(9)
this is good - it seems easy to build a wrapper that would at least work for these two platformsSpithead
Avoid oss, it's old. I don't think I even have it installed anymore.Schlieren
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.Saccharase
I think this is the most straightforward approach. I still use Windows, and I think this solution acceptableKarlotta
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)Petua
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. pip install playsound. Enjoy!Dulci
I got a FileNotFoundError: [Errno 2] No such file or directory: '/dev/dsp', should this answer be opening another file on /dev?Labradorite
@ArtOfWarfare, playsound is definitely a super simple way of playing audio, but it has some problems on Windows (file path issues, not working inside Exception handlers). Can you please post an update for this useful tool?Rag
@Rag - I used to fix issues as people reported them, but I found that it'd always lead to regressions in other areas. So now I have a set of unit tests. If you can add a test that fails, I can try fixing it. I find that asking for this generally leads to people just ghosting. Apparently it's too much to ask for.Dulci
C
31

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.

Ceres answered 31/7, 2013 at 18:53 Comment(8)
Nice. Opening a whole lot of possibility knowing python had this featureKarlotta
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 expensiveEndothecium
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 LinuxPhilosophism
yeah, not working osx: sh: start: command not foundUnsteady
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...Myocarditis
This is terrible advice. It's slow, possibly insecure, and poor form.Dimitry
@Julio Marins You can also use os.system('afplay yourfilehere.mp3') on Mac.Oleograph
Please, PLEASE dont do this! It is the worst practice you could do. 1. Not cross-platform 2. subprocess.call 3. Just dontAnsate
H
30

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

s = Sound() 
s.read('sound.wav') 
s.play()
Houghton answered 21/11, 2008 at 1:11 Comment(4)
Snack doesn't seem to work with some embeded system environmentAugur
it also isn't available on Pypi :-(Huxham
Snack seems to be dead (latest update 2005 - ten years ago).Fritter
You can use 2to3.py to convert tkSnack.py to Python 3. Place tkSnack.py into the "Lib" folder in your Python directory. Then place the snacklib folder into the "tcl" folder in your Python directory. Tested on Python 3.2.Lesbos
C
19

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()
Cos answered 21/11, 2008 at 22:13 Comment(4)
only one problem with this example: the media file needs to be on the (python-) pathBegorra
That's fine - so long as you don't mind pyglet taking over the python process.Rhebarhee
pyglet.media.sources.riff.WAVEFormatException: Not a WAVE file Tremulous
@Begorra you can specify the absolute path of the file when using music=pyglet.media.load(path) instead of music = pyglet.resource.media(path)Waldman
A
10

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.

Avowal answered 29/9, 2011 at 5:42 Comment(2)
pygame doesn't use the correct sampling rate for the wave files I useFerd
Does not always work, it is sometimes throwing segmentation fault and etc. I don't recommend this.Tremulous
D
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 )
Dutyfree answered 20/11, 2008 at 23:45 Comment(1)
hehe, that works fine, but the snack example takes much less lines of code! i'm sure pymedia is more flexibleSpithead
U
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...

Unsubstantial answered 5/12, 2009 at 12:52 Comment(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...Gastronomy
T
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.

Teetotalism answered 5/12, 2009 at 14:53 Comment(0)
U
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)    
Unceremonious answered 10/3, 2013 at 14:35 Comment(0)
T
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.

Trudge answered 2/4, 2013 at 15:46 Comment(2)
link larsimmisch.github.io/pyalsaaudio/libalsaaudio.html#playwav-pyCreel
Does not work with Python 3.Tremulous

© 2022 - 2024 — McMap. All rights reserved.