You are not logged in.

#1 2009-05-27 12:15:35

HashBox
Member
Registered: 2009-01-22
Posts: 271

[HOWTO] Mplayer music daemon

Hello fellow Archers,

I recently noticed that XMMS2 was using 40% of my CPU (not sure how I missed it but it no doubt has something to do with my setup) and decided I needed to correct this. My plan was to initially write my own music server, but that turned out to just be a pain in the ass considering how many formats mplayer supports, so here is my solution.

This setup consists of a few tiny scripts put together to form a very *minimalist* music daemon.

To start, you should create a directory named ".musicd" under your home directory, then run "mkfifo ~/.musicd/control" to create the control pipe.

Now on to the scripts,

The first is "musicd", it is a shell script that looks as follows:

while true; do mplayer -input file=${HOME}/.musicd/control -af pan=1:0.5:0.5 -quiet -playlist ${HOME}/.musicd/playlist | songinfo; sleep 1; done &

This takes care of running mplayer and making sure it can be communicated with. The "-af pan=1:0.5:0.5" can be removed, I use this to down-mix everything to mono for my crappy sound setup.

The second is actually a tiny C program, that could no doubt be implement using common unix tools but I didn't really bother tying:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main()
{
    char artist[128];
    char title[128];

    char buffer[128];

    char path[128];
    snprintf(path, 128, "%s/.musicd/current", getenv("HOME"));

    while (!feof(stdin)) {
        fgets(buffer, 128, stdin);

        buffer[strlen(buffer)-1] = '\0';

        if (!strncmp(" Title:", buffer, 7)) {
            strncpy(title, buffer + 8, 128);
        } else if (!strncmp(" Artist:", buffer, 8)) {
            strncpy(artist, buffer + 9, 128);
            FILE *fp = fopen(path, "w");
            if (fp) {
                fprintf(fp, "%s - %s", artist, title);
                fclose(fp);
            }
        }
    }
}

This program can be compiled with "gcc -o songinfo songinfo.c" and placed somewhere in your path. It simply takes mplayers output and listens for the "Title:" and "Artist:" sections and writes it to a file for use in status bars etc.

Technically this is all you need for it to run now, and you can even start the musicd script if you wish. However for it to be useful you will probably want to make use of the next script. Also it might pay to create a playlist before running mplayer or it will sit there looping and looking ugly, but that is up to you

locate -i "$*" | grep -E 'mp3|ogg|wma|m4a|wmv|avi|mpg|ogm$' > ${HOME}/.musicd/playlist
echo "stop" > ${HOME}/.musicd/control
echo "loadlist ${HOME}/.musicd/playlist" > ${HOME}/.musicd/control

Save this somewhere in your path as "play". If you have started the musicd script it should actually be functional now, if you type "play artist" then locate should find the files and load them into mplayer and it should start playing smile

As a bonus, I've made this neat little script utilizing dmenu to let you quickly select recently used entries:

HISTORY_FILE="${HOME}/.playhist"

SELECTION=`cat $HISTORY_FILE | dmenu -p What\? -i -nb black -nf grey40 -sb grey10 -sf grey80 -fn "-*-proggyclean-*-*-*-*-*-*-*-*-*-*-*-*"`
if [ -n "$SELECTION" ]; then
        echo $SELECTION | cat - $HISTORY_FILE | sort | uniq -i > $HISTORY_FILE
        exec play $SELECTION
fi

Save that one as whatever you like, and bind to a key using your window manager configuration or xbindkeys smile

Now you're done! You may also want to set up scripts or aliases to send pause or stop commands to mplayer as well but that should be trivial if you got this far.
Also if you want to see the song that is playing you can just use "cat ~/.musicd/current".
Oh and one more thing, using mplayer has the added advantage that you can play a video playlist in the same way as you would for music, or switch between the two easily smile

If you have any questions please ask!

Edit: Using snprintf, and removed -idle from mplayer launch line to enable playlists to repeat

Last edited by HashBox (2009-05-28 00:11:30)

Offline

#2 2009-05-27 12:54:04

karol
Archivist
Registered: 2009-05-06
Posts: 25,440

Re: [HOWTO] Mplayer music daemon

HashBox wrote:

Save this somewhere in your path as "play".

