-*- outline -*- *General The idea is to have a set of simple services that run in parallel. We could use either: - Our own kernel - Something rigged with co-routines - A framework like twisted. **The services are: - A queue (maintains playlist state and services requests for insert, peek, pop) or queue manager (maintains several such persistent queues) - The player (retrieves tracks from the queue and plays them, and services requests for start, stop, skip, back) --- can be pointed at different queues - The database (holds details on the available tracks and services browse and search requests) **Where do these live? - Maintaining previous tracks for back (especially with the random queue) - Scanning for new music - Getting random tracks from the database - The interface for starting crawls *Data structures - Tracks can be identitifed by their physical location. - Track information can just be a dictionary - Will RDFlib scale to 1000s of tracks? Newer versions of RDFlib have regexp support. It could be useful for querying, anyway. *Interface - The web interface can work with the above services fairly directly (is Ruby on Rails good for that sort of thing?) - It can be configured with the addresses for the services, and understand their protocols. - Some AJAX-y stuff may be in order, especially for things like search *Protocols **Database - I like the idea of RSS (possibly with enclosures) for search results; the database can have an HTTP interface which is: - GET for searching: GET /optional-artist-name/optional-album-name/?some+search+terms - PUT/POST for new entries (PUT RSS too?) - over time this could be more sophisticated, PUTting individual tracks (i.e., uploading tracks) http://gonze.com/rss_plus_time.html has some notes and links about things like track length in RSS. **Queue manager - Again RSS seems a good fit, although with some namespaces mixed in for track information - GET / gets the list of queues - GET /queue-name/optional-from-position/optional-to-position - PUT /queue-name/position followed by RSS - POST same as PUT but just appends? - DELETE /queue-name/optional-from-position/optional-to-position - What about transactional stuff? Perhaps done in the interface, by checking modified times. **Player - I suppose it's useful to use HTTP here, but it doesn't need to be sophisticated. Just GET really, with commands: - play - skip - back - volume?level - queue?queue-name - status - The return value can just be the current status, every time. Not sure what format though. *Implementation In general, most things don't need locking. The player can block while there are no tracks in the playlist (co-routiney that). **Database **Playlist The random queue can be just a special implementation of the queue that asks for random tracks when it needs them. Could there be other kinds of auto-queuing things? In terms of providing links, there will have to be a translation between 'file:' links and something usable by remote clients. It's probably OK to leave that for now though. **Player PyXMMS may be useful here, if not something lower level. What may be a pain is being able to know when XMMS has finished a song, so that another can be queued. I guess the other way to do it would be to put everything on the XMMS playlist when the player changes queues, and somehow be notified if the queue itself changes. PyGame http://www.pygame.org/docs/ includes a library for mixing music streams. It seems like it can only play files though. *Snippets **Scanning - Use a list of regular expressions to attempt to extract the track names and so on; - Find something to interpret index.html files, so can add from http://... - Other protocols? Maybe not much point .. perhaps could automate iTunes, XMMS, WinAmp. - Are there mp3 tools for extracting the information? Look at python-eyeD3, http://members.optushome.com.au/datasync/programming/mp3cddb/, - Catalogues could be pingable, so the scanner can check occasionally and disable things that aren't connected **Database - How to store music-specific information, like track length? **Playing - Where/How to play can be an abstract method **Protocols - May be more light-weight to use something like JSON, since we're mostly passing around dictionaries, and it's well-supported for JavaScript: http://www.json.org/js.html (JavaScript), http://undefined.org/python/#simple_json (Python) - Some/all services can support both RDF and JSON if necessary.