raspberrytips.nl

Internet radio luisteren met een Raspberry Pi en PiFace CAD

Een Raspberry Pi kun je voor allerlei handige toepassingen gebruiken. Wil je graag je eigen radio maken, dan is dat natuurlijk ook mogelijk. Het bedienen van de radio via de command prompt is echter niet altijd even handig, daarom gaan we een internet radio maken met een display en knop-bediening.

In dit project gebruiken we een Raspberry Pi en een PiFace Control & Display 2. Dit is een LCD scherm (16×2) met 5 fysieke knoppen, tuimelschakelaar en infrarood ontvanger. Met behulp van speciale python library en script kunnen we internet radio luisteren.

Componenten voor dit project

PiFace Control & Display 2 (CAD)

PiFace CAD configuratie

Vanzelfsprekend dient de PiFace CAD aangesloten te zijn op de Raspberry Pi en de bijbehorende software te zijn geïnstalleerd. Doorloop hiervoor de onderstaande stappen:

Activeer de SPI functionaliteit in de configuratie:

sudo raspi-config

Ga naar Advanced Options, selecteer SPI en activeer de optie en sluit raspi-config af.

Om met de PiFace te kunnen communiceren hebben een speciale Python library nodig, dan kunnen we installeren met behulp van het commando:

sudo apt-get install python3-pifacecad

Herstart nadat de installatie is voltooid:

sudo reboot

Het python radio script

Om de audiostreams te kunnen afspelen hebben we een media player nodig, in het script maken we gebruik van mplayer, deze installeer je met het commando:

sudo apt-get install mplayer

Bijna klaar! Als laatste hebben we natuurlijk het python radio script nodig. In de python library is een demo script aanwezig om radio te luisteren echter werkt deze helaas niet. Om die reden hebben we zelf een script gemaakt dat wel werkt.

