Max, On Fri, Jan 28, 2011 at 2:56 AM, Max Kellermann <m...@duempel.org> wrote: > On 2011/01/27 18:11, Tim Carter <t...@frontierdigital.com> wrote: >> What I need is for MPD to retain persistent play history for a given >> playlist. The goal is to enhance the 'repeat' functionality so that a >> given song would not repeat until the entire list had been played >> through completely, even if another playlist were loaded in the interim. >> >> For example, if playlist_1 has tracks 'A', 'B', 'C' and 'D'; playlist_2 >> has 'E', 'F' and 'G'. >> playlist_1 is loaded (with repeat & random enabled). Tracks 'B', 'D' >> and 'C' play. Playlist_2 is then loaded and track 'E' and 'F' are played. >> Finally, playlist_1 is re-loaded. I want track 'A' to be played before >> 'B', 'D' or 'C' are played again. > > What about a client which keeps track of songs already played, and > when that song is added to the queue again, it will auto-remove it? > > That client could run as an accompanying daemon next to mpd.
That sounds kind of nice :-) The client could potentially be written in a higher level language than C, and could grow user-requested "playlist workflow" features like this if they don't fit quite exactly into the main mpd daemon. Writing it in something like Vala (OK, my favorite language lately ;)) would greatly ease maintenance, IMO. It certainly seems like that something that could be done efficiently with a client, particularly if the client runs on the same box as the mpd daemon. The only problem is that mpd itself would be completely unaware of this external daemon's existence, and as such, would not (could not) provide any management service for it (i.e. stopping and starting it, or configuring it). If the goal is not to touch the mpd core, then the most logical way to ease end-user management of said daemon would be to integrate it as a plugin into the most popular mpd clients. They'd have to make a separate TCP connection to the playlist workflow daemon. This method does add complexity architecturally, but it gives us the opportunity to use a higher-level language. The thing that convinces me this is a good idea is that, in general, whenever you can do something entirely using a client library, you should do so, rather than modifying the core. That's just good design, because it keeps the core "lean and mean". So I tend to agree with Max, now that I think about it. It's got a very UNIX-y flavor to it. :-) The next few days' worth of hobby time have me working on rbpitch < http://ubuntuforums.org/showthread.php?p=8229849 > but if no one else is interested by the time I have scratched that itch, I'd be happy to see what I can do. Since you so graciously offered a monetary component to your proposal, I would suggest donating 50% of any planned bounty (regardless of who is chosen to do the work) to the FSF. They need the money, and they are always doing amazing things to drive the free software movement. As to the actual architecture of the daemon : just brainstorming, but I think you would interface with mpd via one of the client libraries < http://mpd.wikia.com/wiki/Client_Libraries >, open up your own TCP port, and define a protocol. You could invent your own binary protocol, or go with something like google-protobuf or ZeroC ICE, or HTTP/SOAP. Then you just have to define the operations and the semantics. Come to think of it, that's probably the most difficult part of the whole job: determining exactly what the scope of the API should be. How generic do we want to get with the functionality? Here are a few example scopes : *Narrowest: Virtually no API, or you can skip the API, configuration, etc. altogether, and just have the daemon perform a static set of playlist manipulations (sounds like moving songs around in the playlist would be most logical), defined to match the stated requirements from Tim. *Narrow: A "low-fat" API, letting the user enable or disable a finite set of well-defined playlist manipulations. An example of another playlist manipulation that someone may want, would be, a way to have another playlist start after the current song is finished. Or even, insert the contents of one playlist into the middle of another for the purposes of a single playback, without actually merging the playlists in mpd's persistent database. *Most Generic: A "full-fat" API, implementing something like a rules engine (with its own grammar of some sort, or XML) for full customizability of playlist routing, and separate out the concepts of "Conditions / Events" (e.g., "Song Ended", "Time Unit Elapsed", "Song Started", "Volume Changed") and "Actions" (e.g., "Move Song in Playlist by N units up/down", "Delete Song from Playlist", "Add Song to Play Queue", "Stop Playing"), and allow the user to dynamically define an arbitrary set of conditions with boolean operators between them, and then an arbitrary list of actions when the conditions are met. The "Actions" would end up closely mirroring the push part of the mpd client interface, but the ability to basically "macro code" your own conditional / action pairs would be the uberform of satisfying this request and all other potential future requests of a similar nature. As you can guess, the difficulty (time / money / brainpower) needed to implement these goes something like: *Narrowest: Fairly simple project that any competent programmer could implement in their language of choice in a week or so. *Narrow: Still a fairly simple project, but with some extensibility tacked on, in case someone else has a similar request that we can add on later. But if we end up doing that a lot, then the management API of our daemon is changing each time... bad. *Most Generic: He he, this is the kind of "enterprisey" solution that businessfolk lust over, and smart programmers run away from as fast as they can. The thinking is, let's satisfy all potential user demands ahead of time, so we don't have to write any code the next time someone thinks of something they want! These systems run a serious danger of becoming an anti-pattern if they become *too* generic; see < http://thedailywtf.com/Articles/The_Enterprise_Rules_Engine.aspx > for a great example. That said, if you strike the correct balance between user empowerment and ease of use, it can actually turn out quite nice. But it requires substantially more time and manpower than the other options. Hope that helps you think about what exactly you'd like. If you think the Narrowest path (a literal interpretation of your requirements) would be best, it could be a quick hack we'd whip up for you, but its general utility "out there" would be fairly limited. Personally I kind of favor the "Narrow" path, but part of me wishes we could sit down to make something as generally useful as the Most Generic solution. Really, this decision is one of the most pivotal decisions to make. There are serious pros and cons to both sides; that is, making a program too specific or too generic. Scoping out exactly what we want, and setting realistic goals that can be met by the expected developers in reasonable time, is crucial. I get the feeling that Max and his predecessors in the mpd maintainer lineage have fought the scoping problem quite extensively while designing the mpd core. Maybe one reason Max suggested we split this out into its own daemon is exactly *because* we don't want to let this dangling scope cause feature sprawl inside the mpd core. ;-) -Sean > > Max > ------------------------------------------------------------------------------ Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)! Finally, a world-class log management solution at an even better price-free! Download using promo code Free_Logger_4_Dev2Dev. Offer expires February 28th, so secure your free ArcSight Logger TODAY! http://p.sf.net/sfu/arcsight-sfd2d _______________________________________________ Musicpd-dev-team mailing list Musicpd-dev-team@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/musicpd-dev-team