Skip to content
Snippets Groups Projects
Commit e03c167f authored by David Trattnig's avatar David Trattnig
Browse files

A/B scheduled fallback queue. #43

parent 5cf5ea8b
No related branches found
No related tags found
No related merge requests found
......@@ -26,23 +26,30 @@ inputs = ref []
# Load settings from ini file
%include "settings.liq"
print("**************************************************************************************")
print(" ENGINE LIQUIDSOAP CONFIGURATION ")
print("**************************************************************************************")
print(" Engine Configuration Folder: #{engine_config_folder}")
print(" Station Fallback Playlist: #{fallback_station_playlist_path}")
print(" Station Fallback Directory: #{fallback_station_dir}")
print("**************************************************************************************")
# Include some functions
%include "library.liq"
######################
# INPUTS #
######################
#####################################
# EVENTS #
#####################################
# Called when some new metadata info is available
def on_metadata_notification(meta) =
filename = meta["filename"]
# artist = meta["artist"]
# title = meta["title"]
system('#{list.assoc(default="", "install_dir", ini)}/guru.py --on_play "#{filename}"')
end
#####################################
# INPUTS #
#####################################
# Enable queue sources
%include "in_queue.liq"
# Enable play from filesystem
%include "in_filesystem.liq"
# Enable fallback sources
%include "in_fallback.liq"
# Enable stream overtakes
%include "in_stream.liq"
......@@ -50,10 +57,10 @@ print("*************************************************************************
# Enabled line in from soundcard
%include "in_soundcard.liq"
######################
# ROUTING #
######################
#####################################
# ROUTING #
#####################################
mixer = mix(id="mixer",
list.append(
......@@ -70,7 +77,7 @@ mixer = mix(id="mixer",
)
stripped_stream = strip_blank(
id='strip_blank',
id="strip_blank",
track_sensitive=false,
max_blank=fallback_max_blank,
min_noise=fallback_min_noise,
......@@ -78,39 +85,38 @@ stripped_stream = strip_blank(
mixer
)
# When some regular playout is happening and it is returned to the fallback,
# we don't want to resume the previous fallback track:
def on_track_change(s) =
source.skip(station_playlist)
source.skip(station_folder)
end
stripped_stream = on_track(on_track_change, stripped_stream)
output_source = fallback(
fallback_one = fallback(
id="fallback-scheduled",
track_sensitive=false,
replay_metadata=true,
[ stripped_stream, fallback_playlist])
[ stripped_stream, input_fallback_scheduled_0, input_fallback_scheduled_1])
output_source = fallback(
fallback_two = fallback(
id="fallback-station-playlist",
track_sensitive=false,
replay_metadata=true,
[ output_source, station_playlist])
[ fallback_one, station_playlist])
output_source = fallback(
fallback_three = fallback(
id="fallback-station-folder",
track_sensitive=false,
replay_metadata=true,
[ output_source, station_folder])
[ fallback_two, station_folder])
output_source = fallback_three
######################
# OUTPUTS #
######################
#####################################
# OUTPUTS #
#####################################
# create soundcard output
%include "out_soundcard.liq"
......
#
# Aura Engine (https://gitlab.servus.at/aura/engine)
#
# Copyright (C) 2017-2020 - The Aura Engine Team.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#####################################
# FALLBACK SOURCES #
#####################################
# Create Sources
input_fallback_scheduled_0 = request.equeue(id="in_fallback_scheduled_0")
input_fallback_scheduled_1 = request.equeue(id="in_fallback_scheduled_1")
station_playlist = playlist(
id="station_playlist",
fallback_station_playlist_path,
mode="randomize",
reload_mode="watch",
reload=0)
station_folder = mksafe(
playlist(id="station_folder",
fallback_station_dir,
mode="randomize",
reload=fallback_station_dir_reload,
reload_mode="seconds"))
# Apply ReplayGain Normalization
input_fallback_scheduled_0 = amplify(id="in_fallback_scheduled_0", 1., override="replay_gain", input_fallback_scheduled_0)
input_fallback_scheduled_1 = amplify(id="in_fallback_scheduled_1", 1., override="replay_gain", input_fallback_scheduled_1)
station_playlist = amplify(id="station_playlist", 1., override="replay_gain", station_playlist)
station_folder = amplify(id="station_folder", 1., override="replay_gain", station_folder)
# Add Event Handlers
input_fallback_scheduled_0 = on_metadata(id="in_fallback_scheduled_0", on_metadata_notification, input_fallback_scheduled_0)
input_fallback_scheduled_1 = on_metadata(id="in_fallback_scheduled_1", on_metadata_notification, input_fallback_scheduled_1)
station_playlist = on_metadata(id="station_playlist", on_metadata_notification, station_playlist)
station_folder = on_metadata(id="station_folder", on_metadata_notification, station_folder)
#####################################
# SERVER FUNCTIONS #
#####################################
# Clear Fallback Queue A
server.register(namespace=source.id(input_fallback_scheduled_0),
description="Clear all items of the scheduled fallback queue A.",
usage="clear",
"clear",
fun (s) ->
begin
clear_queue(input_fallback_scheduled_0)
"Clearing done."
end
)
# Clear Fallback Queue B
server.register(namespace=source.id(input_fallback_scheduled_1),
description="Clear all items of the scheduled fallback queue B.",
usage="clear",
"clear",
fun (s) ->
begin
clear_queue(input_fallback_scheduled_1)
"Clearing done."
end
)
# Seek Fallback Queue A
server.register(namespace = source.id(input_fallback_scheduled_0),
description="Seek to relative position in #{source.id(input_fallback_scheduled_0)}",
usage = "seek <duration in seconds>",
"seek",
fun (t) ->
begin
log("Seeking #{t} sec")
t = float_of_string(default=0.,t)
ret = source.seek(input_fallback_scheduled_0, t)
"Seeked #{ret} seconds."
end
)
# Seek Fallback Queue B
server.register(namespace = source.id(input_fallback_scheduled_1),
description="Seek to relative position in #{source.id(input_fallback_scheduled_1)}",
usage = "seek <duration in seconds>",
"seek",
fun (t) ->
begin
log("Seeking #{t} sec")
t = float_of_string(default=0.,t)
ret = source.seek(input_fallback_scheduled_1, t)
"Seeked #{ret} seconds."
end
)
\ No newline at end of file
......@@ -17,20 +17,20 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Called when some new metadata info is available
def on_metadata_notification(meta) =
filename = meta["filename"]
# artist = meta["artist"]
# title = meta["title"]
system('#{list.assoc(default="", "install_dir", ini)}/guru.py --on_play "#{filename}"')
end
# # Called when some new metadata info is available
# def on_metadata_notification(meta) =
# filename = meta["filename"]
# # artist = meta["artist"]
# # title = meta["title"]
# system('#{list.assoc(default="", "install_dir", ini)}/guru.py --on_play "#{filename}"')
# end
#####################################
# DEFAULT SOURCES #
# QUEUE SOURCES #
#####################################
# Create Filesystem Sources
# Create Sources
input_filesystem_0 = request.equeue(id="in_filesystem_0")
input_filesystem_1 = request.equeue(id="in_filesystem_1")
......@@ -43,65 +43,14 @@ input_filesystem_0 = on_metadata(id="in_filesystem_0", on_metadata_notification,
input_filesystem_1 = on_metadata(id="in_filesystem_1", on_metadata_notification, input_filesystem_1)
#####################################
# FALLBACK SOURCES #
#####################################
fallback_playlist = playlist(
id="playlist_fallback_scheduled",
"",
mode="normal",
reload_mode="watch")
station_playlist = playlist(
id="station_playlist",
fallback_station_playlist_path,
mode="randomize",
reload_mode="watch",
reload=10)
station_folder = mksafe(
playlist(id="station_folder",
fallback_station_dir,
mode="randomize",
reload=fallback_station_dir_reload,
reload_mode="seconds"))
# Apply ReplayGain Normalization
fallback_playlist = amplify(id="playlist_fallback_scheduled", 1., override="replay_gain", fallback_playlist)
station_playlist = amplify(id="station_playlist", 1., override="replay_gain", station_playlist)
station_folder = amplify(id="station_folder", 1., override="replay_gain", station_folder)
# Add Event Handlers
fallback_playlist = on_metadata(id="playlist_fallback_scheduled", on_metadata_notification, fallback_playlist)
station_playlist = on_metadata(id="station_playlist", on_metadata_notification, station_playlist)
station_folder = on_metadata(id="station_folder", on_metadata_notification, station_folder)
#####################################
# SERVER FUNCTIONS #
#####################################
def clear_items(ns) =
ret = server.execute("#{source.id(ns)}.primary_queue")
ret = list.hd(default="", ret)
if ret == "" then
log("Queue cleared.")
(-1.)
else
log("There are still items in the queue, trying skip ...")
source.skip(ns)
(0.1)
end
end
def clear_queue(ns) =
add_timeout(fast=false, 0.5, {clear_items(ns)})
end
# Clear Filesystem Queue A
# Clear Default Queue A
server.register(namespace=source.id(input_filesystem_0),
description="Clear all items of the filesystem queue A.",
description="Clear all items of the default queue A.",
usage="clear",
"clear",
......@@ -112,9 +61,9 @@ server.register(namespace=source.id(input_filesystem_0),
end
)
# Clear Filesystem Queue B
# Clear Default Queue B
server.register(namespace=source.id(input_filesystem_1),
description="Clear all items of the filesystem queue B.",
description="Clear all items of the default queue B.",
usage="clear",
"clear",
......@@ -127,26 +76,30 @@ server.register(namespace=source.id(input_filesystem_1),
# Seek Filesystem Queue A
server.register(namespace = source.id(input_filesystem_0),
description="seek to relative position in #{source.id(input_filesystem_0)}",
description="Seek to relative position in #{source.id(input_filesystem_0)}",
usage = "seek <duration in seconds>",
"seek",
fun(t) -> begin
log("Seeking #{t} sec")
t = float_of_string(default=0.,t)
ret = source.seek(input_filesystem_0, t)
"Seeked #{ret} seconds."
end
)
fun (t) ->
begin
log("Seeking #{t} sec")
t = float_of_string(default=0.,t)
ret = source.seek(input_filesystem_0, t)
"Seeked #{ret} seconds."
end
)
# Seek Filesystem Queue B
server.register(namespace = source.id(input_filesystem_1),
description="seek to relative position in #{source.id(input_filesystem_1)}",
description="Seek to relative position in #{source.id(input_filesystem_1)}",
usage = "seek <duration in seconds>",
"seek",
fun(t) -> begin
log("Seeking #{t} sec")
t = float_of_string(default=0.,t)
ret = source.seek(input_filesystem_1, t)
"Seeked #{ret} seconds."
end
)
\ No newline at end of file
fun (t) ->
begin
log("Seeking #{t} sec")
t = float_of_string(default=0.,t)
ret = source.seek(input_filesystem_1, t)
"Seeked #{ret} seconds."
end
)
......@@ -17,6 +17,44 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#####################################
# CLEAR SOURCE #
#####################################
def clear_items(ns) =
ret = server.execute("#{source.id(ns)}.primary_queue")
ret = list.hd(default="", ret)
if ret == "" then
log("Queue cleared.")
(-1.)
else
log("There are still items in the queue, trying skip ...")
source.skip(ns)
(0.1)
end
end
def clear_queue(ns) =
add_timeout(fast=false, 0.5, {clear_items(ns)})
end
#####################################
# DYNAMIC SOURCES #
#####################################
def create_dynamic_source(~skip=true, name)
log("Creating dynamic source '#{name}'")
track = get_process_lines("cat "^string.quote("next-track.txt"))
track = list.hd(default="", track)
dyn_source = request.dynamic.list(
{ [request.create(track)] })
dyn_source
end
#####################
# stream to icecast #
#####################
......
......@@ -120,3 +120,10 @@ if use_alsa then
end
end
print("**************************************************************************************")
print(" AURA ENGINE - LIQUIDSOAP SETTINGS ")
print("**************************************************************************************")
print(" Engine Configuration Folder: #{engine_config_folder}")
print(" Station Fallback Playlist: #{fallback_station_playlist_path}")
print(" Station Fallback Directory: #{fallback_station_dir}")
print("**************************************************************************************")
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment