Create and play audio announcements automatically — Shell script

ard-Site
5 min readOct 12, 2019

How to use a shell script to make automatic announcements in audio format. This can be used, for example, to automatically output error messages (from services, applications), messages or the weather via an audio interface (e.g.: Internet radio station in the intranet or Internet, RSS podcast, etc.).

A use case is here shown where this shell script automatically creates and outputs announcements over a radio stream. This use case is similar to the announcements you hear at the airport or train station. Something similar is implemented here via an Icecast2 streaming server, which can also be used in the local network to output messages in audio format over loudspeakers at home or in the company.

It can also use this shell script, if it edits something, for other use cases.

Prerequisites

The following must be set up before creating the shell script:

1. If you want to access information or messages via RSS: The RSStail program
Can be installed via package manager apt: sudo apt-get install rsstail
More about rsstail: http://manpages.ubuntu.com/manpages/xenial/man1/rsstail.1.html

2. Internet radio streaming server (set up with icecast2 and ices) with functioning streaming
This is used here as medium for the output of the created announcements. The Internet radio here is silent and plays nothing except when messages need to be output.
There is also a tutorial on how to set up the Internet radio streaming server on my website.

Attention! In this case, the playlist must only contain an audio file that does not output sound. You can download and use this audio file here: https://ard-site.net/downloads/mute_state.mp3

The playlist playlist_live.pls is used here, which contains only the file mute_state.mp3.

3. The program: jq
A program to output values and contents of JSON files. Used in this case to output the weather.
Can be installed via apt package manager: sudo apt-get install jq
More about jq: http://manpages.ubuntu.com/manpages/bionic/man1/jq.1.html

