mpd is the single best music player for what you're describing. You can choose how you want to interact with it. And if you can't find an implementation you like, the API is simple enough you can write something yourself.
Even better, you don't have to 'choose' - in the sense that you can simultaneously connect to mpd via different interfaces (in this same thread I mention how I use ncmpcpp for some things, and cantata for other things).