Get json
specified metadata
#3760
-
Hi! So I've been experimenting with harbor and stuff. After a bunch of iterations I couldn't come up with a simple feature :( All I want is to send only metadata which I specify. For example: only "artist" and "title". I can use this: meta = ref([])
s.on_metadata(fun (m) -> meta := m)
def get_meta(_, response) =
response.json(meta())
end
harbor.http.register(port=7000, method="GET", "/getmeta", get_meta) But it gives me a massive amount of info. How can I reduce this array to the data I need? Or even better: how to determine it by hand? |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 18 replies
-
I think that you need to specify which metadata you want exported. We provide metadata.export which is based on https://www.liquidsoap.info/doc-2.2.4/settings.html#exported-metadata. Otherwise, you can code your own filter. |
Beta Was this translation helpful? Give feedback.
-
Well, it seems handy but unclear for me) |
Beta Was this translation helpful? Give feedback.
-
Hi @gAlleb, You can use |
Beta Was this translation helpful? Give feedback.
-
Hi, @vitoyucepi! Been trying out how are things with This is the function which works flawlessly in 2.2.5: def write_json_nowplaying(omfm_0)
def write_data()
def null_float(f)
f == infinity ? null() : f
end
def null_list(key, _list)
list.assoc.mem(key, _list) ? list.assoc(key, _list) : null()
end
m = omfm_0.last_metadata() ?? []
file_duration = null.get(default=0.0, request.duration(m["filename"]))
pre_artist = null_list("artist", m)
pre_title = null_list("title", m)
default_stream_title = "Default" # null()
stream_title =
if pre_title == null() then
default_stream_title
elsif pre_artist == null() then
pre_title
else
"#{pre_artist} - #{pre_title}"
end
artist = ref("")
title = ref("")
if pre_artist == null() then
if string.contains(substring=" - ", m["title"]) then
let (a, t) = string.split.first(separator=" - ", m["title"])
title := t
artist := a
end
else
title := pre_title
artist := pre_artist
end
np = {
station = {
name = "omFM",
shortcode = "radio",
timezone = "Europe/Moscow"
},
now_playing = {
played_at = null_list("on_air_timestamp", m),
played_at_timestamp = null_list("on_air_timestamp", m),
played_at_date_time = null_list("on_air", m),
duration = null_float(source.duration(omfm_0)),
elapsed = null_float(source.elapsed(omfm_0)),
remaining = null_float(source.remaining(omfm_0)),
playlist = null_list("playlist", m),
filename = null_list("filename", m),
song = {
text = stream_title,
artist = artist(),
title = title(),
album = null_list("album", m),
genre = null_list("genre", m),
song_duration = null_float(file_duration)
}
#playlist = source.id(omfm_0),
},
song_history = songHistory()
}
if (m["jingle_mode"] != "true") then
send_mq_event(json.stringify(np, compact=true))
end
end
thread.run(write_data, every=1.0, fast=false)
end
write_json_nowplaying(omfm_0) But gives an error in 2.3.0 At /home/radio/liquidsoap/omfm/omfm.liq, line 536, char 22-28:
write_json_nowplaying(omfm_0)
Error 5: this value has type
_.{last_metadata : (...) -> _?} (inferred at /home/radio/liquidsoap/omfm/omfm.liq, line 103 char 9 - line 107 char 2)
but it should be a subtype of
_.{last_metadata? : (...) -> [_]} I've tried lots of things: editing/deleting some of the lines. With every iteration new inconsistency appears. In 2.2.5 - this works fine. Same goes for another function with harbour: def get_metadata(_)
def null_float(f)
f == infinity ? null() : f
end
def null_list(key, _list)
list.assoc.mem(key, _list) ? list.assoc(key, _list) : null()
end
#log("method: #{request.method}")
m = omfm_0.last_metadata() ?? []
file_duration = null.get(default=0.0, request.duration(m["filename"]))
pre_artist = null_list("artist", m)
pre_title = null_list("title", m)
default_stream_title = "Default" # null()
stream_title =
if pre_title == null() then
default_stream_title
elsif pre_artist == null() then
pre_title
else
"#{pre_artist} - #{pre_title}"
end
artist = ref("")
title = ref("")
if pre_artist == null() then
if string.contains(substring=" - ", m["title"]) then
let (a, t) = string.split.first(separator=" - ", m["title"])
title := t
artist := a
end
else
title := pre_title
artist := pre_artist
end
data = {
station = {
name = "omFM",
shortcode = "radio",
timezone = "Europe/Moscow"
},
now_playing = {
played_at = null_list("on_air_timestamp", m),
played_at_timestamp = null_list("on_air_timestamp", m),
played_at_date_time = null_list("on_air", m),
duration = null_float(source.duration(omfm_0)),
elapsed = null_float(source.elapsed(omfm_0)),
remaining = null_float(source.remaining(omfm_0)),
playlist = null_list("playlist", m),
filename = null_list("filename", m),
song = {
text = stream_title,
artist = artist(),
title = title(),
album = null_list("album", m),
genre = null_list("genre", m),
song_duration = null_float(file_duration)
}
#playlist = source.id(omfm_0),
},
song_history = songHistory()
}
try
http.response(
status_code=200,
headers=[
("Content-Type", "application/json"),
("Access-Control-Allow-Origin","*")
],
content_type="application/json; charset=UTF-8",
data=json.stringify(data, compact=true) ^ "\n"
)
catch error do
log.severe(error.message, label="http")
http.response(
status_code=500,
content_type="application/json; charset=UTF-8",
data='{"status":"error","message":"Failed to serialize response data"}' ^ "\n"
)
end
end
harbor.http.register.simple("/nowplaying", get_metadata, port=8007, method="GET") It gives me:
Ok, if I get rid of
And so on and so on :) As you see almost every error is connected with something being However I've got a def telegram_omFM(m)
def handle_error(error)
log.important(
"Unable to send Telegram event. #{error.message}",
label="Telegram"
)
end
def null_list(key, _list)
list.assoc.mem(key, _list) ? list.assoc(key, _list) : null()
end
if (m["jingle_mode"] != "true") then
pre_artist = null_list("artist", m)
pre_title = null_list("title", m)
artist = ref("")
title = ref("")
if pre_artist == null() then
if string.contains(substring=" - ", m["title"]) then
let (a, t) = string.split.first(separator=" - ", m["title"])
title := t
artist := a
end
else
title := pre_title
artist := pre_artist
end
try
process.run("telegram-send-omfm 'Now playing: #{artist()} - #{title()}'")
catch error do
handle_error(error)
end
end
end
omfm_0.on_metadata(telegram_omFM) Magic! :) Could you turn it into science? Thanks! |
Beta Was this translation helpful? Give feedback.
-
Got a question. songHistory = ref([])
def save_history(m, ~last=10)
def null_list(key, _list)
list.assoc.mem(key, _list) ? list.assoc(key, _list) : ""
end
def null_float(f)
f == infinity ? null() : f
end
pre_artist = null_list("artist", m)
pre_title = null_list("title", m)
default_stream_title = "Default" # null()
stream_title =
if pre_title == "" then
default_stream_title
elsif pre_artist == "" then
pre_title
else
"#{pre_artist} - #{pre_title}"
end
artist = ref("")
title = ref("")
if pre_artist == "" then
if string.contains(substring=" - ", m["title"]) then
let (a, t) = string.split.first(separator=" - ", m["title"])
title := t
artist := a
end
else
title := pre_title
artist := pre_artist
end
if (m["jingle_mode"] != "true") then
sh = {
played_at = null_list("on_air_timestamp", m),
played_at_timestamp = null_list("on_air_timestamp", m),
played_at_date_time = null_list("on_air", m),
playlist = null_list("playlist", m),
filename = null_list("filename", m),
song = {
text = stream_title,
artist = artist(),
title = title(),
album = null_list("album", m),
genre = null_list("genre", m)
}
}
songHistory := sh::songHistory()
if list.length(songHistory()) > last then
songHistory := list.prefix(last,songHistory())
end
end
end
s.on_metadata(save_history) What can I do to restore it when LS restarts? Save it to json and on restart parse it? Sounds complicated - there are 10 positions and I have no clue how. |
Beta Was this translation helpful? Give feedback.
Hi @gAlleb,
You can use
source.last_metadata() ?? []
to get the last known metadata for source.Compared to previous question you have to use
json()
because metadata has unknown keys. If you want to use a known set of keys, thenrecord
would be fine.Also, you should use base64 if you want to send an image.