4. The text-to-speech software: gtts
Gtts can be downloaded via the package manager pip or from the website pypi (https://pypi.org/project/gTTS/)
There is a tutorial here on the website on how to install the text-to-speech software.

5. If you want to add intro music for the announcements: ffmpeg
Can be installed via apt package manager: sudo apt-get install ffmpeg

6. The audio file announcement_intro.mp3
This audio file is the intro music that is played before the announcement. It may only be in mp3 format.

7. A playlist with only the audio file for the announcement
A playlist announcement_playlist.pls is created here. It only contains the file /home/ubuntu/announcement.mp3

The shell script

  • The text to be output as audio can be found here in the file: /home/ubuntu/announcement_text.txt
  • The messages/information from an RSS feed are stored in this file: /home/ubuntu/announcement_information.txt

The user account ubuntu is used here. You may need to make some changes to the script. The shell script runs as root here.

Creating a shell script

vim /home/ubuntu/play_announcement.sh

The shell script has the following content:

#!/bin/sh#Greetings
greetingtext="This is an important communication. "
echo $greetingtext > /home/ubuntu/announcement_text.txt
#Say the current time
_timetext="It is "
_timetext+=$(env TZ=Europe/London date +"%-H")
_timetext+="O Clock."
echo $_timetext >> /home/ubuntu/announcement_text.txt
#Retrieve messages/information to be output - Title and description of a feed entry
su ubuntu -c "rsstail -N -d -z -P -n 1 -u http://myfeed.tld/myfeed_file.xml > /home/ubuntu/announcement_information.txt &"
cat /home/ubuntu/announcement_information.txt >> /home/ubuntu/announcement_text.txt
#closing text
endtext="Thank you very much for your attention. "
echo $endtext >> /home/ubuntu/announcement_text.txt
#Convert text to audio file - Please adjust language if necessary
rm /home/ubuntu/announcement.mp3
rm /home/ubuntu/announcement_temp.mp3
rm /home/ubuntu/announcement_temp2.mp3
su ubuntu -c "/usr/local/bin/gtts-cli -f /home/ubuntu/announcement_text.txt -l 'en' -o /home/ubuntu/announcement_temp.mp3"
#Making the audio file louder
ffmpeg -i /home/ubuntu/announcement_temp.mp3 -filter:a "volume=16dB" -b:a 128k /home/ubuntu/announcement_temp2.mp3
#Added an intro music - The finished file is now in: /home/ubuntu/announcement.mp3
ffmpeg -y -i /home/ubuntu/announcement_intro.mp3 -i /home/ubuntu/announcement_temp2.mp3 -filter_complex "aevalsrc=0:d=4[s1]; [s1][1:a]concat=n=2:v=0:a=1[ac1]; [0:a][ac1]amix[aout]" -map [aout] -c:a libmp3lame /home/ubuntu/announcement.mp3
#Now play the audio file in the Internet radio stream
#Replace the current playlist with the playlist from the announcement - mv command does not cause any problems while the stream is running.
_lastplayednr=$(sed -n '6 p' /home/ubuntu/ices/logs/ices.cue)
cp /home/ubuntu/ices/playlists/playlist_live.pls /home/ubuntu/ices/playlists/playlist_live_temp.pls
cp /home/ubuntu/ices/playlists/announcement_playlist.pls /home/ubuntu/ices/playlists/announcement_playlist_temp.pls
mv /home/ubuntu/ices/playlists/announcement_playlist_temp.pls /home/ubuntu/ices/playlists/playlist_live.pls
#Now play the playlist of the announcement
sleep 1
ps axf | grep "/home/ubuntu/ices/bin/ices -c /home/ubuntu/ices/etc/ices.conf" | grep -v grep | awk '{print "kill -10 " $1}' | sh
#Announcement broadcast started - During the current announcement, the normal playlist is restored. This will play the announcement only once. After the announcement, the normal playlist will continue.
sleep 10
_eins="0"
_nownr=$(expr $_lastplayednr + $_eins)
tail -n +$_nownr /home/ubuntu/ices/playlists/playlist_live_temp.pls > /home/ubuntu/ices/playlists/playlist_live_temp2.pls
mv /home/ubuntu/ices/playlists/playlist_live_temp2.pls /home/ubuntu/ices/playlists/playlist_live.pls

The greetings and phrases can be edited as required.
The information/messages are retrieved from an RSS feed via the rsstail program. Please do not forget to change the address of the RSS feed. Only one entry (the most current) will be retrieved. Here you can also use wget instead to retrieve information from a website instead of an RSS feed. However, the information may then only be available as unformatted text.

Now add the required file permissions to the shell script.

chmod +x /home/ubuntu/play_announcement.sh

The shell script can run as cronjob e.g.: every hour:

0 * * * * * /home/ubuntu/play_announcement.sh

Or only be called if a web page contains any text (e.g.: if an error message is displayed instead of an empty page). Here as an example in a shell script:

ANNOUNCEMENTTEXT=$(su ran -c "wget -qO- \""https://WEBSITE.TLD\ARE_THERE_ANY_ERRORS"" ")if [ ! -z "$ANNOUNCEMENTTEXT" ];
then
/home/ubuntu/play_announcement.sh
fi

Now we reached the end of this tutorial. You can also extend this shell script as you wish.

Further use cases

Announcements can also be made available via an RSS podcast feed.
But first you have to create a template for the RSS-Podcastfeed. And the entries of the RSS podcast feed are automatically added via a shell script. The shell script can be extended by the shell script for the RSS podcast feed.

The automatic addition of podcast feed entries can be done as follows:

#iTunes RSS feed podcast entry
echo "<item>" > /var/www/WEBSITE/rss/podcast_temp
titel="<title>"
_dateinametitel=$(env TZ=Europe/London date +"%d-%m-%Y %HH00 - ")
titel+=$_dateinametitel
titel+="Nachrichten auf Deutsch"
titel+="</title>"
echo $titel >> /var/www/WEBSITE/rss/podcast_temp
echo "<description>Die aktuellsten Nachrichten aus Österreich und der Welt. Sowie auch Hightech-Nachrichten. Alles kurz und kompakt.</description>" >> /var/www/WEBSITE/rss/podcast_temp
titel="<link>http://WEBSITE.TLD/rss/podcast_de/files/"
titel+=$_dateinamejetzt
titel+=".mp3</link>"
echo $titel >> /var/www/WEBSITE/rss/podcast_temp
titel="<enclosure url=\"http://WEBSITE.TLD/rss/podcast/files/"
titel+=$_dateinamejetzt
titel+=".mp3\" length=\""
rm /var/www/WEBSITE/rss/podcast_laenge
wc -c < /var/www/WEBSITE/rss/podcast/files/$_dateinamejetzt.mp3 | tee /var/www/WEBSITE/rss/podcast_laenge
_laenge=`cat /var/www/WEBSITE/rss/podcast_laenge`
titel+=$_laenge
titel+="\" type=\"audio/mpeg\"/>"
echo $titel >> /var/www/WEBSITE/rss/podcast_temp
titel="<pubDate>"
_datum=$(env TZ=Europe/London date +"%a, %d %b %Y %T %z")
titel+=$_datum
titel+="</pubDate>"
echo $titel >> /var/www/WEBSITE/rss/podcast_temp
titel="<itunes:summary> Latest Announcement"
titel+=" - Folge: "
titel+=$(env TZ=Europe/London date +"%d-%m-%Y %HH00")
titel+="</itunes:summary>"
echo $titel >> /var/www/WEBSITE/rss/podcast_temp
titel="<itunes:subtitle> This is the latest Announcement"
titel+=" - Episode: "
titel+=$(env TZ=Europe/London date +"%d-%m-%Y %HH00")
titel+="</itunes:subtitle>"
echo $titel >> /var/www/WEBSITE/rss/podcast_temp
echo "<itunes:image href=\"http://WEBSITE.TLD/podcast_images/podcast_logo_cover.png\"/>" >> /var/www/WEBSITE/rss/podcast_temp
titel="<itunes:duration>"
titel+=$(mp3info -p "%02m:%02s\n" /var/www/WEBSITE/rss/podcast/files/$_dateinamejetzt.mp3)
titel+="</itunes:duration>"
echo $titel >> /var/www/WEBSITE/rss/podcast_temp
echo "</item>" >> /var/www/WEBSITE/rss/podcast_temp
echo "" >> /var/www/WEBSITE/rss/podcast_temp
sed '/PodcastEntries/ r /var/www/WEBSITE/rss/podcast_temp' /var/www/WEBSITE/rss/podcast.xml > /var/www/WEBSITE/rss/podcast_temp2
cp /var/www/WEBSITE/rss/podcast_temp2 /var/www/WEBSITE/rss/podcast.xml
rm /var/www/WEBSITE/rss/podcast_temp2

However, empty templates for the RSS podcast feed must be created. Where there is a comment with the text “PodcastEntries” in front of the podcast feed entries.

--

--