Playing webradio (and other audio) from Lovelace dashboard
Introduction ¶
One of the nice things about smart speakers is that they can play audio from a wide variety of sources. Combine this with Home Assistant and you have yourself a webradio and custom audio dashboard :)
This blog post will explain my setup and will provide you with the code and pointers needed to build your own version of it.

Note that I’m setting this all up in YAML. Helpers like the dropdown and textbox can also be created using the UI. At the end of this blog posts, it’ll become clear why I’m doing everything in YAML.
Set-up ¶
To set everything up, we’ll need some helpers that’ll provide a dropdown and a textbox, some scripts, and some Lovelace elements.
Let’s go through each part step-by-step. I’ll provide the full code at the end of this blogpost.
Helpers ¶
These helpers will provide the dropdown selection of radio stations and a text field to enter our own URLs into.
Feel free to adapt the list of radio stations to your choosing. Finding the correct URL is often the hardest part. Check if your favorite station has a web player and whether you can extract the URL of the stream from the address bar or the network requests. There are also online services that will provide you with streams for lots of webradio stations.
Radio station dropdown ¶
input_select:
radio_station:
name: 'Pick station'
icon: mdi:radio
initial: VRT Studio Brussel
options:
- VRT Radio 1
- VRT Studio Brussel
- VRT MNM
- VRT NWS
- Topradio
- Qmusic
- VBRO
- Willy Radio
Custom URL textbox ¶
input_text:
url:
name: URL
min: 10
max: 255
icon: mdi:web
mode: text
Scripts ¶
Play from dropdown ¶
The code below will be called by a button on our dashboard and will play the station that’s selected in the dropdown.
Optionally, it will also provide an image (the logo of the radio station) to be displayed on our Lovelace dashboard while playing.
For this you’ll need to download the logos or images you want and store them in (a subfolder of) /config/www/
which will be referenced as /local/
.
script:
play_radio:
alias: Play radio
icon: mdi:play
description: Play web radio on smart speaker
mode: restart
sequence:
- service: media_player.volume_set
data:
entity_id: media_player.livingroom
volume_level: 0.10
- service: media_player.play_media
data:
entity_id: media_player.livingroom
media_content_type: music
media_content_id: >
{%- set station = states('input_select.radio_station') -%}
{% if station == "VRT Radio 1" %} http://icecast.vrtcdn.be/radio1-high.mp3
{% elif station == "VRT Studio Brussel" %} http://icecast.vrtcdn.be/stubru-high.mp3
{% elif station == "VRT Studio Brussel - #ikluisterbelgisch" %} http://icecast.vrtcdn.be/stubru_tgs-high.mp3
{% elif station == "VRT MNM" %} http://icecast.vrtcdn.be/mnm-high.mp3
{% elif station == "VRT NWS" %} http://progressive-audio.lwc.vrtcdn.be/content/fixed/11_11niws-snip_hi.mp3
{% elif station == "Topradio" %} https://str.topradio.be/topradio.mp3
{% elif station == "Qmusic" %} https://21293.live.streamtheworld.com/QMUSIC.mp3
{% elif station == "VBRO" %} https://radiohuis.com/VBRO
{% elif station == "Willy Radio" %} http://20723.live.streamtheworld.com/WILLY.mp3
{% endif %}
extra:
thumb: >
{%- set station = states('input_select.radio_station') -%}
{% if 'Studio Brussel' in station %} https://<your_HA_URL>/local/img/logo/logo_stubru.svg
{% elif 'MNM' in station %} https://<your_HA_URL>/local/img/logo/logo_mnm.svg
{% elif 'NWS' in station %} https://<your_HA_URL>/local/img/logo/logo_vrtnws.svg
{% elif station[:3] == "VRT" %} https://<your_HA_URL>/local/img/logo/logo_vrt.svg
{% elif station == "Topradio" %} https://<your_HA_URL>/local/img/logo/logo_topradio.svg
{% elif station == "Qmusic" %} https://<your_HA_URL>/local/img/logo/logo_qmusic.svg
{% elif station == "VBRO" %} https://<your_HA_URL>/local/img/logo/logo_vbro.png
{% elif station == "Willy Radio" %} https://<your_HA_URL>/local/img/logo/logo_willy.svg
{% endif %}
stream_type: LIVE
Play custom URL ¶
For this script we’ll also need the media_extractor
integration.
This uses youtube_dl
to extract the audio stream from the video/stream/audoclip/… you give it.
media_extractor:
script:
play_media_url:
alias: Play media from URL
mode: single
icon: mdi:music-box-multiple-outline
sequence:
- service: media_player.media_stop
target:
entity_id: media_player.livingroom
- service: media_player.volume_set
data:
entity_id: media_player.livingroom
volume_level: 0.10
- service: media_extractor.play_media
data:
media_content_type: MUSIC
media_content_id: "{{ states('input_text.url') }}"
target:
entity_id: media_player.livingroom
Lovelace Dashboard ¶
You can design your dashboard anyway you like.
I chose to use the Mini Media Player custom card to display what’s playing on my smart speaker. You can find it on HACS.
type: vertical-stack
cards:
- type: custom:mini-media-player
group: false
artwork: cover
source: full
sound_mode: full
info: short
name: Living Room
idle_view:
when_idle: true
entity: media_player.livingroom
- type: entities
entities:
- entity: input_select.radio_station
name: station
- entity: script.play_radio
tap_action:
action: call-service
service: script.turn_on
service_data:
entity_id: script.play_radio
- type: entities
entities:
- entity: input_text.url
name: URL
- entity: script.play_media_url
tap_action:
action: call-service
service: script.turn_on
service_data:
entity_id: script.play_media_url
icon: mdi:play
Complete code ¶
Below you’ll find the complete code for this blog post.
The reason I chose to define everything in YAML, including the helpers, is because I’ve split up my config in packages. This allows me to group to bundle related configurations together, making it easier to find all components.
If you don’t want to use packages, just move the code snippets to the relevant configurations (e.g. scripts.yaml
).
configuration.yaml
homeassistant:
packages: !include_dir_merge_named packages/
# Decided to keep this here as multiple packages may use this single integration
media_extractor:
packages/mediaplayers/media_url.yaml
---
# Play custom audio stream on smart speaker(s)
#
# https://www.home-assistant.io/integrations/media_extractor/
# https://www.home-assistant.io/integrations/input_text/
#
media_url:
script:
play_media_url:
alias: Play media from URL
mode: single
icon: mdi:music-box-multiple-outline
sequence:
- service: media_player.media_stop
target:
entity_id: media_player.livingroom
- service: media_player.volume_set
data:
entity_id: media_player.livingroom
volume_level: 0.10
- service: media_extractor.play_media
data:
media_content_type: MUSIC
media_content_id: "{{ states('input_text.url') }}"
target:
entity_id: media_player.livingroom
input_text:
url:
name: URL
min: 10
max: 255
icon: mdi:web
mode: text
packages/mediaplayers/webradio.yaml
---
# Play webradio on smart speaker(s)
#
# Based on https://community.home-assistant.io/t/chromecast-radio-with-station-and-player-selection/12732
#
# https://www.home-assistant.io/integrations/media_player
# https://www.home-assistant.io/integrations/input_select/
#
webradio:
script:
play_radio:
alias: Play radio
icon: mdi:play
description: Play web radio on Chromecast
mode: restart
sequence:
- service: media_player.volume_set
data:
entity_id: media_player.livingroom
volume_level: 0.10
- service: media_player.play_media
data:
entity_id: media_player.livingroom
media_content_type: music
media_content_id: >
{%- set station = states('input_select.radio_station') -%}
{% if station == "VRT Radio 1" %} http://icecast.vrtcdn.be/radio1-high.mp3
{% elif station == "VRT Studio Brussel" %} http://icecast.vrtcdn.be/stubru-high.mp3
{% elif station == "VRT Studio Brussel - #ikluisterbelgisch" %} http://icecast.vrtcdn.be/stubru_tgs-high.mp3
{% elif station == "VRT MNM" %} http://icecast.vrtcdn.be/mnm-high.mp3
{% elif station == "VRT NWS" %} http://progressive-audio.lwc.vrtcdn.be/content/fixed/11_11niws-snip_hi.mp3
{% elif station == "Topradio" %} https://str.topradio.be/topradio.mp3
{% elif station == "Qmusic" %} https://21293.live.streamtheworld.com/QMUSIC.mp3
{% elif station == "VBRO" %} https://radiohuis.com/VBRO
{% elif station == "Willy Radio" %} http://20723.live.streamtheworld.com/WILLY.mp3
{% endif %}
extra:
thumb: >
{%- set station = states('input_select.radio_station') -%}
{% if 'Studio Brussel' in station %} https://<my_homeassistant>/local/img/logo/logo_stubru.svg
{% elif 'MNM' in station %} https://<my_homeassistant>/local/img/logo/logo_mnm.svg
{% elif 'NWS' in station %} https://<my_homeassistant>/local/img/logo/logo_vrtnws.svg
{% elif station[:3] == "VRT" %} https://<my_homeassistant>/local/img/logo/logo_vrt.svg
{% elif station == "Topradio" %} https://<my_homeassistant>/local/img/logo/logo_topradio.svg
{% elif station == "Qmusic" %} https://<my_homeassistant>/local/img/logo/logo_qmusic.svg
{% elif station == "VBRO" %} https://<my_homeassistant>/local/img/logo/logo_vbro.png
{% elif station == "Willy Radio" %} https://<my_homeassistant>/local/img/logo/logo_willy.svg
{% endif %}
stream_type: LIVE
input_select:
radio_station:
name: 'Kies radiostation'
icon: mdi:radio
initial: VRT Studio Brussel
options:
- VRT Radio 1
- VRT Studio Brussel
- "VRT Studio Brussel - #ikluisterbelgisch"
- VRT MNM
- VRT NWS
- Topradio
- Qmusic
- Topradio
- VBRO
- Willy Radio
Lovelace dashboard
Add new card > Manual.
type: vertical-stack
cards:
- type: custom:mini-media-player
group: false
artwork: cover
source: full
sound_mode: full
info: short
name: Living Room
idle_view:
when_idle: true
entity: media_player.livingroom
- type: entities
entities:
- entity: input_select.radio_station
name: station
- entity: script.play_radio
tap_action:
action: call-service
service: script.turn_on
service_data:
entity_id: script.play_radio
- type: entities
entities:
- entity: input_text.url
name: URL
- entity: script.play_media_url
tap_action:
action: call-service
service: script.turn_on
service_data:
entity_id: script.play_media_url
icon: mdi:play
Enjoy playing your favourite radio station on your smart speakers!