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

Reply via email to