TOTH playlist plays "old" time announcements, from long ago (resolved too early?) #3799
Replies: 12 comments 21 replies
-
Did a few more experiments locally:
This seems to work somehow: I do get an announcement every 5 minutes, but the time is off by 6 minutes. Looking at the logs, it seems the request is prepared much too early, thus picking up an "old" time file. (This gets rewritten every minute to always play the current time.) How can I ensure that it always resolves "late", i.e. picks up the current time file? (The idea behind all that is that I have a playlist with time announcements that are always current, so can be played anytime and everywhere, always announcing the correct time. See also this article: https://blog.syvi.net/tech-snippets/time-und-station-id-announcement-toth-in-azuracast-using-text-to-speech) In case anyone wants to reproduce this, here is the bash script that gets invoked by crontab every minute and generates the time file: #!/bin/bash
# saytime-en
# 2015-07-16 Moonbase
# 2023-03-09 Moonbase (update to PicoTTS; pico2wave & sox must be installed)
# Create /tmp/time.en-GB.wav for Liquidsoap to announce current time.
# Put this script into your ~/bin folder (or ~/.local/bin, or /usr/local/bin).
# 2023-05-28 Moonbase Adapted to AzuraCast
# On a Ubuntu Server, install required modules as follows:
# sudo apt install libttspico-utils sox libsox-fmt-mp3
# Install this file into /usr/local/bin and use root's crontab to run every minute.
# 2023-05-29 Moonbase Simplified silence generation
#
# crontab entry, to keep the file current, like so:
# */1 * * * * /usr/local/bin/saytime-en > /dev/null
# Possible output languages (might require different sox post-processing):
# de-DE - German
# en-GB - British Englisch
# en-US - US Englisch
# fr-FR - French
# it-IT - Italian
# es-ES - Spanish
lang="en-GB" # language for PicoTTS
locale="en_GB.utf8" # (installed!) OS locale
tz='Europe/Berlin' # desired timezone
# In case you wish to copy the file from /tmp into your media folder, specify it here.
# Use a trailing slash for folder names ("/folder/").
# You can also specify a full MP3 file name ("/folder/time-signal.mp3")
media_folder="/var/azuracast/time/"
# silence to add before/after the spoken text, in seconds; empty string for none
#pad="pad 3 3"
pad="pad 2 0"
# English
AMPM="$(LC_ALL=$locale TZ=$tz date +'%p')"
AMPM="${AMPM^^}" # uppercase it
TIME="$(LC_ALL=$locale TZ=$tz date +'%l:%M ')${AMPM}"
TOTH="$(LC_ALL=$locale TZ=$tz date +"%l o'clock ")${AMPM}"
MIN="$(LC_ALL=$locale TZ=$tz date +'%-M')"
DAY="$(LC_ALL=$locale TZ=$tz date +'%A')"
ZERO="oh" # to pronounce the zero when minutes < 10 ("three oh two PM")
# German
#AMPM="$(LC_ALL=$locale TZ=$tz date +'%p')"
#AMPM="${AMPM^^}" # uppercase it
#TIME="$(LC_ALL=$locale TZ=$tz date +'%-H Uhr %-M')"
#TOTH="$(LC_ALL=$locale TZ=$tz date +'genau %-H Uhr')"
#MIN="$(LC_ALL=$locale TZ=$tz date +'%-M')"
#DAY="$(LC_ALL=$locale TZ=$tz date +'%A')"
#ZERO="Uhr" # to pronounce the zero when minutes < 10 ("three oh two PM")
if [ "$MIN" -lt 10 ]; then
TIME="$(LC_ALL=$locale TZ=$tz date +'%l') $ZERO $MIN $AMPM"
fi
if [ "$MIN" -eq 0 ]; then
TIME="$TOTH"
fi
# diag only
#echo $DAY, $TIME
# English
# build text (adapt volume level 0..100)
text='<volume level="100">'"It's $DAY, $TIME, and you're listening to Night Radio.</volume>"
# German
# build text (adapt volume level 0..100), 2s silence at beginning and end
#text='<volume level="100">'"Es ist $DAY, $TIME, und du hörst Nait Räidio.</volume>"
# create WAV audio file using PicoTTS
pico2wave -l=$lang -w=/tmp/time.$lang.wav "$text"
# use sox to make output better understandable (voices are rather muffled)
# we also add some silence at the beginning and end here, if so requested
# adding some treble in the range of +3 to +6 dB helps
# some voices might need a little bass reduction, use s/th like "bass -6 400"
# to avoid clipping, give headroom (gain -h) and reclaim afterwards (gain -r)
# skip the "compand" part if you don’t want compression/limiting.
sox /tmp/time.$lang.wav -c2 -r 44100 -C 128 /tmp/time.$lang.mp3 gain -h bass +2 treble +3 gain -r compand 0.008,0.024 -60,-60,-40,-35,0,-20 10 -60 $pad
# copy it into our media folder
mv /tmp/time.$lang.mp3 "$media_folder"
# diag only: play it loud
#play /tmp/time.$lang.mp3 The funny thing is this worked for many months now on my real AzuraCast stations, using just one predicate, namely
|
Beta Was this translation helpful? Give feedback.
-
I wonder what’s happening here: Reverted back to the single-predicate (
Within the AzuraCast Docker, a
Playing the file from the station’s "On-demand" page plays the correct time. From the log:
(The fail might come from the obscure bug mentioned in #3714) |
Beta Was this translation helpful? Give feedback.
-
I can't reproduce this behavior, am I missing something?
|
Beta Was this translation helpful? Give feedback.
-
Hi, @vitoyucepi, thanks for testing! Yours seems to work, but as soon as I use a predicate string inside the switch it fails, i.e. announces "9 minutes" at 9:10.
Since I only wanted to use half-hour instead of hourly announcements, I thought directly adding the time predicate would be good enough, without adding complicated functions… But it appears there is something going on there, maybe resolving too early, caching, or whatever. Maybe it also behaves differently when lots of other things are going on, as in a real AzuraCast station? Or maybe I don’t understand the time predicate syntax? When changing above to
to "play safe" and give it a little more time, it also seems to work. I’m at my wit’s end here. Maybe the minimal script is just too simple? I’ll try to reduce my local testing script a little, so you could test that. |
Beta Was this translation helpful? Give feedback.
-
Hm. All local tests seem to work now, maybe because they’re fast enough…? On the real station, it’s still one hour off. Let’s look at the log of my test station:
The switch starts at 15:00:15, and plays "It’s 2 o’clock p.m.", so one hour off. Looking closely, I see a Would you say this indicates the station took longer to prepare the actual time, so it was ready only at 15:00:22 and thus played "the old one" at 15:00:15? I’m trying to set the predicate to |
Beta Was this translation helpful? Give feedback.
-
On the first run through (it was just 11:00), using
So it seems on a "real" station preparing the request can take quite a while. I only wonder why, at 11:00:36, it prepares it again? The actual code used on this station is:
|
Beta Was this translation helpful? Give feedback.
-
30s isn’t good either: Still plays one hour off at several stations. I wonder how I could force it to re-prepare/re-read the real file instead of using something old (apparently prepared immediately after the last playout). Such simple things as playing a "time file" often turn out being extremely complicated with LS… sigh… |
Beta Was this translation helpful? Give feedback.
-
To what? The playout (time file) already announces hours & minutes, just abbreviates to "xx o'clock sharp" or "Genau xx Uhr" if minutes are zero.
crontab only has a granularity of minutes. Should be good enough, I’m thinking. We don’t want to keep VMs running unneeded stuff every second or so… And besides, if run "early", it would of course also announce the earlier time ("23:59"). The concept of generating minute-exact "time files" is based on some old code of mine from 2013 or so, that has been in use ever since (and the files also used in some other places). I think it started out with me using SAM PAL automation, Rivendell, and/or LS 1.4 at that time. :-)
Totally wouldn’t know how to do that. Starts looking like becoming an overcomplicated workaround for a simple problem again, somehow… But of course I’d still be interested in a working, stable solution. |
Beta Was this translation helpful? Give feedback.
-
@vitoyucepi @gAlleb Appreciate your help, but are we trying to hunt a (possible) bug here (as you asking for creation time data indicates), or find new, creative solutions? If it helps diagnosing, I can of course make But let me make the situation more clear: My basic intention was to provide AzuraCast users with an easy way to use date/time announcements, as a With AzuraCast, we usually have a VM somewhere in the cloud, that in turn runs an AzuraCast Docker that in turn runs several Liquidsoap instances (one per station). The Docker is a rather barebone OS, thus has not all the tools like So I decided it would be easier to implement all this on the host (not within the Docker) using some bash scripts, invoked once per minute using a crontab, and have their result files stored in a Hope this explains my goals and the setup a little better. Make it easy for an average station owner who is not a programmer. And now I’m open for any suggestions on how to make this come real—either by fixing a possible bug, or by coming up with a solution that’s easy for the user. ;-) I wonder if we could use |
Beta Was this translation helpful? Give feedback.
-
Btw, I even tried
It really looks like after using one playlist entry, LS immediately prefetches the next item and uses that for the next playout—resulting in the time time announcement for Seems to me LS tries—for all playlists—to have "the next one" entry ready for immediate playout start as soon as possible. Which, in our case, of course leads to the pre-generated entry having the time it was generated at (the prefetch time, not the current time). You’d never notice this behaviour with normal songs, but with dynamically generated content you do. This would also explain why adding a time announcement to any "normal" playlist always works better (because other songs come in between), but not in the case of a playlist with just one file entry (because LS thinks it has the next one ready from an hour before). So what we probably want is some mechanism that tells LS to get the next playlist entry now, instead of "any time". |
Beta Was this translation helpful? Give feedback.
-
Next problem: AzuraCast defines an advanced playlist as
When using
I get this error:
Just why can’t something easy just work, for a change? |
Beta Was this translation helpful? Give feedback.
-
TL;DR (Recap): If you want a smoothly overlaid top-of-the-hour time announcement,
Done! The system should now
|
Beta Was this translation helpful? Give feedback.
-
I have a one-file TOTH playlist that should announce the time every half hour. The actual file gets regenerated every minute, so is always correct. But the announcement repeats twice, so every half hour the time announced is off by ½ hour.
What am I overlooking?
Using Liquidsoap 2.2.4-1.
Beta Was this translation helpful? Give feedback.
All reactions