I think sox has a command 'play' so you might want to keep this in mind.

Offline

#3 2009-05-27 13:10:43

Nezmer
Member
Registered: 2008-10-24
Posts: 559
Website

Re: [HOWTO] Mplayer music daemon

Good effort but I have to ask :
What's wrong with mpd ?


English is not my native language .

Offline

#4 2009-05-27 17:28:09

dimigon
Member
Registered: 2009-03-07
Posts: 139
Website

Re: [HOWTO] Mplayer music daemon

From a quick look at the code, you've got at least one buffer overflow going on. Suppose I do

export HOME=`i=0; while [ "$i" -lt 10000 ]; do echo -n $i; let "i=i+1"; done`
./a.out

now try to run the code and give it an EOF or whatever. To fix it, replace sprintf with snprintf.

Offline

#5 2009-05-27 19:13:05

HashBox
Member
Registered: 2009-01-22
Posts: 271

Re: [HOWTO] Mplayer music daemon

Hehe thanks dimigon, I didn't bother paying too much attention to overflows since I knew I'd probably be the only one to use it, but I will fix that shortly.

@Nezmer, I was using MPD before I switched to XMMS2, and it's great but I liked the ability of being able to add files outside of the music directory. It's a small thing I know but that has been my main reason for creating this.

@karol, thank you for pointing that out smile

Offline

#6 2009-05-27 19:16:05

brisbin33
Member
From: boston, ma
Registered: 2008-07-24
Posts: 1,796
Website

Re: [HOWTO] Mplayer music daemon

HashBox wrote:

@Nezmer, I was using MPD before I switched to XMMS2, and it's great but I liked the ability of being able to add files outside of the music directory. It's a small thing I know but that has been my main reason for creating this.

someone in another thread mentioned using a tcp socket to pipe a random audio file through mpd (i.e. playing something one-off and outside of the database/library).  i was very interested but never got any further details.  something to think about...

/edit: i found two scripts here but they both create a temp symlink from the file outside your musicdir to a tempfile inside your musicdir, then update your mpddatabase and play the song with mpc... this is no good b/c updating the mpd db is so time consuming it makes it useless to me.  hence, my excitement at this 'tcp' idea -- that would be instant, if only it were possible.

Last edited by brisbin33 (2009-05-27 19:23:03)

Offline

#7 2009-05-28 00:07:10

HashBox
Member
Registered: 2009-01-22
Posts: 271

Re: [HOWTO] Mplayer music daemon

Thanks for bringing that to my attention, it does sound like a neat way around that limitation, and I agree with you about the the slowness of updating the database, although I don't think that is so much MPD's fault, but more of a filesystem slowness in general. Still maybe MPD2 will fix all that one day ;P

Offline

#8 2009-05-28 01:34:28

anubis2591
Member
Registered: 2008-07-06
Posts: 52
Website

Re: [HOWTO] Mplayer music daemon

brisbin33 wrote:

updating the mpd db is so time consuming it makes it useless to me

The most useful mpc command I use:

mpc update [directory goes here]

So just use that to update only your systemlink.

Last edited by anubis2591 (2009-05-28 01:35:27)

Offline

#9 2009-05-28 02:51:31

HashBox
Member
Registered: 2009-01-22
Posts: 271

Re: [HOWTO] Mplayer music daemon

Oh wow I had no idea you could do that, useful smile

Offline

#10 2009-05-28 09:50:24

madhatter
Member
From: Freudenstadt, Germany
Registered: 2004-09-01
Posts: 59

Re: [HOWTO] Mplayer music daemon

I have to admit I didn't look too closely on your scripts, but why do you have mplayer inside a loop? And why don't you take advantage of mplayer's nice slave mode? Seems to be just the kind of thing it was made for.

Offline

#11 2009-05-28 11:00:25

HashBox
Member
Registered: 2009-01-22
Posts: 271

Re: [HOWTO] Mplayer music daemon

With slave mode I would need a way to know when a track finished in order to start the next one. Basically how mine works is it listens to a fifo for commands which I basically use to update the playlist. The reason mplayer is inside a loop is that it seems to have no concept of repeating a playlist. Using -loop 0 has no effect with a playlist, and setting loop through the fifo causes it to loop only the current track. This is why I removed -idle from the command line aswell. The idea here is that when the playlist finishes mplayer will exit, and therefore the loop will start it again with the same playlist, effectly creating a repeating playlist.

