Hack:xmradio
Talk0this wiki
Here is a shell script that will allow you to play XM Radio online streams with mpd 0.15
- Please read the script and update your login information for XM Radio
- Requires wma and mms support built into mpd (mpd --version will list) (ffmpeg is the decoder, mms the transport)
- External Dependancies: libmms, curl, mpc
Use your distro specific commands to install these packages before attempted to use this script. e.g.:
- Ubuntu:
sudo apt-get install libmms curl mpc
- Freebsd:
portinstall libmms curl mpc
The Wiki software hides the utf-8 strings in the metadata() function (non-fatal), but if you want the original code, you need to click the "edit" button and copy the original script source... <sigh> Until I figure out how to tell the wiki software not to touch the utf-8.
#!/bin/sh
VERSION="0.6"
# ChangeLog:
#
# 0.6 - Update to work with latest XMRO web and add error handling
# 0.5 - Update login and player urls and add new auth tokens to adapt to xmro web changes.
# 0.4 - Changed from MIMMS and temp file to new mpd 0.15 mmsh support directly
# - direct mpd support for mms urls is much faster, so improved experience is expected
# 0.3 - Initial support for retrieving xml song metadata from xmro and displaying to user
# - Error Checking for write access to mpd music directory/stream file.
# - Error Checking for (if)needed MPD_HOST environment variable, and new script specific XM_MPD_HOST variable
# - Error Checking for unavailable channel from XMRO (error)
# 0.2 - Added some error checking for xmro server outage and a new param "-stop", and default
# - the two data files (cookie/.pid) to the user directory (~) for better non-root usage
# 0.1 - Inital Alpha version
# Maintainer: GadgetDave dhorn2000 at gmail.com
# Tested on FreeBSD 7 with mpc/mpd/curl from ports collection
# Tested on Ubuntu 8.04 with curl/mpc from apt-get
#########################################################################################################
#
# xmradio_mpd
# script is used to login to xmradio online using curl, parse the output,
# and get the mirror stream url, then mpc adds it to the mpd playlist.
#
# Dependancies:
#
# mpc - >=12.1 http://www.musicpd.org
# mpd - >=0.16 http://www.musicpd.org (0.15 needed due to ffmpeg/wma/mms)
# curl - >=7.18 http://curl.haxx.se (may work with others, but untested)
#
# You MUST have an XM Radio Online account for this script to work!
#
# Please edit the following 4 variables to setup for your machine/account
##########################################################################################################
# make sure that mpc has the $MPD_HOST environment variable setup appropriately to point to the mpd server
# If you do not have your environment setup with MPD_HOST variable, and need it for MPC, set it here
# if you are running on the same machine as mpd, then no need to change anything as mpc defaults to localhost
# Note: XM_MPD_HOST only take effect if MPD_HOST is not already set in the environment.
#XM_MPD_HOST="hostname.domain.com"
XM_MPD_HOST=""
# xm_online_login_email is the email address you use to login to XM Radio Online
xm_online_login_email="user@host.dom"
# xm_online_login_password is the password you use to login to XM Radio Online
xm_online_login_password="real_password"
xm_country="XMROUS"
#xm_country="XMROCA"
# (Items should not need to be changed below this line - hopefully)
#=============================================================================================================
# temp file for storing http authentication data in cookies (You need write access to this directory)
cookie_file=~/.xm.cookie
xm_online_login_url="http://www.xmradio.com/player/login/xmlogin.action"
# Works with new 128-bit streams as well.
xm_start_stream_url="http://www.xmradio.com/player/listen/play.action?channelKey=$1&newBitRate=high"
xmro_metadata_url="http://www.xmradio.com/padData/pad_provider.jsp?channel="
curl_options=" --silent --no-buffer --show-error --cookie-jar $cookie_file --cookie $cookie_file"
####################################################################################################
#
# metadata()
#
# Retrieves the XMRO XML File containing Artist/Song/Title data for the specified channel
#
# Issue: Converts "&" or ">" or "<" as a kludge to remove UTF-8 XML encoding
#
####################################################################################################
metadata() {
ch=$1
xml_metadata="`curl $curl_options "$xmro_metadata_url$ch" |sed 's/\&/\&/' |sed 's/\&/\&/' |sed 's/\>/\>/' |sed 's/\</\</'`"
#echo $xml_metadata
song="`echo $xml_metadata |tr '</' '\n/' | grep "songtitle>" |grep -v "/"| sed 's/songtitle>//'`"
artist="`echo $xml_metadata |tr '</' '\n/' | grep "artist>" | grep -v "/"| sed 's/artist>//'`"
album="`echo $xml_metadata |tr '</' '\n/' | grep "album>" |grep -v "/"| sed 's/album>//'`"
channel="`echo $xml_metadata |tr '</' '\n/' | grep "channelname>" |grep -v "/"| sed 's/channelname>//'`"
[ -n "$song" ] && echo "Title: "$song
[ -n "$artist" ] && echo "Artist: "$artist
[ -n "$album" ] && echo "Album: "$album
[ -n "$channel" ] && echo "Channel: "$channel
}
#####################################################################################################
#
# initialsetup()
#
# Display some help text to the user to let them know to edit the user variables
#
#####################################################################################################
initialsetup() {
cat <<EOF
Please read and edit the file: `basename $0`, and setup your XM Radio Online account informationy.
Check to make sure that curl, and mpc are installed, (read `basename $0`)
This script will not function until you complete the setup.
EOF
exit 0
}
#####################################################################################################
#
# usage()
#
# General command line parameter help
#
#####################################################################################################
usage () {
cat <<EOF
usage: `basename $0` [-channels | -metadata channel_number | -stop | channel_number]
Where:
[-channels] will list all of the XM Radio Online Channels
[-metadata channel_number] will retrieve the available song/artist/album information from XMRO for
the specified channel_number
[-stop] will stop the currently playing stream
[channel_number] will start downloading and playing the XM Radio Online channel specified
if channel_number is valid, the stream will be retrieved, and mpd will start
playing the stream. The metadata (song/artist/album) will be displayed if available.
Examples:
The following command will start playing "The CoffeeHouse" station (channel 51)
`basename $0` 51
Just retrieve and display Song/Artist/Album information for a specific channel
`basename $0` -metadata 51
Just list all of the available XM Radio Online (XMRO) channels.
`basename $0` -channels
Just STOP playing
`basename $0` -stop
EOF
exit 0
}
########################################################################################################
#
# channels()
#
# Display the static list of XM Radio Online (XMRO) Channels {not dynamically updated}
#
########################################################################################################
channels() {
cat <<EOF
Channel List as of January 2009
See http://www.xmradio.com for the latest list
Type Channel NAME # DESCRIPTION
=====================================================================================
Pop 40s on 4 4 Forties Pop Hits/Big Band
Pop 50s on 5 5 '50s & early '60s Hits
Pop 60s on 6 6 Sixties Pop Hits
Pop 70s on 7 7 Classic 70s Hits/Oldies
Pop 80s on 8 8 Pop Hits of the '80s
Pop 90s on 9 9 Nineties Pop Hits
Country The Roadhouse 10 Classic Country
Country Outlaw Country 12 Rockin' Country/Americana
Country Willie's Place 13 Texas Honky Tonk Music
Country Bluegrass Junc 14 Bluegrass
Country The Village 15 Contemporary & Traditional Folk
Country The Highway 16 Today's New Country
Country Prime Country 17 80s/90s/00s Country Hits
Pop Elvis Radio 18 Elvis Presley 24/7
Country Kenny Chesney 19 Kenny Chesney's No Shoes Radio
Pop 20 on 20 20 Today's Hits
Pop SIRIUS XM Love 23 Favorite Adult Love Songs
Pop The Blend 25 Adult Hits
Pop The Pulse 26 Modern Adult Contemporary
Pop Escape 28 Beautiful Music
Pop BBC Radio One 29 New British Music
Pop Pop2K 30 Hits Of The 2000s
Pop U-Pop 31 International Hits
Christian The Message 32 Contemporary Christian Pop Hits
Christian Praise 33 Gospel
Christian enLighten 34 Southern Gospel
Jazz & Blues Cinemagic 35 Movie soundtracks and more
Pop The Bridge 39 Classic Hits
Rock Deep Tracks 40 Deep Classic Rock
Rock Hair Nation 41 '80s Hair Bands
Rock Liquid Metal 42 Heavy Metal
Rock SIRIUS XMU 43 Indie, Underground, Imports
Rock 1st Wave 44 Classic 80s Alternative Music
Rock The Spectrum 45 Adult Album Rock
Rock Classic Vinyl 46 Early Classic Rock
Rock Alt Nation 47 New Alternative
Rock Octane 48 New Hard Rock
Rock Classic Rewind 49 Later Classic Rock
Rock The Loft 50 Acoustic Eclectic Rock
Rock The CoffeeHouse 51 Acoustic Singer-Songwriters
Rock Faction 52 Action Sports Music
Rock Boneyard 53 Hard and Heavy Classic Rock
Rock Lithium 54 Grunge & 90s Alternative Rock
Rock Margaritaville 55 Jimmy Buffett's Radio Station
Rock Jam On 56 Jam Bands
Rock Grateful Dead 57 Grateful Dead & Family
Rock E Street Radio 58 24/7 Bruce Springsteen & the E Street Band
Rock Underground Gar 59 Garage Rock
Hip-Hop Soul Town 60 Classic Soul
Hip-Hop Heart & Soul 62 Adult R&B Hits
Hip-Hop The Groove 64 Old School R&B
Hip-Hop Shade 45 66 Uncut/Uncensored Hip-Hop
Hip-Hop Hip-Hop Nation 67 Hip-Hop
Hip-Hop The Heat 68 Rhythmic Hits
Jazz & Blues Real Jazz 70 Classic Jazz
Jazz & Blues Watercolors 71 Smooth/Contemporary Jazz
Jazz & Blues Spa 72 New Age
Jazz & Blues Sirius Sinatra 73 Great American Songbook
Jazz & Blues B.B. King's 74 Blues
Jazz & Blues On Broadway 75 Show tunes
Classical SIRIUS XM Pops 77 Popular Classical
Classical Symphony Hall 78 Classical
Classical Met Opera Radio 79 Opera and Classical Vocal
Dance Area 80 Mainstream & Underground Club Music
Dance BPM 81 Current Dance
Dance The System 82 Electronica/Trance
Dance SIRIUS XM Chill 84 Smooth Electronica
Latin Caliente 85 Latin Tropical Music
Latin The Joint 86 Reggae
Latin The Verge 87 Emerging Artists
Latin Air Musique 88 New & Emerging Music
Latin Sur La Route 89 Pop Hits
Latin World Zone 90 World Music
Latin Viva 91 Latin Pop
Latin Ngoma 98 The Sound of Africa
Family Radio Disney 115 Radio Disney
Family Kids Place 116 All Fun for Kids
Religion Catholic Chan 117 Not What You'd Expect
Family Doctor Radio 119 Powered by NYU Langone Medical Center
Talk, News CNN 122 CNN News
Talk, News POTUS 130 Unfiltered Political Talk
Talk, News BBC World 131 BBC World Service
Talk, News C-SPAN 132 C-SPAN Radio
Talk, News XM Public Radio 133 XM Public Radio
Talk, News NPR Now 134 NPR News & Conversation
Talk, News World Radio Net 135 News Around the World
Talk, News The Agenda 137 GLBT Issues
Entertain SIRIUS XM Stars 139 Great Talk Radio for Guys
Sports ESPN Radio 140 Sports Talk
Sports Mad Dog Radio 144 Sports Radio with Chris Russo
Sports PGA TOUR Net 146 The PGA TOUR - Golf Talk
Comedy Blue Collar 148 All-American Comedy
Comedy The Foxxhole 149 Comedy, music, and more presented by Jamie Foxx
Comedy Raw Dog Comedy 150 Comedy Uncensored
Comedy Laugh USA 151 Family Comedy
Entertain SIRIUS XM Stars 155 Celebrity hosts and lifestyle programming
Entertain Oprah & Friends 156 Oprah & Friends
Entertain Cosmo Radio 162 Fun, Fearless, Female
Talk, News FOX News Talk 168 FOX News Talk
Sports MLB Home Plate 175 24/7 MLB
Comedy Virus 202 The Opie & Anthony Show - XL
Sports NHL Home Ice 204 NHL Talk and Play-by-Play
Entertain Oprah's Soul 256 Spiritual Radio
EOF
exit 0
}
# Check for command line parameters and user setup
if [ "$xm_online_login_password" = "real_password" ]; then initialsetup; fi
if [ -z `which curl` ]; then initialsetup; fi
if [ -z `which mpc` ]; then initialsetup; fi
if [ "$1x" = "-channelsx" ]; then channels; fi
if [ "$1x" = "-metadatax" ]; then if [ ! "$2x" = "x" ]; then metadata $2; else echo "Error: missing parameter. `basename $0` -metadata requires a second parameter - channel_number required.\n" && usage; fi; exit 1; fi;
[ "$1x" = "-stopx" ] && mpc --no-status stop && echo "Stream stopped." && exit 0
if [ $# -eq 0 ]; then usage; fi
if [ `echo $1 | egrep -c "^([0-9][0-9]*|[0-9][0-9]*\.[0-9][0-9]*)$"` -lt 1 ]; then usage; fi
if [ $1 -lt 4 ]; then usage; fi
if [ $1 -gt 256 ]; then usage; fi
# Check to see if mpc can work by looking for the environment variable MPD_HOST, or just a localhost mpd listener socket
# otherwise, try using the hostname specified in XM_MPD_HOST variable (if it is set) If nothing is setup, show the user help
[ -n "$XM_MPD_HOST" ] && [ -z "`echo $MPD_HOST`" ] && [ -z "`netstat -an |grep -i LISTEN |grep 6600`" ] && export MPD_HOST="$XM_MPD_HOST"
[ -z "`echo $MPD_HOST`" ] && [ -z "`netstat -an |grep -i LISTEN |grep 6600`" ] && echo "Please check the value of environment variable: MPD_HOST or setup XM_MPD_HOST in the file: `basename $0`" && exit 1
#echo $MPD_HOST
echo "Authenticating User, and Requesting Channel from XMRO..."
#echo $curl_options -d user_id="$xm_online_login_email" -d pword="$xm_online_login_password" "$xm_online_login_url"
login_try="`curl $curl_options -d playerToLaunch=xm -d encryptPassword=false -d userName="$xm_online_login_email" -d password="$xm_online_login_password" "$xm_online_login_url" |grep -ci "invalid user"`"
#cat $cookie_file
#echo $login_try
[ $login_try -gt 0 ] && echo "Invalid Username and/or Password. Please update the credentials in file: `basename $0` and try again" && exit 1
temp_stream_url="`curl $curl_options "$xm_start_stream_url" | grep $xm_country | grep mplayer2 | grep src | sed 's#<embed type="application/x-mplayer2" pluginspage="http://www.microsoft.com/Windows/MediaPlayer/" src="##' | sed 's#" name="xmmediaplayer" width="280" height="50" autostart="1" showstatusbar="1" showcontrols="1" showtracker="0" transparentatstart="0" autosize="0" displaysize="0"></embed>##' | sed 's#\&#\&#g' | tr -d '\n' `"
#echo "Temporary url for radio stream: $temp_stream_url"
[ "$temp_stream_url"x = x ] && echo "Invalid Stream, please report." && exit 1
[ `echo "$temp_stream_url" | grep -ci "Failure"` -gt 0 ] && echo "XM Radio Online is experiencing an outage at the moment. Please try again later" && exit 1
echo "Retrieving stream from CDN..."
final_stream_url="`echo "$temp_stream_url" |sed 's/http:/mmsh:/1' | tr -d '\r\n'`"
#printf $final_stream_url | hexdump -C
# mpc clear playlist,
mpc clear >/dev/null
# mpd requires a mmsh:// url format
mpc add "${final_stream_url}" >/dev/null
mpc play --format "[/t]"
metadata $1
Misc Research related....
If you would like to display wma tags (other than Title) in mpd, you need to know the mapping of WMA tag string to MPD tag string.
For example:
"Author" in WMA Tag is equal to "Artist" in MPD
"Title" in WMA Tag is equal to "Title" in MPD
"WM/AlbumTitle" in WMA Tag is equal to "Album" in MPD
"WM/TrackNumber" in WMA Tag is supported in ffmpeg as an integer, and will map to "Track" in MPD. Just for completeness sake, WM/Track is an alias for WM/TrackNumber, and will work as well.
"Genre" is not currently supported (as of 0.14.1) in MPD via ffmpeg mapping
Take a look here: http://git.musicpd.org/cgit/master/mpd.git/tree/src/decoder/ffmpeg_plugin.c for the MPD mapping
Take a look here: http://git.ffmpeg.org/?p=ffmpeg;a=blob;f=libavformat/asf.c;hb=HEAD for the ffmpeg mapping
Take a look here: http://msdn.microsoft.com/en-us/library/aa386866(VS.85).aspx for the Microsoft asf container mapping.
You can use mutagen (http://code.google.com/p/quodlibet/wiki/Mutagen) to set the WMA tags on the stream, and ffmpeg/mpd will decode them provided that you utilize the correct mapping.
Example using mutagen to set tags in WMA file that ffmpeg can read, and then pass to MPD:
from mutagen.asf import ASF
audio = ASF("myfilename.wma")
audio["Title"] = "MyTitle"
audio["Author"] = "MyArtist"
audio["WM/AlbumTitle"] = "MyAlbum"
audio["WM/TrackNumber"] = "12"
#print ASF.pprint(audio)
#print ASF.keys(audio)
ASF.save(audio)