playd: Easy to use mplayer wrapper with playlist support

killasmurf86 said:
OK, I wrote functions to get info from mplayer (currently not pushed to repository)
The problem is that it's very easy to kill mplayer (I think it's mplayers bug)
I will investigate deeper, when I have more time... I will probably push changes in few hours

OK, it's not mplayer bug, it's playd bug :)
 
How to populate playlist without playing it? I'm trying to start daemon with shuffled playlist from ~/.profile.
Code:
playd /path/to/music-dir
playd rnd
playd playlist
The thing is it starts to play the first file from that directory for a few seconds. Actually, there is a race in the above example that makes playd start two instances of mplayer.

Also, that note about hw.snd.vpc_autoreset in the man page can be removed. It's strictly mplayer's issue and the port's maintainer added a note (not committed yet)
Code:
===================================================================
If seeking in streams causes the playback volume to be reset to
the previous setting (on 8.x or newer system with VPC enabled),
you and you dislike this behaviour, you have two options:
- Use mplayer's -softvol command line option
- Set the sysctl hw.snd.vpc_autoreset to 0
===================================================================
 
eye said:
How to populate playlist without playing it? I'm trying to start daemon with shuffled playlist from ~/.profile.
Code:
playd /path/to/music-dir
playd rnd
playd playlist
The thing is it starts to play the first file from that directory for a few seconds. Actually, there is a race in the above example that makes playd start two instances of mplayer.
Current implementation makes it always play when you make new playlist
But I could add --noplay option

About race condition.... that's interesting... I noticed 2x mplayers, and thought that it was normal... now on slightly newer and powerful PC, I see only 1 mplayer. maybe adding sleep 1 after starting mplayer will prevent that... (can you test with your local playd?)
 
killasmurf86 said:
Current implementation makes it always play when you make new playlist
But I could add --noplay option
Please, do. It also may mitigate the bug.
killasmurf86 said:
About race condition.... that's interesting... I noticed 2x mplayers, and thought that it was normal... now on slightly newer and powerful PC, I see only 1 mplayer. maybe adding sleep 1 after starting mplayer will prevent that... (can you test with your local playd?)
No, I'm not talking about caching instance that mplayer spawns to buffer IO, -nocache negates it. What I see/listen is two tracks playing at the same time. The interesting thing is it does happen only in subshell
Code:
$ (playd /path/to/music-dir; playd rnd; playd playlist)
$ procstat -f $(pgrep mplayer)
  PID COMM               FD T V FLAGS    REF  OFFSET PRO NAME
99629 mplayer           cwd v d --------   -       - -   /
99629 mplayer          root v d --------   -       - -   /
99629 mplayer             0 v c r-------   1       0 -   /dev/null
99629 mplayer             1 v c -w------   1       0 -   /dev/null
99629 mplayer             2 v c -w------   1       0 -   /dev/null
99629 mplayer             3 f - rw------   1       0 -   /home/luser/.config/playd/fifo
99629 mplayer             4 v r r-------   1  360448 -   /path/to/music-dir/bar.mp3
99629 mplayer             5 v c -w------   1 1491968 -   /dev/dsp1.2
99207 mplayer           cwd v d --------   -       - -   /
99207 mplayer          root v d --------   -       - -   /
99207 mplayer             0 v c r-------   1       0 -   /dev/null
99207 mplayer             1 v c -w------   1       0 -   /dev/null
99207 mplayer             2 v c -w------   1       0 -   /dev/null
99207 mplayer             3 f - rw------   1       0 -   -
99207 mplayer             4 v r r-------   1  393216 -   /path/to/music-dir/foo.mp3
99207 mplayer             5 v c -w------   1 1560576 -   /dev/dsp1.1
$ { playd /path/to/music-dir; playd rnd; playd playlist; }
$ procstat -f $(pgrep mplayer)
  PID COMM               FD T V FLAGS    REF  OFFSET PRO NAME
 1312 mplayer           cwd v d --------   -       - -   /
 1312 mplayer          root v d --------   -       - -   /
 1312 mplayer             0 v c r-------   1       0 -   /dev/null
 1312 mplayer             1 v c -w------   1       0 -   /dev/null
 1312 mplayer             2 v c -w------   1       0 -   /dev/null
 1312 mplayer             3 f - rw------   1       0 -   /home/luser/.config/playd/fifo
 1312 mplayer             4 v r r-------   1  229376 -   /path/to/music-dir/bar.mp3
 1312 mplayer             5 v c -w------   1  785408 -   /dev/dsp1.1