#!/usr/bin/env python3
# requires `mplayer` to be installed
# v1.0
# https://raspberrytips.nl/internet-radio-luisteren-raspberry-pi/
from time import sleep
import os
import sys
import signal
import shlex
import math
import lirc
PY3 = sys.version_info[0] >= 3
if not PY3:
print("Radio only works with python3")
sys.exit(1)
from threading import Barrier
import subprocess
import pifacecommon
import pifacecad
from pifacecad.lcd import LCD_WIDTH
UPDATE_INTERVAL = 1
STATIONS = [
{'name': "NPO Radio 2",
'source': 'http://icecast.omroep.nl/radio2-bb-mp3',
'info': "NPO Radio 2"},
{'name': "NPO 3FM",
'source': 'http://icecast.omroep.nl/3fm-bb-mp3',
'info': None},
{'name': "Radio 538",
'source': 'http://vip-icecast.538.lw.triple-it.nl/RADIO538_MP3.m3u',
'info': None},
{'name': "Q-music",
'source': 'http://icecast-qmusic.cdp.triple-it.nl/Qmusic_nl_live_96.mp3.m3u',
'info': None},
{'name': "Sky Radio",
'source': 'http://provisioning.streamtheworld.com/pls/skyradio.pls',
'info': None}
]
PLAY_SYMBOL = pifacecad.LCDBitmap(
[0x10, 0x18, 0x1c, 0x1e, 0x1c, 0x18, 0x10, 0x0])
PAUSE_SYMBOL = pifacecad.LCDBitmap(
[0x0, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x0, 0x0])
PLAY_SYMBOL_INDEX = 0
PAUSE_SYMBOL_INDEX = 1
class Radio(object):
def __init__(self, cad, start_station=0):
self.current_station_index = start_station
self.playing_process = None
cad.lcd.blink_off()
cad.lcd.cursor_off()
cad.lcd.backlight_on()
cad.lcd.store_custom_bitmap(PLAY_SYMBOL_INDEX, PLAY_SYMBOL)
cad.lcd.store_custom_bitmap(PAUSE_SYMBOL_INDEX, PAUSE_SYMBOL)
self.cad = cad
@property
def current_station(self):
"""Returns the current station dict."""
return STATIONS[self.current_station_index]
@property
def playing(self):
return self._is_playing
@playing.setter
def playing(self, should_play):
if should_play:
self.play()
else:
self.stop()
@property
def text_status(self):
"""Returns a text represenation of the playing status."""
if self.playing:
return "Now Playing"
else:
return "Stopped"
def play(self):
"""Plays the current radio station."""
print("Playing {}.".format(self.current_station['name']))
if self.current_station['source'].split("?")[0][-3:] in ['m3u', 'pls']:
play_command = "mplayer -quiet -playlist {stationsource}".format(
stationsource=self.current_station['source'])
else:
play_command = "mplayer -quiet {stationsource}".format(
stationsource=self.current_station['source'])
self.playing_process = subprocess.Popen(
play_command,
shell=True,
preexec_fn=os.setsid)
self._is_playing = True
self.update_display()
def stop(self):
"""Stops the current radio station."""
print("Stopping radio.")
os.killpg(self.playing_process.pid, signal.SIGTERM)
self._is_playing = False
self.update_playing()
def change_station(self, new_station_index):
"""Change the station index."""
was_playing = self.playing
if was_playing:
self.stop()
self.current_station_index = new_station_index % len(STATIONS)
if was_playing:
self.play()
def next_station(self, event=None):
self.change_station(self.current_station_index + 1)
def previous_station(self, event=None):
self.change_station(self.current_station_index - 1)
def update_display(self):
self.update_station()
self.update_playing()
def update_playing(self):
"""Updated the playing status."""
if self.playing:
char_index = PLAY_SYMBOL_INDEX
else:
char_index = PAUSE_SYMBOL_INDEX
self.cad.lcd.set_cursor(0, 0)
self.cad.lcd.write_custom_bitmap(char_index)
def update_station(self):
"""Updates the station status."""
message = self.current_station['name'].ljust(LCD_WIDTH-1)
self.cad.lcd.set_cursor(1, 0)
self.cad.lcd.write(message)
def toggle_playing(self, event=None):
if self.playing:
self.stop()
else:
self.play()
def close(self):
self.stop()
self.cad.lcd.clear()
self.cad.lcd.backlight_off()
def radio_preset_switch(event):
global radio
radio.change_station(event.pin_num)
if __name__ == "__main__":
try:
subprocess.call(["mplayer"], stdout=open('/dev/null'))
except OSError as e:
if e.errno == os.errno.ENOENT:
print(
"MPlayer was not found, install with "
"`sudo apt-get install mplayer`")
sys.exit(1)
else:
raise
cad = pifacecad.PiFaceCAD()
global radio
radio = Radio(cad)
radio.play()
global end_barrier
end_barrier = Barrier(2)
switchlistener = pifacecad.SwitchEventListener(chip=cad)
for pstation in range(4):
switchlistener.register(
pstation, pifacecad.IODIR_ON, radio_preset_switch)
switchlistener.register(4, pifacecad.IODIR_ON, end_barrier.wait)
switchlistener.register(5, pifacecad.IODIR_ON, radio.toggle_playing)
switchlistener.register(6, pifacecad.IODIR_ON, radio.previous_station)
switchlistener.register(7, pifacecad.IODIR_ON, radio.next_station)
switchlistener.activate()
end_barrier.wait()
radio.close()
switchlistener.deactivate()
view raw radio.py hosted with ❤ by GitHub

Je kunt het script naar je Raspberry Pi downloaden met behulp van wget.

wget https://raspberrytips.nl/radio.py

Radio luisteren

Sluit een speaker of koptelefoon aan op de audio uitgang van de Raspberry Pi, start nu het radio script:

sudo python3 radio.py

Hierna kun je direct luisteren naar NPO Radio 2, de fysieke knoppen op de PiFace CAD hebben de volgende functies:

Knop (1) t/m (4) ▸ Radiostation voorkeuze 1 (Radio 2),2 (3FM),3 (538),4 (Q-music)

Navigatieknop (5) links/rechts ▸ vorig/volgend radiostation.
Navigatieknop (5) indrukken ▸ Pauze.

Knop (6) ▸ Radio applicatie afsluiten.

Radiostations toevoegen

In het script zijn 5 Nederlandse stations aanwezig (NPO Radio 2, NPO 3FM, Radio 538, Q-music en Sky Radio). Je kunt zelf meerdere stations toevoegen of wijzigen in het script. De URL’s van alle Nederlandse radio stations kun je terugvinden op listenlive.

    {'name': "NPO Radio 2",
     'source': 'http://icecast.omroep.nl/radio2-bb-mp3',
     'info': None},

Wijzig in het script de name en source van een radio station of voeg een nieuwe toe, ‘info’ wordt niet gebruikt, geef deze de waarde None.