Skip to content

Instantly share code, notes, and snippets.

@xndc
Last active March 10, 2024 16:42
Show Gist options
  • Star 42 You must be signed in to star a gist
  • Fork 10 You must be signed in to fork a gist
  • Save xndc/c732204e274743204f1f to your computer and use it in GitHub Desktop.
Save xndc/c732204e274743204f1f to your computer and use it in GitHub Desktop.
Instant radio streaming script using the TuneIn API
#!/bin/bash
# tunejack.sh uses the TuneIn public API (at opml.radiotime.com) to search for
# a radio station, print out its details and try to play it somehow.
if [ "$#" -eq 0 ]; then
echo "$0: search for a radio station using the TuneIn API"
echo "Usage: $0 PATTERN"
exit 1
fi
# Grab the search pattern.
PATTERN="$*"
# Helper function for encoding a URL.
# See http://stackoverflow.com/questions/296536/
urlencode() {
local string="$*"
local strlen=${#string}
local encoded=""
for (( pos=0 ; pos<strlen ; pos++ )); do
c=${string:$pos:1}
case "$c" in
[-_.~a-zA-Z0-9] ) o="${c}" ;;
* ) printf -v o '%%%02x' "'$c"
esac
encoded+="${o}"
done
echo "${encoded}"
}
# Ask the API for search results.
# Supports both curl and wget.
API_TARGET="http://opml.radiotime.com/Search.ashx?query=$(urlencode $PATTERN)"
if which curl > /dev/null; then
API_RESPONSE=$(curl --silent $API_TARGET)
elif which wget > /dev/null; then
API_RESPONSE=$(wget --quiet --output-document=- $API_TARGET)
else
echo "Error: script requires curl or wget installed."
exit 1
fi
# Try to grab the first <outline> element from the response.
# It has to have attributes type="audio" and item="station".
# Discard results containing key="unavailable" - they're useless stubs.
API_RESULT_TAG=$(echo "$API_RESPONSE" \
| grep '<outline type="audio"' \
| grep 'item="station"' \
| grep -v 'key="unavailable"' \
| head -n 1)
if [[ "$API_RESULT_TAG" == "" ]]; then
echo "No radio stations found."
exit
else
# Split the <outline> tag into multiple lines, so we can grep for each
# XML attribute.
API_RESULT_TAG=$(echo "$API_RESULT_TAG" | sed 's/" /"\n/g')
# Helper function to extract a tag.
# The sed is because we're not actually decoding XML, and things like
# apostrophes are represented by HTML entities like &apos;.
extract_tag() {
TAG="${1}"
echo "$API_RESULT_TAG" | grep "^$TAG=" | cut -d '"' -f 2 \
| sed "s/&apos;/\'/g"
}
# Display the details we're interested in - name, subtext, URL.
echo "$(extract_tag text)"
echo "$(extract_tag subtext)"
echo "$(extract_tag URL)"
# Throw the URL in a variable for later purposes.
API_URL="$(extract_tag URL)"
fi
# Get the actual server URL.
if which curl > /dev/null; then
URL=$(curl --silent $API_URL)
elif which wget > /dev/null; then
URL=$(wget --quiet -O - $API_URL)
fi
# Try and find a media player.
# Run GUI apps in the background - see http://superuser.com/questions/177218
if which mplayer > /dev/null; then
mplayer $URL
elif which mpg123 > /dev/null; then
mpg123 $URL
elif which vlc > /dev/null; then
(vlc $URL &> /dev/null &)
elif which totem > /dev/null; then
(totem $URL &> /dev/null &)
elif which audacious > /dev/null; then
(audacious $URL &> /dev/null &)
elif which xdg-open > /dev/null; then
# This will usually just open the stream status page.
xdg-open $URL
fi
@locness3
Copy link

Thank you for this script!

@ashsaraga
Copy link

ashsaraga commented Nov 13, 2019

Better documentation here than TuneIn, lol — thank you!! 💯 💪

@locness3
Copy link

locness3 commented Dec 7, 2019

Better documentation here than TuneIn

yeah, i just don't find any docs lol

@fwmann
Copy link

fwmann commented Apr 27, 2020

Hi,
yes very good script.
Is it possible to find a station by its ID (it´s called preset_id)? Something like: "http://opml.radiotime.com/Search.ashx?query=s25217"
Background is, if there is a Station with similar names, you get (of course) all Stations containing the search phrase. For example if you search for 'Rock Antenne', there is 'Rock Antenne Soft', 'Rock Antenne Heavy' and so on.
I would like to have the exact Station in the result. With the Station ID you get only one Station in the Result.

Hopefully someone can help with this specific query.

Thanks and Regards
fwmann

@cosinekitty
Copy link

I noticed in my own TuneIn client app, my "Favorites" are now chock full of unplayable stations, LOL. I came here from a Google search and found this in your script:

| grep -v 'key="unavailable"' \

That's essentially what I had to change in my software too. It's weird that their API offers huge piles of unplayable content by default. One would think at least we would have to opt in for useless content with a URL query parameter.

@tarbear123
Copy link

tarbear123 commented May 7, 2022

do I paste it into notepad & save it as a .sh extension and when I want to run it, how do I run the script via macro board i.e stream deck exe and is there a GUI with this?

@core-hacked
Copy link

do I paste it into notepad & save it as a .sh extension and when I want to run it, how do I run the script via macro board i.e stream deck exe and is there a GUI with this?

No, by your comment I am guessing you are on windows. You need linux or at least bash to run it.

@core-hacked
Copy link

core-hacked commented Aug 26, 2022

I hate to advertise, but this comes up when searching for documentation. If anyone is looking for some further API interaction or “rich” streaming (station names, song names etc.), and explanations, you can read this unofficial documentation, to make it happen.

Kind regards!

@JustDancing
Copy link

How can I get a web url rather than a mp3 url? For example, for searching times radio, https://opml.radiotime.com/Search.ashx?query=%22times%20radio%22, the results contain the item with URL="http://opml.radiotime.com/Tune.ashx?id=s309354", how can I get or convert the url to https://itg.tunein.com/radio/Times-Radio-s309354/?

@core-hacked
Copy link

How can I get a web url rather than a mp3 url? For example, for searching times radio, https://opml.radiotime.com/Search.ashx?query=%22times%20radio%22, the results contain the item with URL="http://opml.radiotime.com/Tune.ashx?id=s309354", how can I get or convert the url to https://itg.tunein.com/radio/Times-Radio-s309354/?

  1. Grab the ID - s309354
  2. add it after https://itg.tunein.com/radio/
  3. You get https://itg.tunein.com/radio/s309354/
  4. The link you got redirects to the web page: https://itg.tunein.com/radio/Times-Radio-s309354/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment