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:

piface cad radio raspberry pi

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.

16 gedachten over “Internet radio luisteren met een Raspberry Pi en PiFace CAD”

  1. Als beginnende RPI gebruiker leek mij dit wel een leuk probeersel. Ik heb echter 1 vraag.
    Ik wil maar 1 radiostation dus de pi face is niet echt noodzakelijk. Ook wil ik graag dat hij zodra er spanning op de Pi komt dat hij na het booten direct dat ene station gaat afspelen.
    Ik ben al op zoek naar een oplossing maar als beginnende Pi user zou ik graag een steuntje in de rug hebben

    ruud

  2. Er is iets met het opstarten van programma’s, bij opstarten wel te verstaan.
    Het zou inderdaad makkelijk zijn om bij opstart een opgegeven zender of programma op te starten, een soort autoexec.bat, maar dan voor python.

    In afwachting op uw reactie…

  3. hallo,
    ik heb de aanwijzingen nauwkeurig opgevolgd (op ’n raspberry pi 3 en piface), maar krijg helaas de volgende foutmelding (op de display staat wel: NPO radio2):
    %==================
    pi@raspberrypi:~ $ sudo python3 radio.py
    Playing NPO Radio 2.
    MPlayer2 2.0-728-g2c378c7-4+b1 (C) 2000-2012 MPlayer Team
    Cannot open file ‘/root/.mplayer/input.conf’: No such file or directory
    Failed to open /root/.mplayer/input.conf.
    Cannot open file ‘/etc/mplayer/input.conf’: No such file or directory
    Failed to open /etc/mplayer/input.conf.

    Playing http://icecast.omroep.nl/radio2-bb-mp3.
    Resolving icecast.omroep.nl for AF_INET6…
    Couldn’t resolve name for AF_INET6: icecast.omroep.nl
    Resolving icecast.omroep.nl for AF_INET…
    Connecting to server icecast.omroep.nl[145.58.52.144]: 80…
    Name : Radio 2
    Genre : Mixed
    Website: http://www.radio2.nl
    Public : no
    Bitrate: 192kbit/s
    Cache size set to 320 KiB
    Cache fill: 0.00% (0 bytes)
    ICY Info: StreamTitle=’NPO Radio 2 – Muziekcaf� – TROS’;

    Detected file format: Audio only
    Selected audio codec: MPEG 1.0/2.0/2.5 layers I, II, III [mpg123]
    AUDIO: 48000 Hz, 2 ch, s16le, 192.0 kbit/12.50% (ratio: 24000->192000)
    AO: [pulse] Init failed: Connection refused
    AO: [alsa] 48000Hz 2ch s16le (2 bytes per sample)
    [AO_ALSA] Unable to find simple control ‘Master’,0.
    Video: no video
    Starting playback…
    %==================

    enig idee wat ik moet doen?
    Vriendelijke groet,
    Jan

  4. Je kunt de ontbrekende input.conf downloaden en zelf op de juiste plaats zetten.

    wget https://raw.githubusercontent.com/milomouse/dotfiles/master/.mplayer/input.conf
    sudo mkdir /root/.mplayer/
    sudo cp input.conf /root/.mplayer/input.conf
  5. Sorry Richard,
    Hij werkt nu.
    Heel dom, maar ik zag het icoontje met het speakertje rechts boven.
    Blijkbaar staat daar de boel standaard op HDMI ingesteld i.p.v. Analog.
    Na het instellen op Analog werkte de internetradio !!!

    Nogmaals dank en excuse voor het ongemak.
    Vriendelijke groet,
    Jan

  6. Nog 1 vraagje:
    Nu is het zo dat als de Raspberry opstart dat ik daarna via de terminal de radio moet starten.
    Is het mogelijk de radio automatisch te laten starten?

  7. Hi ,

    Ik krijg een waslijst aan fouten , graag advies a.u.b
    Groet Patrick

    pi@raspberrypi:~ $ sudo python3 radio.py
    Traceback (most recent call last):
    File “radio.py”, line 185, in
    cad = pifacecad.PiFaceCAD()
    File “/usr/lib/python3/dist-packages/pifacecad/core.py”, line 50, in __init__
    self.init_board()
    File “/usr/lib/python3/dist-packages/pifacecad/core.py”, line 80, in init_board
    h=self.hardware_addr, b=self.bus, c=self.chip_select))
    pifacecad.core.NoPiFaceCADDetectedError: No PiFace Control and Display board detected (hardware_addr=0, bus=0, chip_select=1).

  8. LIRC bleek niet standaard mee geïnstalleerd te zijn…
    Deze heb ik handmatig toegevoegd.
    “`python
    pi@raspberrypi:~ $ sudo python3 radio.py &
    [1] 2540
    pi@raspberrypi:~ $ Traceback (most recent call last):
    File “radio.py”, line 13, in
    import lirc
    ModuleNotFoundError: No module named ‘lirc’
    “`
    Nadat ik deze heb toegevoegd met
    “`python
    sudo apt-get install lirc
    “`
    krijg ik de volgende foutmelding, iemand een ide hoe ik dit kan oplossen?
    “`python
    pi@raspberrypi:~ $ sudo python3 radio.py &
    [2] 3146
    pi@raspberrypi:~ $ Traceback (most recent call last):
    File “radio.py”, line 13, in
    import lirc
    File “/usr/lib/python3/dist-packages/lirc/__init__.py”, line 7, in
    from .client import get_default_lircrc_path
    File “/usr/lib/python3/dist-packages/lirc/client.py”, line 38, in
    import _client
    ModuleNotFoundError: No module named ‘_client’
    “`

    • [code]
      pi@raspberrypi:~ $ sudo python3 radio.py &
      [2] 3146
      pi@raspberrypi:~ $ Traceback (most recent call last):
      File “radio.py”, line 13, in
      import lirc
      File “/usr/lib/python3/dist-packages/lirc/__init__.py”, line 7, in
      from .client import get_default_lircrc_path
      File “/usr/lib/python3/dist-packages/lirc/client.py”, line 38, in
      import _client
      ModuleNotFoundError: No module named ‘_client’
      [/code]

Een reactie plaatsen

%d bloggers liken dit: