Get the current playback file in MPlayer slave mode
Problem: I can't find a way to reliably get the current playback file in the MPlayer playlist.
That's how far I got. This work ash script controls a text file with the path to the current playlist. When I update the file, the script closes the old MPlayer instance and opens a new one with a new playlist:
# POLL PLAYLIST FILE FOR CHANGES
CURRENTPLAYLISTPATH=/home/tc/currentplaylist
INFIFO=/tmp/mplayer-in
CURRENTPLAYLIST="NEVERMATCHAPLAYLIST"
FIRSTRUN=1
while [ 1 ];
do
# CHECK FOR NEW PLAYLIST
NEWPLAYLIST=$(head -n 1 $CURRENTPLAYLISTPATH)
if [[ "$NEWPLAYLIST" != "$CURRENTPLAYLIST" ]]; then
if [ "$FIRSTRUN" == 0 ]; then
echo "quit" > "$INFIFO"
fi
# CREATE NAMED PIPE, IF NEEDED
trap "rm -f $INFIFO" EXIT
if [ ! -p $INFIFO ]; then
mkfifo $INFIFO
fi
# START MPLAYER
mplayer -fixed-vo -nolirc -vc ffmpeg12vdpau,ffh264vdpau, -playlist $NEWPLAYLIST -loop 0 -geometry 1696x954 -slave -idle -input file=$INFIFO -quiet -msglevel all=0 -identify | tee -a /home/tc/mplayer.log &
CURRENTPLAYLIST=$NEWPLAYLIST
FIRSTRUN=0
fi
sleep 5;
done
My original plan was to use the "-identify" flag and parse the log file. This actually works really well, as long as I don't need to truncate the log file so it doesn't get too big. As soon as my truncated script is running, MPlayer stops writing to the log file:
FILENAME=/home/tc/mplayer.log
MAXCOUNT=100
if [ -f "$FILENAME" ]; then
LINECOUNT=`wc -l "$FILENAME" | awk '{print $1}'`
if [ "$LINECOUNT" -gt "$MAXCOUNT" ]; then
REMOVECOUNT=`expr $LINECOUNT - $MAXCOUNT`
sed -i 1,"$REMOVECOUNT"d "$FILENAME"
fi
fi
I have searched and searched but couldn't find any other way to get the current playback file.
I tried to output to another named pipe and then monitor it, but only works for a few seconds, then MPlayer freezes completely.
I also tried using bash (instead of ash) and dump the output to a function like below, but I get the same freeze problem:
function parseOutput()
{
while read LINE
do
echo "get_file_name" > /tmp/mplayer-in
if [[ "$LINE" == *ANS_FILENAME* ]]
then
echo ${LINE##ANS_FILENAME=} > "$CURRENTFILEPATH"
fi
sleep 1
done
}
# START MPLAYER
mplayer -fixed-vo -nolirc -vc ffmpeg12vdpau,ffh264vdpau, -playlist $NEWPLAYLIST -loop 0 -geometry 1696x954 -slave -idle -input file=/tmp/mplayer-in -quiet | parseOutput &
I suspect I am missing something very obvious here, so any help, ideas, points in the right direction would be greatly appreciated.
stern
source to share
Well, I gave up on getting the track from MPlayer itself.
My "solution" is probably too hacky, but it works for my needs, since I know that my machine will only have one instance of MPlayer:
lsof -p $(pidof mplayer) | grep -o "/path/to/my/assets/.*"
If anyone has a better option, I'm of course still interested in getting it right, I just couldn't get any of these methods to work.
stern
source to share
Ok then I'll post too.
Try this try (assuming only one instance is running, e.g. on a stern machine):
basename "$(readlink /proc/$(pidof mplayer)/fd/* | grep -v '\(/dev/\|pipe:\|socket:\)')"
This is probably the safer way, as file descriptors may not always be in the same order on all systems. However, this can be shortened with little risk:
basename "$(readlink /proc/$(pidof mplayer)/fd/*)" | head -1
You might want to install this too: http://mplayer-tools.sourceforge.net/
source to share
You can use the command run
.
Put this in ~/.mplayer/input.conf
:
DEL run "echo ${filename} ${stream_pos} >> /home/knarf/out"
Now, if you hit the delete key while playing a file, it will do what you expect, such as adding the current file and stream position to the file ~/out
. You can replace echo
with your own program.
See the slave mod docs (Ctrl-F somevar) for more information .
source to share
About getting properties from MPlayer
I used a non-elementary solution, but it works for me.
stdbuf -oL mplayer --slave --input=file=$FIFO awesome_awesome.mp3 |
{
while IFS= read -r line
do
if [[ "${line}" == ANS_* ]]; then
echo "${line#*=}" > ${line%=*} # echo property_value > property_name
fi
done
} &
mplayer_pid=&!
read filename < ./ANS_FILENAME
read timeLength < ./ANS_LENGTH
echo ($timeLength) $filename
etc.
This is in a different process, so I used files to give properties
'stdbuf' in order not to miss anything
source to share