523 lines
19 KiB
Plaintext
523 lines
19 KiB
Plaintext
def notify(m)
|
|
#current_media_id := string_of(m['schedule_table_id'])
|
|
command = "/usr/lib/airtime/pypo/bin/liquidsoap_scripts/notify.sh --data='#{!pypo_data}' --media-id=#{m['schedule_table_id']} &"
|
|
log(command)
|
|
system(command)
|
|
end
|
|
|
|
def notify_stream(m)
|
|
json_str = string.replace(pattern="\n",(fun (s) -> ""), json_of(m))
|
|
#if a string has a single apostrophe in it, let's comment it out by ending the string before right before it
|
|
#escaping the apostrophe, and then starting a new string right after it. This is why we use 3 apostrophes.
|
|
json_str = string.replace(pattern="'",(fun (s) -> "'\''"), json_str)
|
|
command = "/usr/lib/airtime/pypo/bin/liquidsoap_scripts/notify.sh --webstream='#{json_str}' --media-id=#{!current_dyn_id} &"
|
|
log(command)
|
|
system(command)
|
|
end
|
|
|
|
# A function applied to each metadata chunk
|
|
def append_title(m) =
|
|
log("Using stream_format #{!stream_metadata_type}")
|
|
if !stream_metadata_type == 1 then
|
|
[("title", "#{!show_name} - #{m['artist']}")]
|
|
elsif !stream_metadata_type == 2 then
|
|
[("title", "#{!station_name} - #{!show_name}")]
|
|
else
|
|
[("title", "#{m['artist']} - #{m['title']}")]
|
|
end
|
|
end
|
|
|
|
def crossfade(s)
|
|
#duration is automatically overwritten by metadata fields passed in
|
|
#with audio
|
|
s = fade.in(type="log", duration=0., s)
|
|
s = fade.out(type="log", duration=0., s)
|
|
fader = fun (a,b) -> add(normalize=false,[b,a])
|
|
cross(fader,s)
|
|
end
|
|
|
|
def transition(a,b) =
|
|
log("transition called...")
|
|
add(normalize=false,
|
|
[ sequence([ blank(duration=0.01),
|
|
fade.initial(duration=!default_dj_fade, b) ]),
|
|
fade.final(duration=!default_dj_fade, a) ])
|
|
end
|
|
|
|
# we need this function for special transition case(from default to queue)
|
|
# we don't want the trasition fade to have effect on the first song that would
|
|
# be played siwtching out of the default(silent) source
|
|
def transition_default(a,b) =
|
|
log("transition called...")
|
|
if !just_switched then
|
|
just_switched := false
|
|
add(normalize=false,
|
|
[ sequence([ blank(duration=0.01),
|
|
fade.initial(duration=!default_dj_fade, b) ]),
|
|
fade.final(duration=!default_dj_fade, a) ])
|
|
else
|
|
just_switched := false
|
|
b
|
|
end
|
|
end
|
|
|
|
|
|
# Define a transition that fades out the
|
|
# old source, adds a single, and then
|
|
# plays the new source
|
|
def to_live(old,new) =
|
|
# Fade out old source
|
|
old = fade.final(old)
|
|
# Compose this in sequence with
|
|
# the new source
|
|
sequence([old,new])
|
|
end
|
|
|
|
|
|
def output_to(output_type, type, bitrate, host, port, pass, mount_point, url, description, genre, user, s, stream, connected, name, channels) =
|
|
source = ref s
|
|
def on_error(msg)
|
|
connected := "false"
|
|
system("/usr/lib/airtime/pypo/bin/liquidsoap_scripts/notify.sh --error='#{msg}' --stream-id=#{stream} --time=#{!time} &")
|
|
log("/usr/lib/airtime/pypo/bin/liquidsoap_scripts/notify.sh --error='#{msg}' --stream-id=#{stream} --time=#{!time} &")
|
|
5.
|
|
end
|
|
def on_connect()
|
|
connected := "true"
|
|
system("/usr/lib/airtime/pypo/bin/liquidsoap_scripts/notify.sh --connect --stream-id=#{stream} --time=#{!time} &")
|
|
log("/usr/lib/airtime/pypo/bin/liquidsoap_scripts/notify.sh --connect --stream-id=#{stream} --time=#{!time} &")
|
|
end
|
|
|
|
stereo = (channels == "stereo")
|
|
|
|
if output_type == "icecast" then
|
|
user_ref = ref user
|
|
if user == "" then
|
|
user_ref := "source"
|
|
end
|
|
output_mono = output.icecast(host = host,
|
|
port = port,
|
|
password = pass,
|
|
mount = mount_point,
|
|
fallible = true,
|
|
url = url,
|
|
description = description,
|
|
name = name,
|
|
genre = genre,
|
|
user = !user_ref,
|
|
on_error = on_error,
|
|
on_connect = on_connect)
|
|
|
|
output_stereo = output.icecast(host = host,
|
|
port = port,
|
|
password = pass,
|
|
mount = mount_point,
|
|
fallible = true,
|
|
url = url,
|
|
description = description,
|
|
name = name,
|
|
genre = genre,
|
|
user = !user_ref,
|
|
on_error = on_error,
|
|
on_connect = on_connect)
|
|
if type == "mp3" then
|
|
if bitrate == 24 then
|
|
if stereo then
|
|
ignore(output_stereo(%mp3(bitrate = 24, stereo = true), !source))
|
|
else
|
|
ignore(output_mono(%mp3(bitrate = 24, stereo = false), mean(!source)))
|
|
end
|
|
elsif bitrate == 32 then
|
|
if stereo then
|
|
ignore(output_stereo(%mp3(bitrate = 32, stereo = true), !source))
|
|
else
|
|
ignore(output_mono(%mp3(bitrate = 32, stereo = false), mean(!source)))
|
|
end
|
|
elsif bitrate == 48 then
|
|
if stereo then
|
|
ignore(output_stereo(%mp3(bitrate = 48, stereo = true), !source))
|
|
else
|
|
ignore(output_mono(%mp3(bitrate = 48, stereo = false), mean(!source)))
|
|
end
|
|
elsif bitrate == 64 then
|
|
if stereo then
|
|
ignore(output_stereo(%mp3(bitrate = 64, stereo = true), !source))
|
|
else
|
|
ignore(output_mono(%mp3(bitrate = 64, stereo = false), mean(!source)))
|
|
end
|
|
elsif bitrate == 96 then
|
|
if stereo then
|
|
ignore(output_stereo(%mp3(bitrate = 96, stereo = true), !source))
|
|
else
|
|
ignore(output_mono(%mp3(bitrate = 96, stereo = false), mean(!source)))
|
|
end
|
|
elsif bitrate == 128 then
|
|
if stereo then
|
|
ignore(output_stereo(%mp3(bitrate = 128, stereo = true), !source))
|
|
else
|
|
ignore(output_mono(%mp3(bitrate = 128, stereo = false), mean(!source)))
|
|
end
|
|
elsif bitrate == 160 then
|
|
if stereo then
|
|
ignore(output_stereo(%mp3(bitrate = 160, stereo = true), !source))
|
|
else
|
|
ignore(output_mono(%mp3(bitrate = 160, stereo = false), mean(!source)))
|
|
end
|
|
elsif bitrate == 192 then
|
|
if stereo then
|
|
ignore(output_stereo(%mp3(bitrate = 192, stereo = true), !source))
|
|
else
|
|
ignore(output_mono(%mp3(bitrate = 192, stereo = false), mean(!source)))
|
|
end
|
|
elsif bitrate == 224 then
|
|
if stereo then
|
|
ignore(output_stereo(%mp3(bitrate = 224, stereo = true), !source))
|
|
else
|
|
ignore(output_mono(%mp3(bitrate = 224, stereo = false), mean(!source)))
|
|
end
|
|
elsif bitrate == 256 then
|
|
if stereo then
|
|
ignore(output_stereo(%mp3(bitrate = 256, stereo = true), !source))
|
|
else
|
|
ignore(output_mono(%mp3(bitrate = 256, stereo = false), mean(!source)))
|
|
end
|
|
elsif bitrate == 320 then
|
|
if stereo then
|
|
ignore(output_stereo(%mp3(bitrate = 320, stereo = true), !source))
|
|
else
|
|
ignore(output_mono(%mp3(bitrate = 320, stereo = false), mean(!source)))
|
|
end
|
|
end
|
|
else
|
|
if not icecast_vorbis_metadata then
|
|
source := add(normalize=false, [amplify(0.00001, noise()), !source])
|
|
end
|
|
|
|
if bitrate == 24 or bitrate == 32 or bitrate == 48 then
|
|
if stereo then
|
|
ignore(output_stereo(%vorbis(quality=-0.1, channels = 2), !source))
|
|
else
|
|
ignore(output_mono(%vorbis(quality=-0.1, channels = 1), mean(!source)))
|
|
end
|
|
elsif bitrate == 64 then
|
|
if stereo then
|
|
ignore(output_stereo(%vorbis(quality=0, channels = 2), !source))
|
|
else
|
|
ignore(output_mono(%vorbis(quality=0, channels = 1), mean(!source)))
|
|
end
|
|
elsif bitrate == 96 then
|
|
if stereo then
|
|
ignore(output_stereo(%vorbis(quality=0.2, channels = 2), !source))
|
|
else
|
|
ignore(output_mono(%vorbis(quality=0.2, channels = 1), mean(!source)))
|
|
end
|
|
elsif bitrate == 128 then
|
|
if stereo then
|
|
ignore(output_stereo(%vorbis(quality=0.4, channels = 2), !source))
|
|
else
|
|
ignore(output_mono(%vorbis(quality=0.4, channels = 1), mean(!source)))
|
|
end
|
|
elsif bitrate == 160 then
|
|
if stereo then
|
|
ignore(output_stereo(%vorbis(quality=0.5, channels = 2), !source))
|
|
else
|
|
ignore(output_mono(%vorbis(quality=0.5, channels = 1), mean(!source)))
|
|
end
|
|
elsif bitrate == 192 then
|
|
if stereo then
|
|
ignore(output_stereo(%vorbis(quality=0.6, channels = 2), !source))
|
|
else
|
|
ignore(output_mono(%vorbis(quality=0.6, channels = 1), mean(!source)))
|
|
end
|
|
elsif bitrate == 224 then
|
|
if stereo then
|
|
ignore(output_stereo(%vorbis(quality=0.7, channels = 2), !source))
|
|
else
|
|
ignore(output_mono(%vorbis(quality=0.7, channels = 1), mean(!source)))
|
|
end
|
|
elsif bitrate == 256 then
|
|
if stereo then
|
|
ignore(output_stereo(%vorbis(quality=0.8, channels = 2), !source))
|
|
else
|
|
ignore(output_mono(%vorbis(quality=0.8, channels = 1), mean(!source)))
|
|
end
|
|
elsif bitrate == 320 then
|
|
if stereo then
|
|
ignore(output_stereo(%vorbis(quality=0.9, channels = 2), !source))
|
|
else
|
|
ignore(output_mono(%vorbis(quality=0.9, channels = 1), mean(!source)))
|
|
end
|
|
end
|
|
end
|
|
else
|
|
user_ref = ref user
|
|
if user == "" then
|
|
user_ref := "source"
|
|
end
|
|
|
|
description_ref = ref description
|
|
if description == "" then
|
|
description_ref := "N/A"
|
|
end
|
|
|
|
genre_ref = ref genre
|
|
if genre == "" then
|
|
genre_ref := "N/A"
|
|
end
|
|
|
|
url_ref = ref url
|
|
if url == "" then
|
|
url_ref := "N/A"
|
|
end
|
|
output.shoutcast_mono = output.shoutcast(id = "shoutcast_stream_#{stream}",
|
|
host = host,
|
|
port = port,
|
|
password = pass,
|
|
fallible = true,
|
|
url = !url_ref,
|
|
genre = !genre_ref,
|
|
name = !description_ref,
|
|
user = !user_ref,
|
|
on_error = on_error,
|
|
on_connect = on_connect)
|
|
|
|
output.shoutcast_stereo = output.shoutcast(id = "shoutcast_stream_#{stream}",
|
|
host = host,
|
|
port = port,
|
|
password = pass,
|
|
fallible = true,
|
|
url = !url_ref,
|
|
genre = !genre_ref,
|
|
name = !description_ref,
|
|
user = !user_ref,
|
|
on_error = on_error,
|
|
on_connect = on_connect)
|
|
|
|
if bitrate == 24 then
|
|
if stereo then
|
|
ignore(output.shoutcast_stereo(%mp3(bitrate = 24, stereo = true), !source))
|
|
else
|
|
ignore(output.shoutcast_mono(%mp3(bitrate = 24, stereo = false), mean(!source)))
|
|
end
|
|
elsif bitrate == 32 then
|
|
if stereo then
|
|
ignore(output.shoutcast_stereo(%mp3(bitrate = 32, stereo = true), !source))
|
|
else
|
|
ignore(output.shoutcast_mono(%mp3(bitrate = 32, stereo = false), mean(!source)))
|
|
end
|
|
elsif bitrate == 48 then
|
|
if stereo then
|
|
ignore(output.shoutcast_stereo(%mp3(bitrate = 48, stereo = true), !source))
|
|
else
|
|
ignore(output.shoutcast_mono(%mp3(bitrate = 48, stereo = false), mean(!source)))
|
|
end
|
|
elsif bitrate == 64 then
|
|
if stereo then
|
|
ignore(output.shoutcast_stereo(%mp3(bitrate = 64, stereo = true), !source))
|
|
else
|
|
ignore(output.shoutcast_mono(%mp3(bitrate = 64, stereo = false), mean(!source)))
|
|
end
|
|
elsif bitrate == 96 then
|
|
if stereo then
|
|
ignore(output.shoutcast_stereo(%mp3(bitrate = 96, stereo = true), !source))
|
|
else
|
|
ignore(output.shoutcast_mono(%mp3(bitrate = 96, stereo = false), mean(!source)))
|
|
end
|
|
elsif bitrate == 128 then
|
|
if stereo then
|
|
ignore(output.shoutcast_stereo(%mp3(bitrate = 128, stereo = true), !source))
|
|
else
|
|
ignore(output.shoutcast_mono(%mp3(bitrate = 128, stereo = false), mean(!source)))
|
|
end
|
|
elsif bitrate == 160 then
|
|
if stereo then
|
|
ignore(output.shoutcast_stereo(%mp3(bitrate = 160, stereo = true), !source))
|
|
else
|
|
ignore(output.shoutcast_mono(%mp3(bitrate = 160, stereo = false), mean(!source)))
|
|
end
|
|
elsif bitrate == 192 then
|
|
if stereo then
|
|
ignore(output.shoutcast_stereo(%mp3(bitrate = 192, stereo = true), !source))
|
|
else
|
|
ignore(output.shoutcast_mono(%mp3(bitrate = 192, stereo = false), mean(!source)))
|
|
end
|
|
elsif bitrate == 224 then
|
|
if stereo then
|
|
ignore(output.shoutcast_stereo(%mp3(bitrate = 224, stereo = true), !source))
|
|
else
|
|
ignore(output.shoutcast_mono(%mp3(bitrate = 224, stereo = false), mean(!source)))
|
|
end
|
|
elsif bitrate == 256 then
|
|
if stereo then
|
|
ignore(output.shoutcast_stereo(%mp3(bitrate = 256, stereo = true), !source))
|
|
else
|
|
ignore(output.shoutcast_mono(%mp3(bitrate = 256, stereo = false), mean(!source)))
|
|
end
|
|
elsif bitrate == 320 then
|
|
if stereo then
|
|
ignore(output.shoutcast_stereo(%mp3(bitrate = 320, stereo = true), !source))
|
|
else
|
|
ignore(output.shoutcast_mono(%mp3(bitrate = 320, stereo = false), mean(!source)))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
# Add a skip function to a source
|
|
# when it does not have one
|
|
# by default
|
|
def add_skip_command(s)
|
|
# A command to skip
|
|
def skip(_)
|
|
# get playing (active) queue and flush it
|
|
l = list.hd(server.execute("queue.secondary_queue"))
|
|
l = string.split(separator=" ",l)
|
|
list.iter(fun (rid) -> ignore(server.execute("queue.remove #{rid}")), l)
|
|
|
|
l = list.hd(server.execute("queue.primary_queue"))
|
|
l = string.split(separator=" ", l)
|
|
if list.length(l) > 0 then
|
|
source.skip(s)
|
|
"Skipped"
|
|
else
|
|
"Not skipped"
|
|
end
|
|
end
|
|
# Register the command:
|
|
server.register(namespace="source",
|
|
usage="skip",
|
|
description="Skip the current song.",
|
|
"skip",fun(s) -> begin log("source.skip") skip(s) end)
|
|
end
|
|
|
|
dyn_out = output.icecast(%wav,
|
|
host="localhost",
|
|
port=8999,
|
|
password=stream_harbor_pass,
|
|
mount="test-harbor",
|
|
fallible=true)
|
|
|
|
def set_dynamic_source_id(id) =
|
|
current_dyn_id := id
|
|
string_of(!current_dyn_id)
|
|
end
|
|
|
|
# Function to create a playlist source and output it.
|
|
def create_dynamic_source(uri) =
|
|
# The playlist source
|
|
s = audio_to_stereo(input.http(buffer=2., max=12., uri))
|
|
|
|
# The output
|
|
active_dyn_out = dyn_out(s)
|
|
|
|
# We register both source and output
|
|
# in the list of sources
|
|
dyn_sources :=
|
|
list.append([(uri,s),(uri,active_dyn_out)], !dyn_sources)
|
|
|
|
notify([("schedule_table_id", !current_dyn_id)])
|
|
"Done!"
|
|
end
|
|
|
|
|
|
# A function to destroy a dynamic source
|
|
def destroy_dynamic_source_all(uri) =
|
|
# We need to find the source in the list,
|
|
# remove it and destroy it. Currently, the language
|
|
# lacks some nice operators for that so we do it
|
|
# the functional way
|
|
|
|
# This function is executed on every item in the list
|
|
# of dynamic sources
|
|
def parse_list(ret, current_element) =
|
|
# ret is of the form: (matching_sources, remaining_sources)
|
|
# We extract those two:
|
|
matching_sources = fst(ret)
|
|
remaining_sources = snd(ret)
|
|
|
|
# current_element is of the form: ("uri", source) so
|
|
# we check the first element
|
|
current_uri = fst(current_element)
|
|
# in this case, we add the source to the list of
|
|
# matched sources
|
|
(list.append( [snd(current_element)],
|
|
matching_sources),
|
|
remaining_sources)
|
|
end
|
|
|
|
# now we execute the function:
|
|
result = list.fold(parse_list, ([], []), !dyn_sources)
|
|
matching_sources = fst(result)
|
|
remaining_sources = snd(result)
|
|
|
|
# we store the remaining sources in dyn_sources
|
|
dyn_sources := remaining_sources
|
|
|
|
# if no source matched, we return an error
|
|
if list.length(matching_sources) == 0 then
|
|
"error: no matching sources!"
|
|
else
|
|
# we stop all sources
|
|
list.iter(source.shutdown, matching_sources)
|
|
# And return
|
|
"Done!"
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
# A function to destroy a dynamic source
|
|
def destroy_dynamic_source(uri) =
|
|
# We need to find the source in the list,
|
|
# remove it and destroy it. Currently, the language
|
|
# lacks some nice operators for that so we do it
|
|
# the functional way
|
|
|
|
# This function is executed on every item in the list
|
|
# of dynamic sources
|
|
def parse_list(ret, current_element) =
|
|
# ret is of the form: (matching_sources, remaining_sources)
|
|
# We extract those two:
|
|
matching_sources = fst(ret)
|
|
remaining_sources = snd(ret)
|
|
|
|
# current_element is of the form: ("uri", source) so
|
|
# we check the first element
|
|
current_uri = fst(current_element)
|
|
if current_uri == uri then
|
|
# In this case, we add the source to the list of
|
|
# matched sources
|
|
(list.append( [snd(current_element)],
|
|
matching_sources),
|
|
remaining_sources)
|
|
else
|
|
# In this case, we put the element in the list of remaining
|
|
# sources
|
|
(matching_sources,
|
|
list.append([current_element],
|
|
remaining_sources))
|
|
end
|
|
end
|
|
|
|
# Now we execute the function:
|
|
result = list.fold(parse_list, ([], []), !dyn_sources)
|
|
matching_sources = fst(result)
|
|
remaining_sources = snd(result)
|
|
|
|
# We store the remaining sources in dyn_sources
|
|
dyn_sources := remaining_sources
|
|
|
|
# If no source matched, we return an error
|
|
if list.length(matching_sources) == 0 then
|
|
"Error: no matching sources!"
|
|
else
|
|
# We stop all sources
|
|
list.iter(source.shutdown, matching_sources)
|
|
# And return
|
|
"Done!"
|
|
end
|
|
end
|
|
|
|
|