2

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.

Passiday
  • 119
  • 2
  • 5

2 Answers2

2

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') 
p.set_media(m)
p.play() 
p.pause() 
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).

time-critical playback of short sound bits

Not doing any measurements, but:

  • play feels immediate (push enter, hear sample start)
  • pause seems to have a small but noticable lag, so likely in the range of a few tens to hundreds of milliseconds.

It is noteworthy that one could instantiate more than one player if that helps (and have them play samples at the same time).

Alternative: gstreamer got Python bindings and mp3 as well as ogg decoding.


Further reading:


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.

Ghanima
  • 15,958
  • 17
  • 65
  • 125
0

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.

paddyg
  • 335
  • 1
  • 12