It's probably not a race as sleep(1) between playd invocations doesn't help.

Also, you can close all those open file-descriptors for /dev/null by using
  • <&- instead of </dev/null
  • >&- instead of >/dev/null
  • 2>&- instead of 2>/dev/null
Code:
$ procstat -f $(pgrep mplayer)
  PID COMM               FD T V FLAGS    REF  OFFSET PRO NAME
 2914 mplayer           cwd v d --------   -       - -   /
 2914 mplayer          root v d --------   -       - -   /
 2914 mplayer             0 f - rw------   1       0 -   /home/luser/.config/playd/fifo
 2914 mplayer             1 v r r-------   1  491520 -   /path/to/music-dir/bar.mp3
 2914 mplayer             2 v c -w------   1 2132992 -   /dev/dsp1.2

BTW, does below piece work as expected? The quoting doesn't seem right.
Code:
* )
      	playd_warn "Sorry `echo "${1##*.}" | tr [A-Z] [a-z]` is unsupported playlist type. Ignoring"
      	return 1
      ;;
It should probably be either
Code:
playd_warn "Sorry `echo \\"${1##*.}\\" | tr [A-Z] [a-z]` is unsupported playlist type. Ignoring"
or
Code:
playd_warn "Sorry $(echo \"${1##*.}\" | tr [A-Z] [a-z]) is unsupported playlist type. Ignoring"
Notice how escaping double-quotes inside double-quotes differs between `...` and $(...) - a good reason to avoid using backticks.
 
How about jabber talk.... we're starting to spam FreeBSD forum with non-freebsd stuff :)
I'll pm you details
 
eye said:
Also, you can close all those open file-descriptors for /dev/null by using
  • <&- instead of </dev/null
  • >&- instead of >/dev/null
  • 2>&- instead of 2>/dev/null
Code:
$ procstat -f $(pgrep mplayer)
  PID COMM               FD T V FLAGS    REF  OFFSET PRO NAME
 2914 mplayer           cwd v d --------   -       - -   /
 2914 mplayer          root v d --------   -       - -   /
 2914 mplayer             0 f - rw------   1       0 -   /home/luser/.config/playd/fifo
 2914 mplayer             1 v r r-------   1  491520 -   /path/to/music-dir/bar.mp3
 2914 mplayer             2 v c -w------   1 2132992 -   /dev/dsp1.2
Doh, it works a bit differently on mplayer from Uoti's repo (in git) and mainline (in svn), e.g. closing input doesn't work on mainline
Code:
diff --git a/bin/playd.sh b/bin/playd.sh
--- a/bin/playd.sh
+++ b/bin/playd.sh
@@ -165,8 +165,9 @@ playd_start() {	# {{{1
 			|| local mplayer_run_cmd="$MPLAYER_SND_ONLY_CMD"
 		sleep 1
 
-		#{ ${mplayer_run_cmd} > "$MPLAYER_PIPE" 2> /dev/null & } \
-		{ ${mplayer_run_cmd} > "$MPLAYER_PIPE" 2> /dev/null & } \
+		#{ ${mplayer_run_cmd} > "$MPLAYER_PIPE" 2>&- & } \
+		# closing input fd works only on mplayer-uau
+		{ ${mplayer_run_cmd} > "$MPLAYER_PIPE" 2>&- & } \
 			&& echo "$$" > "$PLAYD_LOCK" \
 			|| playd_die 'Failed to start mplayer'
 		cd - > /dev/null 2> /dev/null
killasmurf86 said:
How about jabber talk.... we're starting to spam FreeBSD forum with non-freebsd stuff :)
I'll pm you details
No thanks, non-public discussions suck and cannot be found on google. This forum is about userland programming, what's so wrong about dev talk? If it turns out to be too voluminous you can create a mailing list to reduce noise ratio here.
 
eye said:
it works a bit differently on mplayer from Uoti's repo (in git) and mainline (in svn), e.g. closing input doesn't work on mainline
Oops, with -noconsolecontrols both work
Code:
$ procstat -f $(pgrep mplayer)
  PID COMM               FD T V FLAGS    REF  OFFSET PRO NAME
33484 mplayer           cwd v d --------   -       - -   /
33484 mplayer          root v d --------   -       - -   /
33484 mplayer             0 f - rw------   1       0 -   /home/luser/.config/playd/playd.fifo
33484 mplayer             1 f - -w------   1       0 -   /home/luser/.config/playd/mplayer.fifo
33484 mplayer             2 v r r-------   1   71680 -   /path/to/music-dir/foo.mp3
33484 mplayer             3 v c -w------   1  290816 -   /dev/dsp1.2
Code:
diff --git a/bin/playd.sh b/bin/playd.sh
--- a/bin/playd.sh
+++ b/bin/playd.sh
@@ -70,7 +70,7 @@ readonly CAT_LOCK="$PLAYD_HOME/cat.lock"
 
 # to customise mplayers command line set PLAYD_MPLAYER_USER_OPTIONS environment variable
 #readonly MPLAYER_CMD_GENERIC="$PLAYD_MPLAYER_USER_OPTIONS -really-quiet -idle -input file=$PLAYD_PIPE"
-readonly MPLAYER_CMD_GENERIC="$PLAYD_MPLAYER_USER_OPTIONS -quiet -idle -input file=$PLAYD_PIPE"
+readonly MPLAYER_CMD_GENERIC="$PLAYD_MPLAYER_USER_OPTIONS -noconsolecontrols -quiet -idle -input file=$PLAYD_PIPE"
 readonly MPLAYER_CMD="mplayer $MPLAYER_CMD_GENERIC"
 readonly MPLAYER_SND_ONLY_CMD="mplayer -vo null $MPLAYER_CMD_GENERIC"
 NOVID=0
@@ -164,8 +164,8 @@ playd_start() {	# {{{1
 			&& local mplayer_run_cmd="$MPLAYER_CMD" \
 			|| local mplayer_run_cmd="$MPLAYER_SND_ONLY_CMD"
 
-		#{ ${mplayer_run_cmd} > "$MPLAYER_PIPE" 2> /dev/null & } \
-		{ ${mplayer_run_cmd} > "$MPLAYER_PIPE" 2> /dev/null & } \
+		#{ ${mplayer_run_cmd} <&- > "$MPLAYER_PIPE" 2>&- & } \
+		{ ${mplayer_run_cmd} <&- > "$MPLAYER_PIPE" 2>&- & } \
 			&& echo "$$" > "$PLAYD_LOCK" \
 			|| playd_die 'Failed to start mplayer'
 		cd - > /dev/null 2> /dev/null
 
eye said:
BTW, does below piece work as expected? The quoting doesn't seem right.
Code:
* )
      	playd_warn "Sorry `echo "${1##*.}" | tr [A-Z] [a-z]` is unsupported playlist type. Ignoring"
      	return 1
      ;;
It should probably be either
Code:
playd_warn "Sorry `echo \\"${1##*.}\\" | tr [A-Z] [a-z]` is unsupported playlist type. Ignoring"
or
Code:
playd_warn "Sorry $(echo \"${1##*.}\" | tr [A-Z] [a-z]) is unsupported playlist type. Ignoring"
Notice how escaping double-quotes inside double-quotes differs between `...` and $(...) - a good reason to avoid using backticks.


It's fine.. Check this out:
$ echo "test `echo "x"`" in sh or mksh
 
Just pushed rev f17d1537ea9f
Now playd shows position in playlist.
Actually it guesses position in playlist by matching playlist entries and filename (full path) that mplayer is playd.
Thanks for your post with $ procstat -f $(pgrep mplayer) otherwise I would never thought of it :D

Now It should be possible to implement previous... (which should play previous song against first matched playlist entry of current song [Did what I said make sense, to you?])

:D
Woooooooot
 
  • Thanks
Reactions: eye
Hmm, new get functions are a bit buggy
Code:
$ cat /tmp/m.blah
ANS_FILENAME='my track.mp3'
and here is how playd works
Code:
$ playd get filename | cat
ANS_filename=my track.mp3
Terminated
(no quoting, mangled case in ANS_FILENAME, "Terminated" in stdout)

I was thinking about
Code:
eval $(playd get filename)
echo Current track is $ANS_FILENAME[/cmd]in zsh's [file]precmd[/file] hook or [file]~/.screenrc[/file].
 
eye said:
Hmm, new get functions are a bit buggy
Code:
$ cat /tmp/m.blah
ANS_FILENAME='my track.mp3'
and here is how playd works
Code:
$ playd get filename | cat
ANS_filename=my track.mp3
Terminated
(no quoting, mangled case in ANS_FILENAME, "Terminated" in stdout)

I was thinking about
Code:
eval $(playd get filename)
echo Current track is $ANS_FILENAME[/cmd]in zsh's [file]precmd[/file] hook or [file]~/.screenrc[/file].[/quote]

Just fixed (and pushed) by adding [b]2> /dev/null[/b] to cat :D

I preffer [b]2> /dev/null[/b] over [b]2>-[/b], because I think it's easier to understand :D (more people are familiar with this)

DID you subscribe to rss or atom feeds of commits?
 
killasmurf86 said:
Just fixed (and pushed)
It has more assumption about mplayer's config -nomsgmodule and -nomsgcolor.
killasmurf86 said:
DID you subscribe to rss or atom feeds of commits?
Nah, only to crontab
Code:
$
You have new mail.
$ mail
Mail version 8.1 6/6/93.  Type ? for help.
"/var/mail/luser": 1 message 1 new
>N  1 luser@earth.local    Sat Nov 20 16:05  23/854   "Cron <luser@earth> slurp hg /a/playd.sh"
&
Message 1:
From luser@earth.local Sat Nov 20 16:05:07 2010
Date: Sat, 20 Nov 2010 13:05:02 +0000 (UTC)
From: luser@earth.local (Cron Daemon)
To: luser@earth.local
Subject: Cron <luser@earth> slurp hg /a/playd.sh
X-Cron-Env: <PATH=/home/luser/.bin:/bin:/usr/bin:/usr/local/bin>
X-Cron-Env: <SHELL=/bin/sh>
X-Cron-Env: <HOME=/home/luser>
X-Cron-Env: <LOGNAME=luser>
X-Cron-Env: <USER=luser>

53:ca5190b1e0ba
54:f17d1537ea9f
55:2482978da388
56:ac1044126e82
57:565e24ce0642
58:13105a41801e
59:e46067f6f348
60:b8fdeaf36f35

&
 
The links on the first post are broken. I would be interested in seeing your shell script. Is there another link?
 
You haven't looked at that manpage when committing 74:8c15e48779dd. There are more - $, ^. Perhaps, you should consider filtering output by fgrep -x before doing awk rather than haphazardly escaping RE.
 
I'm lazy, like everyone else :)
I thought I had $ ^ espaced already... :D

No, playd_current_file_escaped is used to inject filename in awk script
 
I'm curious why do you need to know position in order to switch to previous track in playlist? What's wrong with $ playd cmd 'pt_step -1'?
 
killasmurf86 said:
eye said:
one more wish for your TODO: make playd remember position in playlist across daemon restarts (or reboots)
I told you I can't..... I don't know at any time what mplayer is playing
It should be possible now. One way is to keep log of played files
Code:
$ mplayer -playlist ~/foo.plst -nomsgmodule -msglevel all=-1 -msglevel identify=4 | fgrep -i file
ID_FILENAME=/path/to/music-dir/foo.mp3
ID_FILENAME=/path/to/music-dir/bar.mp3
ID_FILENAME=/path/to/music-dir/foo.mp3
And when mplayer is not alive do load playlist and jump (pt_step) to the last file in the log.

This feature is useful for lazy people putting their entire music library into playlist and shuffling it. Keeping current position across reboots would make distribution of played tracks more even because it ensures that every track is played at least once. Currently some tracks play more often than others either by repeating playlist from the start or increasing the chance to hit already played files with random command.
 
Top