Raspberry Radio - Use text-to-speech to turn your Raspberry Pi into a virtual DJ

What is Raspberry Radio?

A photo of a bright-red, plastic, paint-splattered radio. Raspberry Radio turns your Raspberry Pi into a virtual DJ. It uses Python text-to-speech (pyttsx3) to tell you something about the songs before playing them, and even reads out the news and weather every half hour or so. To do this, it uses my newsreader program to download the current weather and headlines.

Using Raspberry Radio, you benefit from the friendly company and insight that a DJ gives you, while maintaining control over the songs that make it to the playlist.

I wrote about Raspberry Radio for The MagPi magazine, issue 122. The code in the magazine was shortened in a couple of places to fit the magazine and make it easier to read. I've posted a slightly longer version of the code here.

The main differences are:

  • Additional ways for the DJ to introduce the tracks.
  • Extra code that randomly tags a short, enthusiastic phrase on the end of the DJ's saying to add some variety.

UPDATE: You can now download both parts of my Raspberry Radio tutorial in a single PDF here.

What you'll need

In the same folder as raspberry_radio.py, you need to have:

  • rr_newsreader.py - my newsreader program, which downloads the news. This featured in issue 121 of The MagPi.
  • A subfolder containing your MP3 files, called music. It's okay if there are subfolders in there, similar to the way your iTunes folder is organised. I don't recommend pointing Raspberry Radio at your entire iTunes folder, though, because indexing takes time. Feel free to download my album Artificial if you don't have any MP3s.
  • A subfolder containing jingles, called jingles. Download some great jingles here.
  • A news jingle called news_jingle.mp3. You can download my news jingle from my sound effects pack Press Play. I also like this one, but you'll need to trim the silence off the end.

Raspberry Radio uses a Display-O-Tron HAT to display the artist and song name, like a DAB radio would. If you don't have a Display-O-Tron, you can delete the instructions where indicated, and the program will work fine.

A photo of my Raspberry Radio setup, with white ipod speakers connected to the Raspberry Pi, and a Display-O-Tron HAT showing the artist and song title.

A photo of my Raspberry Radio setup, with white iPod speakers connected to the Raspberry Pi, and a Display-O-Tron HAT showing the artist and song title.

Installing the dependencies

You'll need to install the required libraries. Open a terminal window and then enter the following instructions:

pip install pyttsx3
pip install tinytag
pip install playsound
pip install requests
pip install feedparser

Download the Python code for Raspberry Radio

Here's the program code. Remember you also need to have rr_newsreader.py in the same folder as this.

# Raspberry Radio from The MagPi by Sean McManus
# www.sean.co.uk

import rr_newsreader, random, pyttsx3, os, sys
from playsound import playsound
from tinytag import TinyTag
import dot3k.lcd as lcd # Remove if not using Display-O-Tron

def output(text):
    print(text)
    voice.say(text)
    voice.runAndWait()

def broadcast_news_and_weather():
    playsound('news_jingle.mp3')
    date = rr_newsreader.get_date()
    output(date)
    news_headlines = rr_newsreader.get_news()
    for line in news_headlines:
        output(line)
    weather_report, temperature = rr_newsreader.get_weather()
    output(weather_report)

def index_directory(path, songs, perform_checks):
    print("Processing directory:", path)
    for entry in os.listdir(path):
        path_plus_entry = os.path.join(path, entry)
        if os.path.isdir(path_plus_entry):
            index_directory(path_plus_entry, songs, perform_checks)
        elif entry.endswith('.mp3'):  # Supported formats
            tag = TinyTag.get(path_plus_entry)
            if perform_checks == False or \
                  (tag.title is not None and \
                   tag.genre not in ["Books & Spoken", "Christmas"] and \
                   tag.duration < 6000 and \
                   "live" not in tag.album and \
                   "live" not in tag.title):
                songs.append(path_plus_entry)
                print("Track added:", tag.title, "by", tag.artist, "from", tag.album)
    return songs

