During the day, I enjoy streaming a popular scam-baiter from Twitch to listen in the background. It’s usually really funny, there’s a lot of waiting around, so it’s not disrupting to my work day, and it’s mainly audio based so I don’t need to pay visual attention to it.
I’ve put together a combination of inputs on the lovelace front end, and some automations, and now I can stream the audio from Twitch, using media_extractor, to my instance of forked-daapd, which then pushes the audio to whatever remote speaker I choose. If you provide a start time
(using the format HH:mm:ss
) then it will start to stream from that timestamp.
To implement it, you’ll need to have a media player, media extractor, and the lovelace-text-input-row plugin from the HACS integration.. It involves a lovelace front end, a couple of automations, and a couple of scripts.
Lovelace UI Code
entities:
- entity: input_text.media_id
type: 'custom:text-input-row'
- entity: input_text.start_time
type: 'custom:text-input-row'
- action_name: Stream Music
icon: 'mdi:music'
name: ' '
service: script.stream_music
type: call-service
- action_name: Update Time
icon: 'mdi:refresh'
name: ' '
service: script.1586984693530
type: call-service
title: Stream to Music Server
type: entities
Automation
This automation will update the UI with the media stream URL for any source that’s a remote stream (regardless of where you started it), and trigger the script to update the timestamp in the UI.
- id: '1587058178874'
alias: Populate Music Entities
description: ''
trigger:
- entity_id: media_player.music_server
platform: state
to: playing
condition:
- condition: template
value_template: '{{ ''http'' in state_attr(''media_player.music_server'', ''media_content_id'')
}}'
- condition: state
entity_id: input_text.start_time
state: ''
action:
- data_template:
value: '{{ state_attr(''media_player.music_server'', ''media_content_id'') }}'
entity_id: input_text.media_id
service: input_text.set_value
- data: {}
entity_id: script.1586984693530
service: script.turn_on
Scripts
There are three scripts: the first one to begin the stream, on button press. The other two will run repeatedly as long as the stream is being played, in order to update the timestamp in the UI. This will allow me to stop the stream, then pick it back up from the last place I was listening without any need to keep track of the timestamp.
stream_music:
alias: Stream Music
sequence:
- data_template:
media_content_id: '{{states(''input_text.media_id'')}}'
media_content_type: video/youtube
entity_id: media_player.music_server
service: media_extractor.play_media
- condition: template
value_template: '{{ states(''input_text.start_time'') != '''' }}'
- data_template:
entity_id: media_player.music_server
seek_position: '{% set ts = states(''input_text.start_time'').split(":") %}
{% if (ts|length == 2) %} {{ ((ts[0] | int ) * 60) + (ts[1] | int)}} {% else
%} {{ ((ts[0] | int ) * 60 * 60) + ((ts[1] | int) * 60) + (ts[2] | int)}}
{% endif %}'
service: media_player.media_seek
- timeout: 00:00:30
wait_template: '{{ states(''media_player.music_server'') == ''playing''}}'
- data: {}
entity_id: script.1586984693530
service: script.turn_on
'1586984693530':
alias: Update Timestamp Text Input
sequence:
- data_template:
entity_id: input_text.start_time
value: '{% set time = (state_attr("media_player.music_server", "media_position").split(":")[0]
| int) %} {% set seconds = ((time % 60) | int) %} {% set minutes = ((time
% 3600) / 60) | int %} {% set hours = ((time % 86400) / 3600) | int %} {%
set days = (time / 86400) | int %} {{ "%02d" | format(hours) ~ ":" ~ "%02d"
| format(minutes) ~ ":" ~ "%02d" | format(seconds)}}'
service: input_text.set_value
- delay: 00:00:05
- data: {}
entity_id: script.1586985396087
service: script.turn_on
'1586985396087':
alias: Continue Polling Music Server Timestamp
sequence:
- condition: state
entity_id: media_player.music_server
state: playing
- data: {}
entity_id: script.1586984693530
service: script.turn_on