How to play an audiofile with pyaudio?
38,551
Solution 1
The example seems pretty clear to me. You simply save the example as playwav.py call:
python playwav.py my_fav_wav.wav
The wave example with some extra comments:
import pyaudio
import wave
import sys
# length of data to read.
chunk = 1024
# validation. If a wave file hasn't been specified, exit.
if len(sys.argv) < 2:
print "Plays a wave file.\n\n" +\
"Usage: %s filename.wav" % sys.argv[0]
sys.exit(-1)
'''
************************************************************************
This is the start of the "minimum needed to read a wave"
************************************************************************
'''
# open the file for reading.
wf = wave.open(sys.argv[1], 'rb')
# create an audio object
p = pyaudio.PyAudio()
# open stream based on the wave object which has been input.
stream = p.open(format =
p.get_format_from_width(wf.getsampwidth()),
channels = wf.getnchannels(),
rate = wf.getframerate(),
output = True)
# read data (based on the chunk size)
data = wf.readframes(chunk)
# play stream (looping from beginning of file to the end)
while data != '':
# writing to the stream is what *actually* plays the sound.
stream.write(data)
data = wf.readframes(chunk)
# cleanup stuff.
stream.close()
p.terminate()
Solution 2
May be this small wrapper (warning: created on knees) of their example will help you to understand the meaning of code they wrote.
import pyaudio
import wave
import sys
class AudioFile:
chunk = 1024
def __init__(self, file):
""" Init audio stream """
self.wf = wave.open(file, 'rb')
self.p = pyaudio.PyAudio()
self.stream = self.p.open(
format = self.p.get_format_from_width(self.wf.getsampwidth()),
channels = self.wf.getnchannels(),
rate = self.wf.getframerate(),
output = True
)
def play(self):
""" Play entire file """
data = self.wf.readframes(self.chunk)
while data != '':
self.stream.write(data)
data = self.wf.readframes(self.chunk)
def close(self):
""" Graceful shutdown """
self.stream.close()
self.p.terminate()
# Usage example for pyaudio
a = AudioFile("1.wav")
a.play()
a.close()
Author by
JShoe
Updated on July 09, 2022Comments
-
JShoe almost 2 years
I do not understand the example material for pyaudio. It seems they had written an entire small program and it threw me off.
How do I just play a single audio file?
Format is not an issue, I just want to know the bare minimum code I need to play an audio file.
-
JShoe almost 13 yearsBut I the print stuff necessary?
-
JShoe almost 13 yearsAnd this is all I need? I don't has to have any example saved etc...? Just Pyaudio right? This is standalone?
-
Mikhail Churbanov almost 13 years@JShoe: Of course you need to save it to some *.py file (e.g. "somefile.py") and then run it with your python. And of course you need to have an audio file "1.wav" in your working dir.
-
JShoe almost 13 yearsWell right. By the way, what is the default working dir for both mac and windows?
-
Mikhail Churbanov almost 13 years@JShoe: Usually it is the place from where you call python. But you can specify absolute path to the file. That depends on what you really need to achieve.
-
Jonathan almost 9 yearsI get
Cannot connect to server request channel
jack server is not running or cannot be started
-
Jonathan almost 9 yearsDoes this take in account speed of the file?
-
cwallenpoole almost 9 years@JonathanLeaders You may wat to make that a new question
-
Jonathan almost 9 yearsApparently it plays regardless of the error, just at the wrong speed, so i went with pygame.mixer
-
SwiftStudier about 6 yearsWith Python 3 I had to replace the condition to
if len(data) > 0
; otherwise this loop turns to infinite -
mazunki over 5 years@SwiftStudier With Python you can solve the issue with
while data != b""
as well, following the original answer's method. Apparently, in Python 3, a binary string is a sequence of octets, while a standard string is a sequence of Unicode characters. Python2 ignores the b in front of a string, so I would suggest OP to edit his answer. tl, dr:b""==""
returns False. -
Gringo Suave over 4 years
while data:
works correctly, also needswf.close()
-
Gringo Suave over 4 yearsself.wf not closed.
-
jotadepicas about 3 yearsdata is not ascii, while should be != b'', with "b" prefix, otherwise it loops forever