Now Playing LCD for my internet stream

This is not really a PIC project but it is connected to my Medium Wave Mayhem modulator. I use Radio Génération Soul Disco Funk, now also known as Radio Goodlife, as its source. Now its display nicely shows the frequency but not what is playing on the stream. Which I get from an aging Raspberry Pi 3B. It runs a shell script where ffmpeg is getting the stream and filtering it and then sending it to VLC (actually cvlc which is the command line version) which outputs it as audio. The play-generationsouldiscofunk.sh script is very simple:

ffmpeg -hide_banner -i https://gestream.fr/g-radio-hd.mp3 -af "highpass=80, lowpass=f=4500, lowpass=f=4500, lowpass=f=4500:t=h:w=3333, acompressor=threshold=-10dB:ratio=9:attack=200:release=1000, volume=2dB" -f wav - | cvlc --avcodec-codec=wav -

It uses a brick wall low pass filter for 4.5 kHz as per requirements for medium wave, some highpass filtering to remove excess bass, some compressing to get a fuller "AM" sound and then pipes the result to cvlc which plays the stream via the 3.5mm socket to my modulator. The play-generationsouldiscofunk.sh script runs from crontab with the @reboot parameter after a 10 s delay to allow network to come up. Otherwise the stream will fail to play.

Now I happen to have two identical LCD screens of 2x16 characters. The second display was connected to the RPi and runs a Python 3 program. It isn't even the first program I wrote but as I am not very good in Python I just looked everything up. Eventually I came with:

import time
import RPi.GPIO as GPIO
from RPLCD.gpio import CharLCD
lcd = CharLCD(pin_rs=18, pin_rw=None, pin_e=19, pins_data=[21, 22, 23, 24],
    numbering_mode=GPIO.BOARD)
lcd.clear()
lcd.write_string('Starting...')
artist_index = 0
title_index = 0
while True:
    f = open('/tmp/artist','r')
    artist = f.readline()
    f.close()
    artist_len = len(artist)
    f = open('/tmp/title','r')
    title = f.readline()
    f.close()
    title_len = len(title)
    lcd.clear()
    lcd.cursor_pos = (0, 0)
    if (artist_index + 16) < artist_len:
        artist_index+=1
    else:
        artist_index = 0
    lcd.write_string(artist[artist_index:(artist_index + 16)])
    lcd.cursor_pos = (1, 0)
    if (title_index + 16) < title_len:
        title_index+=1
    else:
        title_index = 0
    lcd.write_string(title[title_index:(title_index + 16)])
    time.sleep(0.3)

I first had installed nowplaying_lcd.py on another RPi 3B and it worked right away. pip complained it did not want to install the required RPLCD library but running inside a virtual environment solved that. It had to be created with python3 -m venv venv where the second venv is in the directory I want to run from, in this case /home/pi/lcd/. Then it installed just fine with ./bin/pip3 install RPLCD. But my program refused to run and attempting to install RPi.GPIO failed. Compile error. Huh? Turned out I had to run sudo apt install python3-dev. I have no idea why it worked on the other 3B. Maybe because it runs Debian Trixie which must have had installed python3-dev and the other still runs Buster, which hadn't, who knows.

So now I had my display going and I had to get the stream's metadata. VLC can make a webserver with metadata but I could not get that to work. Also, <Ctrl>+<I> has an empty window. After some more querying I discovered that ffmpeg has a metadata option. So I wrote a quick shell script to populate my artist and title variables that my nowplaying script reads:

#!/bin/bash
for (( i=0; i<4; i++ ))
do
ffmpeg -i https://gestream.fr/g-radio-hd.mp3 -f ffmetadata -|grep StreamTitle= > /tmp/meta.txt
cat /tmp/meta.txt | awk -F'StreamTitle=' '{print $2}'>/tmp/meta1.txt
cat /tmp/meta1.txt | awk -F' - ' '{print $1}'>/tmp/artist
cat /tmp/meta1.txt | awk -F' - ' '{print $2}'>/tmp/title
sleep 13
done

getmeta.sh queries the stream server and saves the current metadata (StreamTitle) to a temp file. Maybe this is what VLC did not understand. Then it extracts the artist and title and writes them to their respective files. It does that four times and then exits and then gets restarted from a cron job running every minute. This way the nowplaying information on my LCD is updated every 15 seconds.

Now the only thing left is to start everything when the RPi is switched on. This script (startmeta.sh):

#!/bin/bash
echo "Now Playing" > /tmp/artist
echo "Waiting..." > /tmp/title
/home/pi/lcd/venv/bin/python3 /home/pi/lcd/venv/nowplaying_lcd.py
exit

preloads the LCD so the nowplaying info will show "Waiting..." until the metadata from the stream is available and then runs the nowplaying program. The last step is to enter the cron jobs:

# m h dom mon dow command
@reboot sleep 10; /home/pi/bin/play-generationsouldiscofunk.sh > /dev/null
@reboot /home/pi/lcd/venv/startmeta.sh
* * * * * /home/pi/lcd/venv/getmeta.sh

Success!

Back to the projects page

Date: 2 August 2026

CC-GNU GPL
This software is licensed under the CC-GNU GPL.