How can I play audio (it would be like a 1 second sound) from a Python script?
It would be best if it was platform independent, but firstly it needs to work on a Mac.
I know I could just execute the afplay file.mp3
command from within Python, but is it possible to do it in raw Python? I would also be better if it didn't rely on external libraries.
To play a notification sound using python, call a music player, such as vlc. VLC prompted me to use its commandline version, cvlc, instead.
from subprocess import call
call(["cvlc", "--play-and-exit", "myNotificationTone.mp3"])
It requires vlc to be preinstalled on the device. Tested on Linux(Ubuntu 16.04 LTS); Running Python 3.5.
This is the easiest & best iv'e found. It supports Linux/pulseaudio, Mac/coreaudio, and Windows/WASAPI.
import soundfile as sf
import soundcard as sc
default_speaker = sc.default_speaker()
samples, samplerate = sf.read('bell.wav')
default_speaker.play(samples, samplerate=samplerate)
See https://github.com/bastibe/PySoundFile and https://github.com/bastibe/SoundCard for tons of other super-useful features.
Your best bet is probably to use pygame/SDL. It's an external library, but it has great support across platforms.
pygame.mixer.init()
pygame.mixer.music.load("file.mp3")
pygame.mixer.music.play()
You can find more specific documentation about the audio mixer support in the pygame.mixer.music documentation
Also on OSX - from SO, using OSX's afplay command:
import subprocess
subprocess.call(["afplay", "path/to/audio/file"])
UPDATE: All this does is specify how to do what the OP wanted to avoid doing in the first place. I guess I posted this here because what OP wanted to avoid was the info I was looking for. Whoops.
import subprocess
If the wav file IS in the directory of the python script:
f = './mySound.wav'
subprocess.Popen(['aplay','-q',f)
If the wav file IS NOT in the directory of the python script:
f = 'mySound.wav'
subprocess.Popen(['aplay','-q', 'wav/' + f)
If you want to learn more about aplay:
man aplay
Try playsound which is a Pure Python, cross platform, single function module with no dependencies for playing sounds.
Install via pip:
$ pip install playsound
Once you've installed, you can use it like this:
from playsound import playsound
playsound('/path/to/a/sound/file/you/want/to/play.mp3')
Install playsound
package using :
pip install playsound
Usage:
from playsound import playsound
playsound("file location\audio.p3")
Simply You can do it with the help of cvlc- I did it in this way:
import os
os.popen2("cvlc /home/maulo/selfProject/task.mp3 --play-and-exit")
/home/maulo/selfProject/task.mp3. This is the location of my mp3 file. with the help of "--play-and-exit" you will be able to play again the sound without ending the vlc process.
Sorry for the late reply, but I think this is a good place to advertise my library ...
AFAIK, the standard library has only one module for playing audio: ossaudiodev. Sadly, this only works on Linux and FreeBSD.
UPDATE: There is also winsound, but obviously this is also platform-specific.
For something more platform-independent, you'll need to use an external library.
My recommendation is the sounddevice module (but beware, I'm the author).
The package includes the pre-compiled PortAudio library for Mac OS X and Windows, and can be easily installed with:
pip install sounddevice --user
It can play back sound from NumPy arrays, but it can also use plain Python buffers (if NumPy is not available).
To play back a NumPy array, that's all you need (assuming that the audio data has a sampling frequency of 44100 Hz):
import sounddevice as sd
sd.play(myarray, 44100)
For more details, have a look at the documentation.
It cannot read/write sound files, you'll need a separate library for that.
Pypi has a list of modules for python in music. My favorite would be jython because it has more resources and libraries for music. As example of of code to play a single note from the textbook:
# playNote.py
# Demonstrates how to play a single note.
from music import * # import music library
note = Note(C4, HN) # create a middle C half note
Play.midi(note) # and play it!
It's Simple. I did it this way.
For a wav file
from IPython.display import Audio
from scipy.io.wavfile import read
fs, data = read('StarWars60.wav', mmap=True) # fs - sampling frequency
data = data.reshape(-1, 1)
Audio(data = data[:, 0], rate = fs)
For mp3 file
import IPython.display import Audio
Audio('audio_file_name.mp3')
import subprocess
If the wav file IS in the directory of the python script:
f = './mySound.wav'
subprocess.Popen(['aplay','-q',f)
If the wav file IS NOT in the directory of the python script:
f = 'mySound.wav'
subprocess.Popen(['aplay','-q', 'wav/' + f)
If you want to learn more about aplay:
man aplay
Aaron's answer appears to be about 10x more complicated than necessary. Just do this if you only need an answer that works on OS X:
from AppKit import NSSound
sound = NSSound.alloc()
sound.initWithContentsOfFile_byReference_('/path/to/file.wav', True)
sound.play()
One thing... this returns immediately. So you might want to also do this, if you want the call to block until the sound finishes playing.
from time import sleep
sleep(sound.duration())
Edit: I took this function and combined it with variants for Windows and Linux. The result is a pure python, cross platform module with no dependencies called playsound. I've uploaded it to pypi.
pip install playsound
Then run it like this:
from playsound import playsound
playsound('/path/to/file.wav', block = False)
MP3 files also work on OS X. WAV should work on all platforms. I don't know what other combinations of platform/file format do or don't work - I haven't tried them yet.
I recently made my Music Player support all audio files locally. I did this by figuring out a way to use the vlc python module and also the VLC dll files. You can check it out: https://github.com/elibroftw/music-caster/blob/master/audio_player.py
Install playsound
package using :
pip install playsound
Usage:
from playsound import playsound
playsound("file location\audio.p3")
Sorry for the late reply, but I think this is a good place to advertise my library ...
AFAIK, the standard library has only one module for playing audio: ossaudiodev. Sadly, this only works on Linux and FreeBSD.
UPDATE: There is also winsound, but obviously this is also platform-specific.
For something more platform-independent, you'll need to use an external library.
My recommendation is the sounddevice module (but beware, I'm the author).
The package includes the pre-compiled PortAudio library for Mac OS X and Windows, and can be easily installed with:
pip install sounddevice --user
It can play back sound from NumPy arrays, but it can also use plain Python buffers (if NumPy is not available).
To play back a NumPy array, that's all you need (assuming that the audio data has a sampling frequency of 44100 Hz):
import sounddevice as sd
sd.play(myarray, 44100)
For more details, have a look at the documentation.
It cannot read/write sound files, you'll need a separate library for that.
If you're on OSX, you can use the "os" module or "subprocess" etc. to call the OSX "play" command. From the OSX shell, it looks like
play "bah.wav"
It starts to play in about a half-second on my machine.
You can see this: http://www.speech.kth.se/snack/
s = Sound()
s.read('sound.wav')
s.play()
Try sounddevice
If you don't have the module enter
pip install sounddevice
in your terminal.
Then in your preferred Python script (I use Juypter), enter
import sounddevice as sd
sd.play(audio, sr)
will play what you want through Python
The best way to get the audio and samplerate you want is with the librosa module. Enter this in terminal if you don't have the librosa module.
pip install librosa
audio, sr = librosa.load('wave_file.wav')
Whatever wav file you want to play, just make sure it's in the same directory as your Python script. This should allow you to play your desired wav file through Python
Cheers, Charlie
P.S.
Once audio is a "librosa" data object, Python sees it as a numpy array. As an experiment, try playing a long (try 20,000 data points) thing of a random numpy array. Python should play it as white noise. The sounddevice module plays numpy arrays and lists as well.
Your best bet is probably to use pygame/SDL. It's an external library, but it has great support across platforms.
pygame.mixer.init()
pygame.mixer.music.load("file.mp3")
pygame.mixer.music.play()
You can find more specific documentation about the audio mixer support in the pygame.mixer.music documentation
If you're on OSX, you can use the "os" module or "subprocess" etc. to call the OSX "play" command. From the OSX shell, it looks like
play "bah.wav"
It starts to play in about a half-second on my machine.
In a Colab notebook you can do:
from IPython.display import Audio
Audio(waveform, Rate=16000)
Try PySoundCard which uses PortAudio for playback which is available on many platforms. In addition, it recognizes "professional" sound devices with lots of channels.
Here a small example from the Readme:
from pysoundcard import Stream
"""Loop back five seconds of audio data."""
fs = 44100
blocksize = 16
s = Stream(samplerate=fs, blocksize=blocksize)
s.start()
for n in range(int(fs*5/blocksize)):
s.write(s.read(blocksize))
s.stop()
Your best bet is probably to use pygame/SDL. It's an external library, but it has great support across platforms.
pygame.mixer.init()
pygame.mixer.music.load("file.mp3")
pygame.mixer.music.play()
You can find more specific documentation about the audio mixer support in the pygame.mixer.music documentation
Take a look at Simpleaudio, which is a relatively recent and lightweight library for this purpose:
> pip install simpleaudio
Then:
import simpleaudio as sa
wave_obj = sa.WaveObject.from_wave_file("path/to/file.wav")
play_obj = wave_obj.play()
play_obj.wait_done()
Make sure to use uncompressed 16 bit PCM files.
This is the easiest & best iv'e found. It supports Linux/pulseaudio, Mac/coreaudio, and Windows/WASAPI.
import soundfile as sf
import soundcard as sc
default_speaker = sc.default_speaker()
samples, samplerate = sf.read('bell.wav')
default_speaker.play(samples, samplerate=samplerate)
See https://github.com/bastibe/PySoundFile and https://github.com/bastibe/SoundCard for tons of other super-useful features.
In a Colab notebook you can do:
from IPython.display import Audio
Audio(waveform, Rate=16000)
You can see this: http://www.speech.kth.se/snack/
s = Sound()
s.read('sound.wav')
s.play()
Try sounddevice
If you don't have the module enter
pip install sounddevice
in your terminal.
Then in your preferred Python script (I use Juypter), enter
import sounddevice as sd
sd.play(audio, sr)
will play what you want through Python
The best way to get the audio and samplerate you want is with the librosa module. Enter this in terminal if you don't have the librosa module.
pip install librosa
audio, sr = librosa.load('wave_file.wav')
Whatever wav file you want to play, just make sure it's in the same directory as your Python script. This should allow you to play your desired wav file through Python
Cheers, Charlie
P.S.
Once audio is a "librosa" data object, Python sees it as a numpy array. As an experiment, try playing a long (try 20,000 data points) thing of a random numpy array. Python should play it as white noise. The sounddevice module plays numpy arrays and lists as well.
Try playsound which is a Pure Python, cross platform, single function module with no dependencies for playing sounds.
Install via pip:
$ pip install playsound
Once you've installed, you can use it like this:
from playsound import playsound
playsound('/path/to/a/sound/file/you/want/to/play.mp3')
Mac OS I tried a lot of codes but just this works on me
import pygame
import time
pygame.mixer.init()
pygame.init()
pygame.mixer.music.load('fire alarm sound.mp3') *On my project folder*
i = 0
while i<10:
pygame.mixer.music.play(loops=10, start=0.0)
time.sleep(10)*to protect from closing*
pygame.mixer.music.set_volume(10)
i = i + 1
For those who use Linux and the other packages haven't worked on MP3 files, audioplayer
worked fine for me:
https://pypi.org/project/audioplayer/
from audioplayer import AudioPlayer<br>
AudioPlayer("path/to/somemusic.mp3").play(block=True)
It is possible to play audio in OS X without any 3rd party libraries using an analogue of the following code. The raw audio data can be input with wave_wave.writeframes. This code extracts 4 seconds of audio from the input file.
import wave
import io
from AppKit import NSSound
wave_output = io.BytesIO()
wave_shell = wave.open(wave_output, mode="wb")
file_path = 'SINE.WAV'
input_audio = wave.open(file_path)
input_audio_frames = input_audio.readframes(input_audio.getnframes())
wave_shell.setnchannels(input_audio.getnchannels())
wave_shell.setsampwidth(input_audio.getsampwidth())
wave_shell.setframerate(input_audio.getframerate())
seconds_multiplier = input_audio.getnchannels() * input_audio.getsampwidth() * input_audio.getframerate()
wave_shell.writeframes(input_audio_frames[second_multiplier:second_multiplier*5])
wave_shell.close()
wave_output.seek(0)
wave_data = wave_output.read()
audio_stream = NSSound.alloc()
audio_stream.initWithData_(wave_data)
audio_stream.play()
It's Simple. I did it this way.
For a wav file
from IPython.display import Audio
from scipy.io.wavfile import read
fs, data = read('StarWars60.wav', mmap=True) # fs - sampling frequency
data = data.reshape(-1, 1)
Audio(data = data[:, 0], rate = fs)
For mp3 file
import IPython.display import Audio
Audio('audio_file_name.mp3')
Pypi has a list of modules for python in music. My favorite would be jython because it has more resources and libraries for music. As example of of code to play a single note from the textbook:
# playNote.py
# Demonstrates how to play a single note.
from music import * # import music library
note = Note(C4, HN) # create a middle C half note
Play.midi(note) # and play it!
To play a notification sound using python, call a music player, such as vlc. VLC prompted me to use its commandline version, cvlc, instead.
from subprocess import call
call(["cvlc", "--play-and-exit", "myNotificationTone.mp3"])
It requires vlc to be preinstalled on the device. Tested on Linux(Ubuntu 16.04 LTS); Running Python 3.5.
I recently made my Music Player support all audio files locally. I did this by figuring out a way to use the vlc python module and also the VLC dll files. You can check it out: https://github.com/elibroftw/music-caster/blob/master/audio_player.py
Mac OS I tried a lot of codes but just this works on me
import pygame
import time
pygame.mixer.init()
pygame.init()
pygame.mixer.music.load('fire alarm sound.mp3') *On my project folder*
i = 0
while i<10:
pygame.mixer.music.play(loops=10, start=0.0)
time.sleep(10)*to protect from closing*
pygame.mixer.music.set_volume(10)
i = i + 1
It is possible to play audio in OS X without any 3rd party libraries using an analogue of the following code. The raw audio data can be input with wave_wave.writeframes. This code extracts 4 seconds of audio from the input file.
import wave
import io
from AppKit import NSSound
wave_output = io.BytesIO()
wave_shell = wave.open(wave_output, mode="wb")
file_path = 'SINE.WAV'
input_audio = wave.open(file_path)
input_audio_frames = input_audio.readframes(input_audio.getnframes())
wave_shell.setnchannels(input_audio.getnchannels())
wave_shell.setsampwidth(input_audio.getsampwidth())
wave_shell.setframerate(input_audio.getframerate())
seconds_multiplier = input_audio.getnchannels() * input_audio.getsampwidth() * input_audio.getframerate()
wave_shell.writeframes(input_audio_frames[second_multiplier:second_multiplier*5])
wave_shell.close()
wave_output.seek(0)
wave_data = wave_output.read()
audio_stream = NSSound.alloc()
audio_stream.initWithData_(wave_data)
audio_stream.play()
Take a look at Simpleaudio, which is a relatively recent and lightweight library for this purpose:
> pip install simpleaudio
Then:
import simpleaudio as sa
wave_obj = sa.WaveObject.from_wave_file("path/to/file.wav")
play_obj = wave_obj.play()
play_obj.wait_done()
Make sure to use uncompressed 16 bit PCM files.
In pydub we've recently opted to use ffplay (via subprocess) from the ffmpeg suite of tools, which internally uses SDL.
It works for our purposes – mainly just making it easier to test the results of pydub code in interactive mode – but it has it's downsides, like causing a new program to appear in the dock on mac.
I've linked the implementation above, but a simplified version follows:
import subprocess
def play(audio_file_path):
subprocess.call(["ffplay", "-nodisp", "-autoexit", audio_file_path])
The -nodisp
flag stops ffplay from showing a new window, and the -autoexit
flag causes ffplay to exit and return a status code when the audio file is done playing.
edit: pydub now uses pyaudio for playback when it's installed and falls back to ffplay to avoid the downsides I mentioned. The link above shows that implementation as well.
For those who use Linux and the other packages haven't worked on MP3 files, audioplayer
worked fine for me:
https://pypi.org/project/audioplayer/
from audioplayer import AudioPlayer<br>
AudioPlayer("path/to/somemusic.mp3").play(block=True)
Your best bet is probably to use pygame/SDL. It's an external library, but it has great support across platforms.
pygame.mixer.init()
pygame.mixer.music.load("file.mp3")
pygame.mixer.music.play()
You can find more specific documentation about the audio mixer support in the pygame.mixer.music documentation
In pydub we've recently opted to use ffplay (via subprocess) from the ffmpeg suite of tools, which internally uses SDL.
It works for our purposes – mainly just making it easier to test the results of pydub code in interactive mode – but it has it's downsides, like causing a new program to appear in the dock on mac.
I've linked the implementation above, but a simplified version follows:
import subprocess
def play(audio_file_path):
subprocess.call(["ffplay", "-nodisp", "-autoexit", audio_file_path])
The -nodisp
flag stops ffplay from showing a new window, and the -autoexit
flag causes ffplay to exit and return a status code when the audio file is done playing.
edit: pydub now uses pyaudio for playback when it's installed and falls back to ffplay to avoid the downsides I mentioned. The link above shows that implementation as well.
Aaron's answer appears to be about 10x more complicated than necessary. Just do this if you only need an answer that works on OS X:
from AppKit import NSSound
sound = NSSound.alloc()
sound.initWithContentsOfFile_byReference_('/path/to/file.wav', True)
sound.play()
One thing... this returns immediately. So you might want to also do this, if you want the call to block until the sound finishes playing.
from time import sleep
sleep(sound.duration())
Edit: I took this function and combined it with variants for Windows and Linux. The result is a pure python, cross platform module with no dependencies called playsound. I've uploaded it to pypi.
pip install playsound
Then run it like this:
from playsound import playsound
playsound('/path/to/file.wav', block = False)
MP3 files also work on OS X. WAV should work on all platforms. I don't know what other combinations of platform/file format do or don't work - I haven't tried them yet.
Simply You can do it with the help of cvlc- I did it in this way:
import os
os.popen2("cvlc /home/maulo/selfProject/task.mp3 --play-and-exit")
/home/maulo/selfProject/task.mp3. This is the location of my mp3 file. with the help of "--play-and-exit" you will be able to play again the sound without ending the vlc process.
Try PySoundCard which uses PortAudio for playback which is available on many platforms. In addition, it recognizes "professional" sound devices with lots of channels.
Here a small example from the Readme:
from pysoundcard import Stream
"""Loop back five seconds of audio data."""
fs = 44100
blocksize = 16
s = Stream(samplerate=fs, blocksize=blocksize)
s.start()
for n in range(int(fs*5/blocksize)):
s.write(s.read(blocksize))
s.stop()
Source: Stackoverflow.com