Sirius/XM now has the ability to listen via the web. The new page uses a flash plugin for playing a particular stream. There is a username/password box and then it allows you to choose a station much like a jukebox. After 90 minutes of listening it will ask you if you are still listening. Is there a way to incorporate this into Linuxmce similar to HULU? Also, the place I listen most I don't have a keyboard mouse. Is it possible to use the remote with flash? Is it possible to pre-populate the username/ password?
Thanks Kevin
Sounds like a fun project... but I think these guys are busy crushing bugs rather than feature enhancements. It sounds pretty easy, so I will look into it, because my powers are weak. I know that flash is... glitchy at best in firefox.
A cursory examination reveals that the streaming protocol for Sirius XM is exposed via SOAP.
Look at Sipie for an example of how it was solved in Python, and make an equivalent C++ device.
However, to do this right, I would suggest making a Sirius Plugin, and a Sirius Streamer, that can provide a URL that can be passed via MH Play Media. This would allow it to work on all LinuxMCE devices, including Squeezeboxes. Look at existing code for a reference.
Grab usernames and passwords from Users, so that each user can have their individual subscription preferences.
Point being, this is more than possible, and can actually be done right.
-Thom
Thom,
It has been a while since I have coded in C++. But would be more than willing to give this a go when I get some spare time. I will try to look at the wiki and gather as much info/knowledge as possible, but I am sure I am going to have many questions.
Kevin
Thom,
When you say it is exposed through SOAP, does this mean the Flash plugin uses a web service to communicate with the Sirius server? Meaning I could potentially create my own client as long as I know the web services to call? Is this what you mean by the streamer?
Kevin
Yes.
Again, study Sipie.
-Thom
Look also at pyxis
also learn the MH Play Media command in the Media PlugIn. This is what you will need to use to actually take the stream and send it to a player.
If it is as I suspect, you'll get back an MP3 stream after sending what you want to get information wise by SOAP, this can be passed to the MH Play Media command to send the appropriate commands to the target player, rather than having a player embedded into the Sirus XM device.
-Thom
Thx.
What tool did you use to capture the Flash http traffic to determine they were using a SOAP based web service?
I will try to take a look at that stuff in the coming days.
i just took a look at the Sipie code All of 5 seconds.
-Thom
Took a look at Pyxis since Sipie has basically been deprecated. My game plan is to mess with this in Java since that is what I am most familiar with at the present. Once I get something working there and understand the communication, I will port it to C++ which shouldn't be to big a deal. Once that is done I will work on understanding MH player and streamer.
Have you had a chance to look into this?
I started a wiki page- but am clearly seeing that I don't even know where to begin.
http://wiki.linuxmce.com/index.php/SiriusRadio (http://wiki.linuxmce.com/index.php/SiriusRadio)
It looks like the StreamHandler.py file just runs a command titled self.command that feeds the stream and timestamp to mplayer. I was trying to follow the Shoutcast Radio Plugin to see how that called xine or mplayer and mimic the process, but I don't understand the function calls...
Basically,
Shoutcast Plugin merely provides a data grid to the media plugin.
Since Shoutcast is merely sending playlist files, and since Xine can read those playlist files, the Shoutcast PlugIn merely forms a URL to the playlist on the Shoutcast server.
This will not work for Sirius XM.
You will need to investigate how the stream is loaded and decoded. Based on this, you may be able to make a sort of proxy that you can pass to MH Play Media (passing a URL in the Filename device data parameter.)
Basically, MH Play Media, will send a CMD Play Media command to the Plugin that handles the media type for an entertainment area, normally this is the Xine PlugIn...the Xine Plugin then finds any Xine Players in the target entertaninment area, and sends a CMD_Play_Media to them.
To see the effect, go to the web admin, go select the media plugin in the device tree, and select "Send Command" and select "MH Play Media" ... you'll see the parameters you can pass to the command.
-Thom
Thanks Thom-
Based on MH Play Media, it looks like the only field I would populate is #13 Filename- the others- PK_Device and EntertainArea would be set by wherever we wanted the media played. Songs would not be repeated or queued- the idea would be to just stream, so #117 and #253 are not needed.
As for populating #13 Filename- the authors of Pyxis made it very simple (this is from StreamHandler.py):
print "Starting mplayer..."
if self.options.record:
stream = stream.replace(' ','') + '_'
now = datetime.datetime.now()
filename = stream + now.strftime("%Y-%m-%d_%H-%M-%S") + '.wav'
mpc = "%s '%s'" % (self.command + filename, url)
else:
mpc = "%s '%s'" % (self.command, url)
log('mpc = %s' % mpc)
self.pipeopen(mpc)
And from the Config.py file, the above just feeds the stream to mplayer:
self.config.set('mediaplayer', 'command', '/usr/bin/mplayer')
It seems like a simple script that run "pyxis" and waited for the user to select a channel to import to the prompt at the terminal- then that channel was fed into #13 Filename above, you would have the start to a working Sirius integration.
So, where do I go from here? How do I get LMCE to grab this stream?
Edit 1: If you type in "print mpc" immediately after defining mpc under "else" in the above code, it prints out the actual address of the stream.
Edit 2: You can pass the pyxis python script the stream when you start the program. For example, you can type in pyxis "espn radio"
and the espn stream will automatically start when pyxis loads.
Sirius and XM have changed their web site in the past month. Not sure the streams in Pyxis or Sypie will work anymore. XMTuner works against the new Sirius/XM servers. I have used FiddlerCap to capture the outgoing http communications. Another program that I think works is XMmicroplayer. I haven't had a chance to mess with this lately. I am able to pull the current information as far as stations and currently playing. Can even find small icons, am working on finding larger ones. Once I get time I also want to try and get the stream working. I am doing all of this through java currently since it is what I am currently programming in.
Cool- thanks for working on this. I was playing with it to try something.
I can confirm that pyxis currently works out of the box. I don't know if Pyxis changed to match the website changes, but it worked with no issues as of last night march 7, 2011.
My idea was to have SIRRUS/XM show up in the media list, just like AUDIO, VIDEO etc. Then the channels icons would show up in the matrix much the same way albums or movies do. You could use the categories passed back from sirius to sort genre etc. Then when you clicked a station the artist, song and album would be listed in the now playing as you have stated. I have an 11 month old at home and my wife works second shift, so finding time to mess with this is sometimes difficult.
Have you had anymore time to look at this? I think I need to find a developer IRC that can answer a couple questions. Really I need to know how to tie into LCME's system.
The stream from pyxis is very straight forward- it even calls mplayer to play the stream. If LMCE would rather use xine- I don't know enough to know if/why that would be problem. All I need to do is have a program that calls pyxis and feeds it a stream.
Right now, I have a shortcut on my desktop with the following code:
#!/bin/bash
xterm -e pyxis "Siriusly Sinatra"
All it does is opens up a terminal, and tells pyxis to cal up the Frank Sinatra channel...
Obvious this is far too static for what is needed to implement into LMCE, but if I knew how to get that part to call from a button called on the UI I think I can tap away at my keyboard until the next roadblock.
I don't even need someone to tell me how to do it- even just pointing to a template that does something similar would be helpful- I think.
that's not good enough.
We support a lot of different devices, and LinuxMCE needs to be able to send a stream to those devices, not only media directors, but also Squeezeboxes, and the like.
Come on fellas, stop thinking hacks, and actually learn the system.
start with the Developers Guide on the wiki.
-Thom
Sorry,
I haven't had a chance to look at it much. I am away on vacation thru the weekend so maybe I can get some time on the plane.
I will also look at the wiki!
Kevin
Quote from: tschak909 on March 15, 2011, 06:02:02 AM
that's not good enough.
I totally agree. Given my very limited (read: no programming skills) it is a
start and would waste nobody else's time other than my own and those that read my posts here on the thread.
From the Developers Guide- it appears I need to learn how to use DCEGen mentioned here: http://wiki.linuxmce.com/index.php/Developers_Guide#5._The_devices (http://wiki.linuxmce.com/index.php/Developers_Guide#5._The_devices)
Based on the modular design, I think my approach is correct- if I can get something static working on my core, I can then branch that into sending the same static stream to my MDs. From there, making the stream dependent on what the user chooses would just be another piece in the puzzle. I am pretty aware of my programming limitations and I think trying to builid a fully functioning plugin off the bat would lead to nothing but failure and a lot of frustration.
At any rate, searching the wiki for golden nuggets, I found this: http://wiki.linuxmce.org/index.php/C%2B%2B_Project (http://wiki.linuxmce.org/index.php/C%2B%2B_Project) It describes installing dcegen and the process for creating a device template. This is the road I'm going to stumble down- so if someone knows this is the wrong road and could point me down the correct road, it would be greatly appreciated. Even confirmation that this is the correction path would be helpful.
As a side note, while my goal is to get Sirius working in LMCE, I wonder if most of what I have to learn to get there will differ greatly from the topic of this thread and, hence, warrant a new thread....
That is the correct path.
And for those who take the time, I will always bend over backwards to help.
-Thom
Thom,
I have the high-res vector graphics for the channel logos. What is the best size, resolution and format to create logos for use in the grid?
Thx.
Kevin
Cool! :)
rendering them in png format 532x532 would probably be best.
-Thom
Thx.
I'll try to get them done by the weekend.
How is this? Not a graphic artist so any suggestion will not be taken to heart. If someone who is good at this wants to provide me a vector file to use as a background, I can easily add the logos to it and raise or lower an object as needed.
not bad at all!!! and you said you were not an artist!!!
Dennis
I have created button logos for all the sirius channels that are available over the internet.
Thom,
If I want to create a grid similar to music or videos, searchable by category, do I have to do any coding, or is that all done within the database? I figure I will attack navigation and get that working before I attack sending anything to the media player.
Thanks,
Kevin
That is all done in code. We have a Shoutcast PlugIn which does just this:
http://svn.linuxmce.org/svn/branches/LinuxMCE-0810/src/Shoutcast_Radio_Plugin/
and it is documented here:
http://wiki.linuxmce.org/index.php/MediaSourcePlugin
-Thom
Ok Thom, I took a quick glance at the Shoutcast plugin and have a few questions.
First, it looks like I should be able to use most of this code as is. Meaning change the Shoutcast_Radio_Plugin class to Sirius_Radio_Plugin class and use most of the same members. I will need to add a member to handle the sirius login, retrieve cookies etc and possibly manipulate the call to createMediaStream. Is anything else going to be needed outside of this plugin?
It doesn't look like I have to change anything in the main class, other than the Class name being called. Are these correct assumptions?
Also, is this something I can do on my current setup without rebuilding the whole system, I currently am lacking a dev machine at this time.
You can do all the dev work against an existing core. I do this often.
As for the plugin, the plugin's only job is to:
(1) create the data grids
(2) create the media stream so that the system knows it's there, and give it a specific type
(3) make sure that when it's passed a media stream, it's the right one
(4) find matching player devices in a given entertainment area that can play the stream
(5) send the play command to the appropriate players.
-Thom
Thom,
Have managed to dig into this a bit and am going to just rewrite the Shoutcast plugin for now. Since the XML reader on my system isn't working properly I am just going to define the list of genres and stations as an array of Strings and Stations and load them into the vectors on startup instead of trying to pull them from sirius.com.
I am going to try to get the grid working first before I go logging in and grabbing the stationURL which takes several different calls to sirius.com and manipulation of the response.
My question is concerning the Picture used.
In the wiki it says to use Row_Picture *AddPicture(string sFile);
Does this always add a picture or will it check to see if it is already registered and return that? i don't want to add the same picture everytime the plugin is loaded.
Thx Kevin
OK, I grabbed all the linuxmce source from svn and am trying to build just the Shoucast plugin. Getting all kinds of errors. Am I barking up the wrong tree?
I don't have a test environment so i need to be able to build and test from my core without screwing things up.
Any help is appreciated. I have tommorow off work so I was going to try and really get something working.
Thx,
Kevin
(1) do this on your core,
(2) put all the contents of /usr/pluto/lib into src/lib to bootstrap things.
-Thom
Quote from: kyfalcon on April 21, 2011, 10:07:06 PM
"rewrite the Shoutcast plugin for now. "
Certainly not trying to bust your balls- both because you're still working on this and because you are much more capable of reading the tables in LMCE. That said, not sure why you are focusing on a portion of the code that seems, to me, to be already done with Pyxis. Everything from the initial setup, to username/handshake, to station identification retrieval to playing the stream is already coded. I have been trying to figure out how to get LMCE to accept the stream.
Back to the point, why not use the existing (and future) code from the Pyxis project who have a following dedicated to following any changes made by Sirius and are quickly able to release new versions as required? I have looked quite a bit into the Pyxis code to try and understand how it works. I have duct taped a simple script on my desktop just to see the effects of code changes in Pyxis. Certainly nothing that can be folded into LMCE, but I need to start somewhere....
I can't promise I will be of any help, but will continue to try to make a contribution...
/My apologies for anyone who read my previous comments- I've decided they were not beneficial to the forums or anyone and should be removed. Would rather keep on topic and get Sirius integrated...
If you do use Pyxis, you'll need to rip out the user interface code, and replace it completely with the DCEGenned code, connecting pieces appropriately.
I do not see why this seems to be beyond people's comprehension. There are so many examples of merging DCE bits with existing code bases:
* SimplePhone (uses LinPhone in a separate thread)
* lmce_launch_manager_old (uses Qt UI code, instantiated in a separate thread from Main.cpp)
* Xine_Player (uses libxine and spawns a thread to handle xine streams and time code)
Those are just three examples.
-Thom
All pyxis does is make calls to the sirius website and pass the url to mplayer. I have mimic that much in java. The real benefit will come from taking that knowledge and being able to choose the stations from a gui rather than having to go to a terminal and typing in the station you want to listen too. Much more efficient and user friendly. The problem for me is it has been 7-8 years since I have coded in c/c++ so I am a little rusty, probably even longer since I have done c++ in unix/linux.
Thom once I copy that stuff will i be able to just compile the Shoutcast plugin only?
What about my question concerning the button images?
Again thanks for the help.
I know I am close on this.
don't worry about duplicates. :)
Once you have the stuff in lib, you'll be able to compile the shoutcast plugin so (with make so... all plugins are compiled with make so)
You can then copy it into /usr/pluto/bin
and create a child device of the DCERouter, select the Shoutcast PlugIn.
reload router, regenerate all the orbiters, and you will see a new Shoutcast audio source when you select Audio.
-Thom
the shoutcast object file builds fine but when it tries to build the httpUtils I get all kinds of curl errors.
Did I miss something?
you're probably missing curl-dev as a package. install it.
-Thom
The grid is working with genres ad stations ;D
Next will be to add the graphics for the stations.
Thx for the help Thom!
np man, I'm proud of ya. ;)
See guys? I will BEND OVER BACKWARDS for _ANYONE_ who is willing to dig in and try. ;)
-Thom
Quote from: kyfalcon on April 22, 2011, 09:23:41 PM
The grid is working with genres ad stations ;D
Sweet- really look forward to trying this. Great job!
Will you be able to share the steam across mds, or will each MD require a separate stream?
Quote from: huh on April 22, 2011, 10:06:47 PM
Sweet- really look forward to trying this. Great job!
Will you be able to share the steam across mds, or will each MD require a separate stream?
Baby Steps.
Ok Thom my pointer knowledge is located in my brain where the fuzzies live. I'm getting this error
Shoutcast_Radio_Plugin.cpp: In member function 'void DCE::Shoutcast_Radio_Plugin::loadStations()':
Shoutcast_Radio_Plugin.cpp:539: error: invalid use of incomplete type 'struct Row_Picture'
../Media_Plugin/MediaAttributes_LowLevel.h:45: error: forward declaration of 'struct Row_Picture'
I have a Structure called Stations which has a member picID which is a long int.
The code below in bold is giving me the error.
while(count < 120){
Row_Picture *p_MyPic = m_pMedia_Plugin->m_pMediaAttributes->m_pMediaAttributes_LowLevel->AddPicture("/home/mediapics/" + StringUtils::itos(stations[count].id) + ".png");
stations[count].picID = p_MyPic->PK_Picture_get();
m_vectStations.push_back(stations[count++]);
}
Make sure you have the includes for pluto_media in your plugin.
-Thom
That worked!
I have gotten so used to Java ide's where you ask it to fix imports :) It's become a whole different mindset and not necessarily for the better.
Quote from: kyfalcon on April 22, 2011, 11:24:40 PM
Baby Steps.
:). Of course- not trying to push- just don't know the limitations. I am curious if it would be like mythtv where the stream appears to only be able to go to one MD or if it is like an audio stream that can be sent to multiple devices. If each MD required a separate stream, would you need multiple streaming accounts? Font think two can be streaming under the same user/password.
Also, have you considered how you are going to handle the 90 minute (iirc) timeout period after which time you have to tell Sirius you are still listening. Is there a way to know the time is up and automatically sent a "still here" signal, or is a user interface required to have the user physically press yes? I will read the legal to see if I can see somewhere that automatically answering the question is against their terms of use.
Again- not trying to push- these are part of the list of questions I wrote myself in the hopes of getting to if I was able to even get as far as you.
The grid is working with images! I may change the images at a later date because it looks like the dce added a background color.
the 90 minute timeout is strictly a function of the sirius web app. I can play all day in pyxis or the windows app i use at work.
As far as streams go, Thom could better answer that.
The next part will be to use curl to do the login and handshaking needed to get the url of the stream. I assume I would pass this to the start media function.
Are you pulling down JPEGs or PNGs for images?
-Thom
Quote from: tschak909 on April 23, 2011, 01:29:33 AM
Are you pulling down JPEGs or PNGs for images?
-Thom
Row_Picture *p_MyPic = m_pMedia_Plugin->m_pMediaAttributes->m_pMediaAttributes_LowLevel->AddPicture("/home/mediapics/" + StringUtils::itos(stations[count].id) + ".png");
I then populate with the ID that gets returned.
OK- I'm not a lawyer, but to insure that LMCE stays within Sirius' terms and conditions per their terms of use: http://www.siriusxm.com/customeragreement (http://www.siriusxm.com/customeragreement), I think there are a couple items to keep in mind. Please keep in mind (AFAIK), Sirius is only available to customers in the US and Canada.
1) Per C.3, "You may only listen to to the Internet Radio Service on one single Internet enabled device at one time." As that all MDs can access the internet, it would appear that each MD would require a separate username/password. That said, I have several Squeezeboxes, and when you sync them, they are obviously Internet enabled devices and accessing the same stream at the same time. I would guess that Logitech would follow their own Terms and Conditions and would not allow something natively that violates their Terms and Conditions. Arguably, then, in practice, sharing a stream across multiple MDs would be, essentially, identical to Squeezeboxes share a stream across across multiple Squeezeboxes. I would argue that if sharing the stream across MDs violates the T&C, then sharing across Squeezeboxes does the same.
2) C.4 talks about personal use only. During install, I don't see that any disclaimers warn the user against using the software for commercial purposes, but maybe that is inherent in the PPL or GPL licenses (again, not sure the legal behind LMCE). Just like a user could commercially play a DVD in a commercial setting, a user could play the Sirius stream in a commercial setting. I think it is up to the user to insure they follow the laws of their respective countries. I just wonder if LMCE somewhere should somewhere very visible declare the user responsible for the actions taken by the installer- and maybe it already does. I wonder if items like these are added to the software list during the initial setup or in the admin, that the popup (or other means of informing the user) shouldn't mention the user's responsibility to follow their local laws.
3) C.5 is very interesting.... "You may not... construct a media player or interface that accesses the Internet Radio Service. In addition, your use of any products or services that access the Internet Radio Service an which are provided by third parties not authorized by us constitutes a violation of this Agreement, even if you did not create such product or services and/or do not understand how they were created." I don't see that there is a list of "authorized" third party programs that are allowed to access the streams. I don't understand how Pyxis grabs the stream or how the LMCE integration will grab the stream.... I don't understand enough about how this will work and what is acceptable to make an argument one way other other.
This post is meant purely as a opinion and my way of contributing to the project. I am not a lawyer and could be totally off-base with my opinions of the legal documents. I sincerely hope that in no way this stifles Sirius integration into LMCE. I will continue my pursuit of the legal aspects of integrating Sirius into LMCE and post here as information becomes available.