I'm currently implementing a plugin to stream radio from last.fm. After initial handshakes you can retrieve a xspf playlist, which is easy enough to parse and use the mp3 locations for playing. However I'm also trying to add support for handling the "lastfm://" URLs, and I'm not sure how to do this.
If I understand correctly, if I use a class based on input_impl I can use the g_is_our_path method to identify the "lastfm://" part of the path successfully, but then I need to implement the audio decoding, and maybe treat each location as a subsong. More logical would be to derive from the playlist_loader class (as I'm effectively trying to load a playlist), but I can't do this as the get_extension method only considers the extension which the URLs don't have.
If anyone has any hints or ideas it would be greatly appreciated.
I don't know how handling lastfm:// URLs works exactly, some searching on the net revealed that you have to create a http:// URL that contains them as a parameter. Regarding your problem: playlist formats can also be recognized by content type ("application/xspf+xml" for XSPF), see playlist_loader::is_our_content_type() (http://foosion.foobar2000.org/doxygen/0.9.5.2/classplaylist__loader.html#a77863049d2b0a0a2b98308c5f3251c3). Then you only need something to read from a lastfm:// URL that can also report the content type.
That's where the filesystem (http://foosion.foobar2000.org/doxygen/0.9.5.2/classfoobar2000__io_1_1filesystem.html) service comes into play. Basically, you could implement a filesystem service for lastfm:// URLs that would internally create the proper http:// URL and retrieve data from that (you could delegate this to the existing filesystem handler as long as you only need to do HTTP GET). Of course, you have to be careful about session management and synchronization. as the filesystem handler can be used from arbitrary threads.
Edit: There is also another way that results in a less seamless integration, but is a bit easier to implement. You could add your own UI for entering lastfm:// URLs, for example a dialog invoked by the main menu command "File/Add Last.fm playlist..." (or whatever would be an appropriate name). In that case, you have full control about the way the entered URL is handled.
Thanks for the help.
I have managed to implement it as you have suggested, with a lastfm:// filesystem, and using the is_our_content_type() method in my playlist loader. I however haven't worked out how to report the correct content type. (Currently I cheat by returning true for "text/plain;charset=utf-8", but obviously this isn't a solution...)
I assume I need to declare a new file class which overrides the get_content_type() method, and then do something like type cast p_out of my filesystem's open method to that new type. Does that make any sense?
You would have to implement your own file class that forwards all calls to a file object for the HTTP address except for the get_content_type() method.