I have been trying to find a reliable method to play sound on my Pi Zero W, in Python. By default, Zero does not have audio output, but I have set up an I2S amp and speaker, following this guide: http://www.lucadentella.it/en/2017/04/26/raspberry-pi-zero-audio-output-via-i2s/

In general, the audio output is good. For example, I can use headless vlc player to stream audio from youtube or various internet radio stations.

But I was quite surprised the options are quite poor when you need to play sound from Python. Pyglet seems to be abandoned, at least the AVbin lib it relies on definately is. Launching an external player in separate process to play sounds might be acceptable for a "media player" application, but not reliable when you need to play little bits of sounds with precise timing. So a method more native to Python is sought.

Despite the load of heavy reference requirements, I've currently settled on pygame. But unfortunately it behaves bad, when the app has been running for long time. I've described symptoms here: https://stackoverflow.com/questions/54564107/pygame-mixer-music-ogg-playback-distorted-after-long-period-of-idling

If there are reliable alternative to pygame, I'd gladly use that. Currently I am stuck with pygame, that has this weird glitch, where the only workaround is to do secret re-initialisation at regular time intervals.

New contributor
Passiday is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.

On a Pi Zero with a recent Raspbian and Python 3.6 I tried a few things1 that didn't work that well out of the box and finally I settled for vlc. It's using a USB soundcard and alsa but it's likely to work with an I2S soundcard as well.

Installed vlc along with approx. 150 other packages and Python-bindings for vlc via

sudo apt-get install vlc 
sudo pip3 install python-vlc

Playing from Python worked straight forward:

import vlc
instance = vlc.Instance('--aout=alsa')
p = Instance.media_player_new()
m = Instance.media_new('something.mp3') 
vlc.libvlc_audio_set_volume(p, volume)  # volume 0..100

Didn't do any long time running tests though (feel free to post another answer about that if going that way).

1 Installed ffmpeg along with sdl2 and ffpyplayer - didn't get it to play, both using pip3 and installing from github. Checked ffmpeg-python which in fact worked for cool stuff like creating video overlays and converting audio and video, didn't seem to be the right choice for simply playing audio. Tried pyglet which needed avbin for which I didn't find a source or an ARM binary. Tested pygame that didn't work with sdl2 - and I did not want to install another version of the sdl.

  • For media-player style song playback, I tested running vlc in subprocess, and killing the subprocess if I want to stop the playback. Perhaps very brutal, but appears to work without big problems. But I am looking for time-critical playback of short sound bits (for example percussions in specific pattern). An external player is not viable for this purpose. Luckily, my installation of pygame generally works, but with that stupid degradation when mixer is idle for long time. – Passiday 23 hours ago
  • Fair enough, but note that the approach as outlined in my answer is not creating a new subprocess each time but instantiates a player once and reuses that. This may or may not behave differently with respect to any delays. I would guess that you're the best candidate to measure that with your setup and according to your requirements. Feel free to give us an update about your findings. – Ghanima 23 hours ago

I used mpg321 in subprocess. https://www.raspberrypi.org/forums/viewtopic.php?f=32&t=231250&p=1416572&hilit=mpg321#p1416572 it's possible to pipe info in and out (for instance fft for graphics, volume, pause etc.

  • I am looking for a solution that is capable of real-time sound effect playback. Anything that relies on external player, mpg321 or vlc, will have noticable variable-length delay that makes it unreliable for such purpose. – Passiday 23 hours ago

Your Answer

Passiday is a new contributor. Be nice, and check out our Code of Conduct.

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.