I've been using this setup for little over a day so I'm still tweaking, but so far it has been working really well for me, the ability to easily switch to watching movies or tv shows is really handy for me too.

Slave mode is something however that I should look into some more, my original idea was to have an application that kept an internal playlist and issued commands to mplayer, but I gave up on it for some reason.

Anyway thanks for the input.

Offline

#12 2009-05-28 13:32:02

brisbin33
Member
From: boston, ma
Registered: 2008-07-24
Posts: 1,796
Website

Re: [HOWTO] Mplayer music daemon

anubis2591 wrote:
brisbin33 wrote:

updating the mpd db is so time consuming it makes it useless to me

The most useful mpc command I use:

mpc update [directory goes here]

So just use that to update only your systemlink.

hmm, maybe i'm a little confused; what's the difference b/w mpd create-db and mpc update? i always do both whenever i add new music to the collection.

/edit i'm thinking create-db recreates the db in it's entirety and mpc update will just update changes or a specific folder if passed... this is useful information, thanks.

if you're correct (i assume you are) then mpc-play is my new best friend big_smile

Last edited by brisbin33 (2009-05-28 13:36:37)

Offline

#13 2009-05-28 19:14:00

anubis2591
Member
Registered: 2008-07-06
Posts: 52
Website

Re: [HOWTO] Mplayer music daemon

brisbin33 wrote:
anubis2591 wrote:
brisbin33 wrote:

updating the mpd db is so time consuming it makes it useless to me

The most useful mpc command I use:

mpc update [directory goes here]

So just use that to update only your systemlink.

hmm, maybe i'm a little confused; what's the difference b/w mpd create-db and mpc update? i always do both whenever i add new music to the collection.

/edit i'm thinking create-db recreates the db in it's entirety and mpc update will just update changes or a specific folder if passed... this is useful information, thanks.

if you're correct (i assume you are) then mpc-play is my new best friend big_smile

Yeah, mpd create-db takes forever because it goes from scratch. mpc update updates the whole db and then mpc update Directory\ Name updates/adds only that directory. Amazingly useful if you add music as much as I do.

Offline

#14 2009-05-28 19:27:46

madhatter
Member
From: Freudenstadt, Germany
Registered: 2004-09-01
Posts: 59

Re: [HOWTO] Mplayer music daemon

I experimented a bit with the slave mode a bit just now,
and "loop 0" does not work indeed, although the documentation says otherwise it seems "loop 1" is needed to loop forever.
Why do you need to know when a track is over? You use playlists after all? Anyway, I noticed mplayer creates a new line when a track is finished.

here's my "setup":

$ mkfifo in
$ mkfifo out
$ tail -f in | mplayer -slave -idle -quiet | cat > out

$ cat out

$ echo "loadlist bla" > in
$ echo "loop 1" > in

Offline

#15 2009-05-28 19:50:19

HashBox
Member
Registered: 2009-01-22
Posts: 271

Re: [HOWTO] Mplayer music daemon

Sweet, if that is working as expected then I will have to make some modifications smile

Offline

#16 2009-10-24 05:11:41

fflarex
Member
Registered: 2007-09-15
Posts: 466

Re: [HOWTO] Mplayer music daemon

I realize this might require a rewrite, but even so it doesn't look too hard... you could incorporate the ideas from this to get gapless playback. I'll probably do it myself in a few weeks when my schedule winds down, if nobody else has already (along with rewriting the C program as a shell script, since I don't understand it).

EDIT: I never got around to doing this, but mplayer2 has a gapless audio switch!

Last edited by fflarex (2011-03-31 20:31:02)

Offline

#17 2009-10-24 23:58:38

HashBox
Member
Registered: 2009-01-22
Posts: 271

Re: [HOWTO] Mplayer music daemon

That sounds like an interesting idea, unfortunately I'm not using Linux at the moment so I'm unable to experiment with it, but I still have the scripts and stuff on my drive, so maybe it would be worth me putting it into a github repository so it's easier to fork and modify?

Offline

Board footer

Powered by FluxBB