MP3 playback is supported on most/many SAMD51 and nRF boards. It is not supported on any M0 boards. Check whether your board is supported by going to its download page on circuitpython.org and looking for "audiomp3" in the list of "built in modules available".

Compressed audio can be a nice alternative to uncompressed WAV files - especially when you have a small filesystem like that on many CircuitPython boards: those WAV files get pretty big fast! Thanks to the expiration of the MP3 patent pool, we can now include MP3 decoding as a core CircuitPython capability and you can even play multiple MP3s at a time!

CircuitPython supports any MP3 file you like. We've found that mono and stereo files from 32kbit/s to 128kbit/s work, with sample rates from 16kHz to 44.1kHz. The DAC output on the SAMD51 M4 is just 12-bit so there's not much point in using higher bitrates.

We're going to play one short mp3 file, wait for a button to be pressed, and then play a second short mp3 file. Use the same wiring as the other audio examples.

Because creating an MP3Decoder object takes a lot of memory, it's best to do this just once when your program starts, and then update the .file property of the MP3Decoder when you want to play a different file.  Otherwise, you may encounter the dreaded MemoryError.

Download these two mp3 files and copy them to your board:

Copy and paste the following code into code.py using your favorite editor, and save the file:

import board
import digitalio

from audiomp3 import MP3Decoder

try:
    from audioio import AudioOut
except ImportError:
    try:
        from audiopwmio import PWMAudioOut as AudioOut
    except ImportError:
        pass  # not always supported by every board!

button = digitalio.DigitalInOut(board.A1)
button.switch_to_input(pull=digitalio.Pull.UP)

# The listed mp3files will be played in order
mp3files = ["begins.mp3", "xfiles.mp3"]

# You have to specify some mp3 file when creating the decoder
mp3 = open(mp3files[0], "rb")
decoder = MP3Decoder(mp3)
audio = AudioOut(board.A0)

while True:
    for filename in mp3files:
        # Updating the .file property of the existing decoder
        # helps avoid running out of memory (MemoryError exception)
        decoder.file = open(filename, "rb")
        audio.play(decoder)
        print("playing", filename)

        # This allows you to do other things while the audio plays!
        while audio.playing:
            pass

        print("Waiting for button press to continue!")
        while button.value:
            pass
This guide was first published on Apr 02, 2018. It was last updated on Apr 02, 2018.
This page (CircuitPython MP3 Audio) was last updated on Sep 23, 2020.