def play_songs(number_of_songs):
    for _ in range(number_of_songs):  
        if random.random() > 0.4:
            jingle_to_play = random.choice(jingles)
            playsound(jingle_to_play)
        song_to_play = random.choice(songs)
        tag = TinyTag.get(song_to_play)
        dj_says = random.choice(
            [
                f"What were you doing in {tag.year}? Here's what {tag.artist} was up to.",
                f"Let's hear some {tag.artist}.",
                f"This one's called {tag.title}.",
                f"I love {tag.artist}! Let's hear one from {tag.year}.",
                f"Here's a {tag.year} track from the album {tag.album}.",
                f"Coming up, {tag.artist} with {tag.title}!",
                f"Here's {tag.artist}! This is {tag.title}.",
                f"Next up, we have {tag.title}!",
                f"Something a bit different now, from {tag.artist}.",
                f"See if you recognise this one from {tag.year}.",
                f"Something a little bit special for you now. It's {tag.artist}.",
                f"Fancy some {tag.genre} music? Here's {tag.artist}.",
                f"In just a moment, you'll hear {tag.title}.",
                f"I can't stop singing {tag.title}. Thank you, {tag.artist}."
            ])
        if random.random() > 0.6:
            dj_says += random.choice([" I love this song!", " Awesome tune!", " Enjoy!", " Epic!",
                                      " Great, great track!"])  # Note spaces at start of strings
        output(dj_says)
        
        # Display-O-Tron code follows
        DAB_display = (tag.artist + ' ' * 16)[:16] \
                      + (tag.title + ' ' * 32)[:32]
        lcd.clear()
        lcd.write(DAB_display)
        # Display-O-Tron code ends

        playsound(song_to_play)

songs = index_directory("music", [], True)  # pass folder name for music
jingles = index_directory("jingles", [], False) # folder for jingles
voice = pyttsx3.init()
voice.setProperty('rate', 170)

while True:
    broadcast_news_and_weather()
    play_songs(8)

Running Raspberry Radio

Open the code in Thonny in Raspberry Pi OS, and click the Run button. The program (and indeed the programme) will run until you click the Stop button.

Enhancing Raspberry Radio

You can use Raspberry Radio together with my PiGlow disco lights code to make lights flash while the music plays.

You can also use a Python API to download random jokes from the internet for the DJ to say in between the songs from time to time.

More Raspberry Pi projects

Find more Raspberry Pi projects and tutorials here.

Image credits

With thanks to Manfred Richter via Pixabay for the radio photo.

Credits

© Sean McManus. All rights reserved.

Visit www.sean.co.uk for free chapters from Sean's coding books (including Mission Python, Scratch Programming in Easy Steps and Coder Academy) and more!

Discover my latest books

Coding Compendium

Coding Compendium

A free 100-page ebook collecting my projects and tutorials for Raspberry Pi, micro:bit, Scratch and Python. Simply join my newsletter to download it.

Web Design in Easy Steps

Web Design IES

Web Design in Easy Steps, now in its 7th Edition, shows you how to make effective websites that work on any device.

100 Top Tips: Microsoft Excel

100 Top Tips: Microsoft Excel

Power up your Microsoft Excel skills with this powerful pocket-sized book of tips that will save you time and help you learn more from your spreadsheets.

Scratch Programming in Easy Steps

Scratch Programming IES

This book, now fully updated for Scratch 3, will take you from the basics of the Scratch language into the depths of its more advanced features. A great way to start programming.

Mission Python book

Mission Python

Code a space adventure game in this Python programming book published by No Starch Press.

Cool Scratch Projects in Easy Steps book

Cool Scratch Projects in Easy Steps

Discover how to make 3D games, create mazes, build a drum machine, make a game with cartoon animals and more!

Walking astronaut from Mission Python book Top | Search | Help | Privacy | Access Keys | Contact me
Home | Newsletter | Blog | Copywriting Services | Books | Free book chapters | Articles | Music | Photos | Games | Shop | About