rewrite streamer and controller -- much cleaner and efficient; continue to work on new architecture

This commit is contained in:
bkfox
2019-07-31 02:17:30 +02:00
parent 8581743d13
commit 8e1d2b6769
20 changed files with 550 additions and 2540 deletions

View File

@ -1,171 +0,0 @@
{% comment %}
TODO: update doc
Base configuration file to configure a station on liquidsoap.
# Interactive elements:
An interactive element is accessible to the people, in order to:
- get metadata
- seek
- skip the current sound
- enable/disable it
# Element of the context
We use theses elements from the template's context:
- controller: controller describing the station itself
- settings: global settings
# Overwrite the template
It is possible to overwrite the template, there are blocks at different
position in order to do it. Keep in mind that you might want to avoid to
put station specific configuration in the template itself.
{% endcomment %}
{% block functions %}
{% comment %}
Seek function
{% endcomment %}
def seek(source, t) =
t = float_of_string(default=0.,t)
ret = source.seek(source,t)
log("seek #{ret} seconds.")
"#{ret}"
end
{% comment %}
Transition to live sources
{% endcomment %}
def to_live(stream,live)
stream = fade.final(duration=2., type='log', stream)
live = fade.initial(duration=2., type='log', live)
add(normalize=false, [stream,live])
end
{% comment %}
Transition to stream sources
{% endcomment %}
def to_stream(live,stream)
source.skip(stream)
add(normalize=false, [live,stream])
end
{% comment %}
An interactive source is a source that:
- is skippable through the given id on external interfaces
- is seekable through the given id and amount of seconds on e.i.
- can be disabled
- store metadata
{% endcomment %}
def interactive_source (id, s, ~active=true, ~disable_switch=false) =
server.register(namespace=id,
description="Seek to a relative position",
usage="seek <duration>",
"seek", fun (x) -> begin seek(s, x) end)
s = store_metadata(id=id, size=1, s)
add_skip_command(s)
if disable_switch then
s
else
at(interactive.bool('#{id}_active', active), s)
end
end
{% comment %}
A stream is a source that:
- is a playlist on random mode (playlist object accessible at {id}_playlist
- is interactive
{% endcomment %}
def stream (id, file) =
s = playlist(id = '#{id}_playlist', mode = "random", reload_mode='watch', file)
interactive_source(id, s)
end
{% endblock %}
{% block functions_extras %}
{% endblock %}
{% block config %}
set("server.socket", true)
set("server.socket.path", "{{ station.streamer.socket_path }}")
set("log.file.path", "{{ station.path }}/liquidsoap.log")
{% for key, value in settings.AIRCOX_LIQUIDSOAP_SET.items %}
set("{{ key|safe }}", {{ value|safe }})
{% endfor %}
{% endblock %}
{% block config_extras %}
{% endblock %}
{% block sources %}
live = fallback([
{% with source=station.dealer %}
interactive_source('{{ source.id }}',
playlist.once(reload_mode='watch', "{{ source.path }}"),
active=false
),
{% endwith %}
])
stream = fallback([
rotate([
{% for source in station.sources %}
{% if source != station.dealer %}
{% with stream=source.stream %}
{% if stream.delay %}
delay({{ stream.delay }}.,
stream("{{ source.id }}", "{{ source.path }}")),
{% elif stream.begin and stream.end %}
at({ {{stream.begin}}-{{stream.end}} },
stream("{{ source.id }}", "{{ source.path }}")),
{% else %}
stream("{{ source.id }}", "{{ source.path }}"),
{% endif %}
{% endwith %}
{% endif %}
{% endfor %}
]),
blank(id="blank", duration=0.1),
])
{% endblock %}
{% block sources_extras %}
{% endblock %}
{% block station %}
{{ station.streamer.id }} = interactive_source (
"{{ station.streamer.id }}",
fallback(
track_sensitive=false,
transitions=[to_live,to_stream],
[ live, stream ]
),
disable_switch=true
)
{% endblock %}
{% block station_extras %}
{% endblock %}
{% block outputs %}
{% for output in station.outputs %}
output.{{ output.get_type_display }}(
{% if output.settings %}
{{ output.settings|safe }},
{% endif %}
{{ station.streamer.id }}
)
{% endfor %}
{% endblock %}
{% block output_extras %}
{% endblock %}

View File

@ -0,0 +1,125 @@
{% comment %}
Base liquidsoap station configuration.
[stream] +--> streams ---+---> station
|
dealer ---'
{% endcomment %}
{% block functions %}
{# Seek function #}
def seek(source, t) =
t = float_of_string(default=0.,t)
ret = source.seek(source,t)
log("seek #{ret} seconds.")
"#{ret}"
end
{# Transition to live sources #}
def to_live(stream, live)
stream = fade.final(duration=2., type='log', stream)
live = fade.initial(duration=2., type='log', live)
add(normalize=false, [stream,live])
end
{# Transition to stream sources #}
def to_stream(live, stream)
source.skip(stream)
add(normalize=false, [live,stream])
end
{% comment %}
An interactive source is a source that:
- is skippable through the given id on external interfaces
- is seekable through the given id and amount of seconds on e.i.
- store metadata
{% endcomment %}
def interactive (id, s) =
server.register(namespace=id,
description="Seek to a relative position",
usage="seek <duration>",
"seek", fun (x) -> begin seek(s, x) end)
s = store_metadata(id=id, size=1, s)
add_skip_command(s)
s
end
{% comment %}
A stream is an interactive playlist
{% endcomment %}
def stream (id, file) =
s = playlist(mode = "random", reload_mode='watch', file)
interactive(id, s)
end
{% endblock %}
{% block config %}
set("server.socket", true)
set("server.socket.path", "{{ streamer.socket_path }}")
set("log.file.path", "{{ station.path }}/liquidsoap.log")
{% for key, value in settings.AIRCOX_LIQUIDSOAP_SET.items %}
set("{{ key|safe }}", {{ value|safe }})
{% endfor %}
{% endblock %}
{% block config_extras %}
{% endblock %}
{% block sources %}
{% with source=streamer.dealer %}
live = interactive('{{ source.id }}',
request.queue(id="{{ source.id }}_queue")
)
{% endwith %}
streams = rotate(id="streams", [
{% for source in streamer.sources %}
{% if source != streamer.dealer %}
{% with stream=source.stream %}
{% if stream.delay %}
delay({{ stream.delay }}.,
stream("{{ source.id }}", "{{ source.path }}")),
{% elif stream.begin and stream.end %}
at({ {{stream.begin}}-{{stream.end}} },
stream("{{ source.id }}", "{{ source.path }}")),
{% else %}
stream("{{ source.id }}", "{{ source.path }}"),
{% endif %}
{% endwith %}
{% endif %}
{% endfor %}
])
{% endblock %}
{% block station %}
{{ streamer.id }} = interactive (
"{{ streamer.id }}",
fallback([
live,
streams,
blank(id="blank", duration=0.1)
], track_sensitive=false, transitions=[to_live,to_stream])
)
{% endblock %}
{% block outputs %}
{% for output in streamer.outputs %}
output.{{ output.get_type_display }}(
{% if output.settings %}
{{ output.settings|safe }},
{% endif %}
{{ streamer.id }}
)
{% endfor %}
{% endblock %}