Difference between revisions of "Integrate Sirius"
(→Hack the default theme) |
(Corrected what sipie README actually says at this time) |
||
Line 109: | Line 109: | ||
# python-wxgtk2.6 is option but it currently works better then the pure | # python-wxgtk2.6 is option but it currently works better then the pure | ||
# gtk interface | # gtk interface | ||
− | apt-get install mplayer python-setuptools python-wxgtk2.6 | + | apt-get install mplayer python-setuptools python-wxgtk2.6 |
</pre> | </pre> | ||
+ | |||
+ | |||
====Installing Beautiful Soup==== | ====Installing Beautiful Soup==== |
Revision as of 17:53, 19 February 2009
This article is going to give you all of the info you need in order to pipe your online Sirius Satellite Radio account directly through your MythTV system. The first draft of this article is based around a Fedora Core 6 setup but it should be EASILY adapted to any distro. Please, READ THE ENTIRE ARTICLE CAREFULLY all the way to the end before you start anything.
Note: this is NOT a plug-in and is basically a hack but when completed it looks just like a plug-in.
Contents
Article from 10,000 feet
What this article is...
This article IS about:
- Setting up MythTV to play streams from Sirius Radio Online
- How-To use programs that other people wrote (and are not affiliated with MythTV)
- How-To integrate everything with the default MythTV menu theme
What this article is not...
This article IS NOT:
- How-To get free access to the streams (although a Sirius online guest account will work fine)
- How-To perfectly integrate with your particular MythTV GUI (we only cover the default menu theme)
- A Sirius Radio Plug-in for MythTV
- An audio stream capture how-to, but you can check out Eli's example recorder right here.
What you need to have
Setup
- You only need to have an account setup at Sirius.com.
Installed
Required:
- MythTV
- Python (2.4+)
- mplayer
- sipie (myth specific install instructions are below)
- Beautiful Soup (instructions also below)
Optional:
- wxPython
- python-notify (highly recommended)
Introducing SIPIE
Pronounced SY PIE, like sirius python sipie is a command line player for sirius on-line Internet streaming. It requires a login to sirius's streaming, both guest and subscriber logins are supported. Streams are entered on the command line or are asked for. TAB twice will list all streams, type part of a stream and hit TAB to complete it. You can change streams without restarting (and thus not re-authenticating) by hitting CTRL-C while a stream is playing. sipie is written in python, and uses mplayer for the streams. Beautiful Soup is the only extra library you'll need. See the README on how to get it. Eli Criffield
Let's get started!
Installing Sipie Requirements
I (TwoOneSix) have recently written a player for sipie (mythPlayer) that is for usage in MythTV, so we'll need to get the version from SVN instead of the one listed in the README file (details below). Remember that ONLY when you get sipie working OUTSIDE of MythTV, will it work INSIDE of MythTV. Also, make sure when you do your initial sipie setup that you do it under your mythtv account (or whatever account runs the front end).
VIA YUM
You should only need the extras repository on FC6 to install... This is based on my install.
Make sure this is done in your GUI or you won't be able to see the captcha
Remember that wxPython, notify-python, and dbus-x11 are not required, but I suggest making sure it's installed... also I added subversion to the command to save a step later in the process.
# yum install mplayer python python-setuptools wxPython notify-python dbus-x11 subversion Dependencies Resolved ============================================================================= Package Arch Version Repository Size ============================================================================= Installing: wxPython i386 2.6.3.2-2.fc6 extras 7.4 M Installing for dependencies: wxGTK i386 2.6.3-2.6.3.2.3.fc6 extras 3.5 M wxGTK-gl i386 2.6.3-2.6.3.2.3.fc6 extras 28 k Transaction Summary ============================================================================= Install 3 Package(s) Update 0 Package(s) Remove 0 Package(s) Total download size: 11 M <snip> Completed!
FEDORA 8 USERS
Python tools are compiled under devel... here is your install command:
# yum install mplayer python python-setuptools-devel wxPython notify-python dbus-x11 subversion
END FEDORA 8 USERS
VIA Ubuntu
This is from the README excluding the easy_install portion at the end!
Make sure mutliverse is enabled, if not enable it grep multiverse /etc/apt/sources.list if nothing returns go to System -> Administration -> Synaptic Package Manager Settings -> Repositories -> Ubuntu Software -> Software restricted by copyright or legal issues (multiverse) CHECK THAT then # python-wxgtk2.6 is option but it currently works better then the pure # gtk interface apt-get install mplayer python-setuptools python-wxgtk2.6
Installing Beautiful Soup
Simply do:
# easy_install BeautifulSoup
Gabe says he has some issues getting Beautiful Soup to install this way, so he ran these commands to get it working. I didn't have to do this so I couldn't verify, but we'll take his word.
# cd /usr/bin # wget http://www.crummy.com/software/BeautifulSoup/download/BeautifulSoup.py
Installing Sipie
Since the Sipie player we want is currently in SVN, we have to checkout the code and easy_install from a local copy. This also allows us to tweak the file settings prior to running the setup. Here we go... You need to have subversion installed (see above).
First, we need to find (or make) a place to put the code (I use /usr/src for my sources) and download the code:
# cd /usr/src
Now we'll pull down the latest and greatest version of sipie from SVN:
# svn co https://sipie.svn.sourceforge.net/svnroot/sipie sipie
OPTIONAL SETUP
If you're OK with seeing the standard pop-up and think that leaving the pop-up on the screen for 2 minutes is OK, then simply skip this step.
# vi /usr/src/sipie/contrib/mythPlayer.py
Edit the following lines:
26: tryPopups = True # Set as False to disable pop-ups 27: notifySeconds = 120000 # This is a MAX time (in ms) to show a single song name. Default: 120000 (2 min)
END OPTIONAL SETUP
OK, now we need to easy_install sipie for use. You should see similar (but not exactly the same) output as listed below, if you see a stack trace or a "code dump" make sure you have python-setuptools (Fedora 8: python-setuptools-devel) installed correctly.
Move into the source directory:
# cd /usr/src/sipie
Now install sipie:
# easy_install .
Expected Output:
Processing . Running setup.py -q bdist_egg --dist-dir /usr/src/sipie/egg-dist-tmp-e9BrUR Sipie 0.1196144357 is already the active version in easy-install.pth Installing sipie.py script to /usr/bin Installing cliSipie script to /usr/bin Installing gtkSipie script to /usr/bin Installing wxSipie script to /usr/bin Installed /usr/lib/python2.5/site-packages/Sipie-0.1196144357-py2.5.egg Processing dependencies for Sipie==0.1196144357 Finished processing dependencies for Sipie==0.1196144357
Now, we need to move my contributed player to a better place. In this example, I am moving the file to /usr/bin because that's the same place the other files were moved (see the above output: ... scipt to /usr/bin).
# cp /usr/src/sipie/contrib/mythPlayer.py /usr/bin
Alright, now sipie is installed and ready to go!
Configuring Sipie
You need to ensure that the configuration is done under the same user account that MythTV runs under, in my case it's the mythtv user, simple enough.
$ cd ~ $ sipie.py username and a crypted password will be stored in ~/.sipie/config no plain text passwords are stored if you want to change your password remove ~/.sipie/config then run sipie and it'll ask you for username and password again Enter username: MySiriusUsername Enter password: Login Type, type guest or subscriber Enter login type: subscriber
- Enter the captcha in the popup window or if sipie can't find wxGTK you will have to open the image file it tells you to open and enter the captcha at the command prompt.
- You should now be prompted to select a station, if you have a GUI, pick one from the drop-down and chose "play"... you should hear the stream...
Note: it doesn't matter if you see a GUI app window... in a minute, we'll force it to run with no user input. We're currently only focused on hearing the stream.
- Stop the stream VIA the "stop" button on the GUI or Ctrl+C twice on the command line.
Let's also quickly test my mythPlayer.py code.
$ mythPlayer.py octane
You should hear the stream and see the pop-up window along with the song info back on the command line. Great! Now hit ctrl+c and it should kill the stream and exit out to the command line.
Let's hack it together
OK, now we are going to write a simple shell script that we will use to make MythTV happy while talking to sipie.
Create sipie_myth
We need to create a single executable file so find a nice place you can execute it from. Personally, I use /usr/bin. You can replace vi with gedit or kedit if you prefer a GUI text editor.
# vi /usr/bin/sipie_myth
Now, paste in the following code:
#!/bin/bash # Script By: Josh <TwoOneSix AT thatclothingco DOT com> # Used to control sipie from MythTV menu pid_file=/tmp/sipie_myth.pid die_mythSipie() { # Kill off the child processes first... pkill -P `cat $pid_file` # Now kill off the parent process... kill `cat $pid_file` rm -f $pid_file return 0 } play_mythSipie() { echo "I'm about to play:" $1 /usr/bin/mythPlayer.py $1 & # you may have to tweak this line if you copied the player to another location echo $! > $pid_file return 0 } # If we see the kill command, kill the old processes/streams if [ "$1" = "kill" ]; then die_mythSipie # If we see the play command, kill any existing streams then play the stream elif [ "$1" = "play" ] && [ "$2" != "" ]; then if [ ! -e $pid_file ] ; then play_mythSipie $2 else die_mythSipie # Just to be sure it's gone... if [ ! -e $pid_file ] ; then play_mythSipie $2 else echo 1>&2 '******FATAL ERROR STARTING STREAM PLAY******' exit 1 fi fi exit 0 else echo 1>&2 'Usage: ' $0 '{kill | play} stream (stream only required on play)' exit 127 fi
Now you will want to make the file executable:
# chmod a+x /usr/bin/sipie_myth
Test scripts
Now, as your mythtv user, pull up a command window and run the command we just "made" with the stream to test.
- Usage: /usr/bin/sipie_myth {kill | play} stream (stream only required on play)
$ sipie_myth play octane
Do you hear the stream without having to enter a single thing in the command window? Do you see the song names in the command window and in the pop-up notifier (if you left tryPopus=True)? That's good, now use this to kill the stream:
$ sipie_myth kill
Did you have to enter information? That's bad. Make sure you configured sipie as your mythtv user and try again.
Did the kill process not end the stream? This is caused by the mythPlayer.py not cleaning up properly on exit. Modify /usr/bin/mythPlayer.py with the following
#!/usr/bin/python # -*- coding: utf-8 -*- # Josh Zeno <TwoOneSix@thatclothingco.com> # mythPlayer.py: This is a sipie player that it tweaked specifically for MythTV usage # and is designed to be run as a background process that is managed by the script # sipie_myth (found at: http://www.mythtv.org/wiki/index.php/Integrate_Sirius) # Licensed under GPLv2 See: http://www.gnu.org/licenses/gpl.txt #################################### # What makes this player different? # --You must send the stream name as an argument: i.e. mythSipie octane # --Is able to run as a "friendly" background process using sipie_myth as mentioned above # --Gives the user the option to disable pynotify popups and set the popup timeout # --Adds the sipie icon to the pynotify pop-up window # --Does not keep your Sirius session open so you have to be careful how often you change streams import atexit import sys,signal,os def mythPlayer(): from Sipie.Config import Config from Sipie.Player import Player from Sipie import StreamHandler import time global sipie tryPopups = True # Set as False to disable pop-ups notifySeconds = 120000 # This is a MAX time (in ms) to show a single song name. Default: 120000 (2 min) if tryPopups: try: import pynotify from pkg_resources import Requirement, resource_filename pynotify.init("mythSipie") except: print "WARN: Not found! Is pynotify installed?" tryPopups = False def getIcon(): icon_file = resource_filename(Requirement.parse("Sipie"),"Sipie/data/sipie.png") if os.path.isfile(icon_file): return icon_file configdir = '%s/.sipie'%os.environ['HOME'] streamHandler = StreamHandler.mplayerHandler('/usr/bin/mplayer') # haven't tried other handlers yet config = Config(configdir) sipie = Player(config.items()) sipie.setPlayer(streamHandler) FirstLoop = True while True: if len(sys.argv) == 2 and FirstLoop: stream = sys.argv[1].lower() elif sys.argv[0].lower().find("sipie") == -1 and FirstLoop: stream = os.path.basename(sys.argv[0]) try: sipie.setStream(stream) except : FirstLoop = False print "******FATAL: Invalid Stream!******" sipie.close() sys.exit() sipie.play() # We have to handle pynotify differently from the command line to keep it from crashing the player while True: playing = sipie.nowPlaying() if playing['new']: if tryPopups: nPop = pynotify.Notification(playing['stream'], playing['playing'], getIcon()) nPop.set_timeout(notifySeconds) nPop.show() print playing['logfmt'] try: time.sleep(30) except KeyboardInterrupt: print "Thanks for playing!" sipie.close() sys.exit() FirstLoop = False def handler(signum, frame): sipie.close() sys.exit() signal.signal(signal.SIGTERM, handler) if __name__ == '__main__': mythPlayer()
Setting up the MythTV GUI
At this point, you should be able to listen to (and kill) streams from the command line with no user intervention... that's 1/2 the battle. Now, we are going to hack a couple of buttons onto the default menu theme.
Note: If you are currently running .20+ chances are that you're using the default menu theme. No, not the actual MythTV theme, just the menu theme. To check out which one you're using do this in Myth: Utilities / Setup (or Setup) -> Setup -> Appearance -> and at the bottom of the first options page you will see the menu themes selection box, we will be hacking into "Default" so make sure it's set to that one. If you use classic or DVR you can change some of the commands below so that your work is being done on that particular theme (just add /themes/classic or /themes/DVR respectively to the "cd" commands below).
Backup the default theme
# cd /usr/share/mythtv # tar cfvz default_backup.tar.gz *.xml
I use the -v option because it's an easy way to verify (VIA verbose) what files were put into the tar ball.
Hack the default theme
I'm only going to show you the 2 required changes to get this hack to work.
Now, add the following to mainmenu.xml file.
# cd /usr/share/mythtv # vi mainmenu.xml
<button> <type>MUSIC</type> <text>Play Sirius Radio</text> <action>MENU siriusmenu.xml</action> </button>
Then, create the siriusmenu.xml file (be sure to add all of the streams you want access to):
# vi siriusmenu.xml
<mythmenu name="SIRIUS"> <button> <type>MUSIC</type> <text>Howard 100</text> <action>EXEC /usr/bin/sipie_myth play howardstern100</action> </button> <button> <type>MUSIC</type> <text>Octane</text> <action>EXEC /usr/bin/sipie_myth play octane</action> </button> <button> <type>MUSIC</type> <text>Alt Nation</text> <action>EXEC /usr/bin/sipie_myth play altnation</action> </button> <button> <type>MUSIC</type> <text>Super Shuffle</text> <action>EXEC /usr/bin/sipie_myth play supershuffle</action> </button> <button> <type>MUSIC</type> <text>Big 80s</text> <action>EXEC /usr/bin/sipie_myth play big80s</action> </button> <button> <type>MUSIC</type> <text>Lithium</text> <action>EXEC /usr/bin/sipie_myth play 90salternative</action> </button> <button> <type>MUSIC</type> <text>Sirius Hits 1</text> <action>EXEC /usr/bin/sipie_myth play siriushits1</action> </button> <button> <type>MUSIC</type> <text>Coffee House</text> <action>EXEC /usr/bin/sipie_myth play coffeehouse</action> </button> <button> <type>MUSIC</type> <text>NFL Radio</text> <action>EXEC /usr/bin/sipie_myth play siriusnflradio</action> </button> <button> <type>TV_DELETE</type> <text>Stop Listening</text> <action>EXEC /usr/bin/sipie_myth kill</action> </button> </mythmenu>
EDIT: Alternate Menu Options
After reviewing the channel guide provided by Sirius, I decided i wanted a repeatable way to update the channels provided by Sirius. After looking at the Channel Guide, I noticed that not all channels were playable online. I wrote this script to scrap the Sirius channel listing and generate mythtv menus that accounts for the channels that are playable online as well as breaking the channels out by category and genre. This is my first python script, so please go easy on it.
Instructions:
1. Setup all requirements as stated above and test to verify that you can hear music
2. Execute the script below in any directory (this script requires python lxml bindings)
3. copy the xml files to /usr/share/mythtv if not executing the script in that directory.
4. Modify an existing menu to open siriusmenu.xml as indicated above.
Output Hierarchy
siriusmenu.xml |---Category |---Genre |---channels listed here |---Genre |---channels listed here |---Category |---Genre |---channels listed here |---Genre |---channels listed here |---Category |---Genre |---channels listed here |---Genre |---channels listed here |---Category |---Genre |---channels listed here |---Genre |---channels listed here
Script
from lxml import etree import lxml.html import os.path import urllib2 # Open a url and read the page url = 'http://www.sirius.com/servlet/ContentServer?pagename=Sirius/CachedPage&c=ChannelLineup&cid=1218563499691' res = urllib2.urlopen(url) page = res.read(); # get html html = lxml.html.fromstring(page) # get channel table channel_table = html.get_element_by_id('channel_guide_tbody') #print(channel_table.tag) table = [] for tr in channel_table: #print(tr.tag) row = [] for td in tr: if len(td) == 1: a = td[0] if a.get("title") == 'Listen': row.append(a.get("href")) row.append('Listen') elif len(a) == 1: span = a[0] row.append(span.text) else: row.append(a.text) else: row.append(td.text) if row[-1] is not None: table.append(row) #print(row) #print('\n') categories = [] genres = [] channels = [] for row in table: channel = row[2] name = row[3] category = row[4] genre = row[5] description = row[6] url = row[7] # clean the url url = url.replace("','','');", '').replace("javascript:%20launchPlayer('",'') words = url.split(",", 1) url = words[1] url = url[1:] #print(url) # build categories if not category in categories: categories.append(category) new = [category] genres.append(new) # build genres for cat in genres: if cat[0] == category and not genre in cat: cat.append(genre) new = [genre] channels.append(new) # build the channels for chan in channels: if chan[0] == genre: chan.append([channel + "-" + name, url]) categories.sort() #print(categories) #print('\n') #print(genres) #print('\n') #print(channels) #print('\n') categories_xml = etree.Element("mythmenu", name="SIRIUS") for category in categories: button = etree.SubElement(categories_xml, "button") menu_type = etree.SubElement(button, "type") menu_type.text = "MUSIC" menu_text = etree.SubElement(button, "text") menu_text.text = category menu_action = etree.SubElement(button, "action") menu_action.text = "MENU sirius_" + category.replace('/', '-').lower() + ".xml" button = etree.SubElement(categories_xml, "button") menu_type = etree.SubElement(button, "type") menu_type.text = "TV_DELETE" menu_text = etree.SubElement(button, "text") menu_text.text = "Stop Listening" menu_action = etree.SubElement(button, "action") menu_action.text = "EXEC /usr/bin/sipie_myth kill" #print(etree.tostring(categories_xml, pretty_print=True)) categories_file = "siriusmenu.xml" FILE = open(categories_file, "w") FILE.write(etree.tostring(categories_xml, pretty_print=True)) FILE.close() for row in genres: genre_xml = etree.Element("mythmenu", name="SIRIUS-" + row[0].replace('/', '-')) for genre in row: if genre in categories: continue button = etree.SubElement(genre_xml, "button") menu_type = etree.SubElement(button, "type") menu_type.text = "MUSIC" menu_text = etree.SubElement(button, "text") menu_text.text = genre menu_action = etree.SubElement(button, "action") menu_action.text = "MENU sirius_" + genre.replace('/', '-').replace(' ', '_').replace('&', 'and').replace('\'', '').lower() + ".xml" button = etree.SubElement(genre_xml, "button") menu_type = etree.SubElement(button, "type") menu_type.text = "TV_DELETE" menu_text = etree.SubElement(button, "text") menu_text.text = "Stop Listening" menu_action = etree.SubElement(button, "action") menu_action.text = "EXEC /usr/bin/sipie_myth kill" #print(etree.tostring(genre_xml, pretty_print=True)) genre_file = "sirius_" + row[0].replace('/', '-').lower() + ".xml" FILE = open(genre_file, "w") FILE.write(etree.tostring(genre_xml, pretty_print=True)) FILE.close() for row in channels: channel_xml = etree.Element("mythmenu", name="SIRIUS-" + row[0].replace('/', '-')) button = etree.SubElement(channel_xml, "button") menu_type = etree.SubElement(button, "type") menu_type.text = "TV_DELETE" menu_text = etree.SubElement(button, "text") menu_text.text = "Stop Listening" menu_action = etree.SubElement(button, "action") menu_action.text = "EXEC /usr/bin/sipie_myth kill" for channel in row: #print(channel) found = "false" for genre in genres: #print(genre) if channel in genre: found = "true" if found == "true": continue button = etree.SubElement(channel_xml, "button") menu_type = etree.SubElement(button, "type") menu_type.text = "MUSIC" menu_text = etree.SubElement(button, "text") menu_text.text = channel[0] menu_action = etree.SubElement(button, "action") menu_action.text = "EXEC /usr/bin/sipie_myth play " + channel[1] button = etree.SubElement(channel_xml, "button") menu_type = etree.SubElement(button, "type") menu_type.text = "TV_DELETE" menu_text = etree.SubElement(button, "text") menu_text.text = "Stop Listening" menu_action = etree.SubElement(button, "action") menu_action.text = "EXEC /usr/bin/sipie_myth kill" #print(etree.tostring(channel_xml, pretty_print=True)) channel_file = "sirius_" + row[0].replace('/', '-').replace(' ', '_').replace('&', 'and').replace('\'', '').lower() + ".xml" FILE = open(channel_file, "w") FILE.write(etree.tostring(channel_xml, pretty_print=True)) FILE.close()
--Dmfrey 05:43, 20 December 2008 (UTC)
Tag definitions
OK, now the tag definitions for the above xml file
- "button" tells the theme to paint a button on the screen
- "type" tells the theme what image to use for the button
- "text" tells MythTV what button text to put on the screen
- "action" tells MythTV what to do when you select the button
Why it works
You have to wrap sipie_myth around the stream because when MythTV runs the EXEC it waits for a response before it releases the button. sipie_myth simply kicks off the stream and tells MythTV that it's finished executing. You are going to have to modify the XML menu files if you want to add another language tag or if you want to add additional channels.
Additional Setup and Usage Notes
- Be patient after you choose a stream as sometimes it will take 30 - 45 seconds to start playing
- The stream will play until you choose the "Stop Listening" button on the GUI (or sipie_myth kill is executed)
- When you're listening to a stream, it locks up the audio output device for MythTV which can be good and it can be bad, see below.
- GOOD
- If you want to watch a Football game on TV and listen to the commentators from Sirius instead of the TV commentators
- BAD
- If you wanted to play 2 audio streams at once to make your own mix tapes. ;-)