Technology
 

Hack:xmradio

From Music Player Daemon Community Wiki

Here is a shell script that will allow you to play XM Radio online streams with mpd 0.14

  • 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.4"
# ChangeLog:
#
# 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.2 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.15   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"

# US residents will use this default country code entry, Canadians must switch these comments
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://xmro.xmradio.com/xstream/login_servlet.jsp"
# Works with new 128-bit streams as well.
xm_start_stream_url="http://player.xmradio.com/player/2ft/playMedia.jsp?ch=$1&speed=high"
xmro_metadata_url="http://www.xmradio.com/padData/pad_provider.jsp?channel="
curl_options="--silent --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/\&amp/\&/' |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 user_id="$xm_online_login_email" -d pword="$xm_online_login_password" "$xm_online_login_url" |grep -c "Invalid email and"`" 
#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 -v mplayer2 | sed 's/<PARAM NAME="FileName" VALUE="//I' | sed 's/">//I' |sed 's/[^.]//' | sed 's/[ \t]*$//' | tr -d '\n'`" 
#echo $temp_stream_url
[ `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 location data for CDN stream..."

final_stream_url="`curl $curl_options "$temp_stream_url" |grep mms: | sed 's/<Ref href="//' |sed 's/"\/>//' |sed 's/        mms:/http:/'|sed 's/http:/mmsh:/'`"
[ `echo "$final_stream_url" |grep -ci "error"` -gt 0 ] && echo "Error: Unplayable Stream, please check the channel number(most likely) and authentication cookie(possible), or an XMRO Outage." && exit 1
#echo $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)
Rate this article: