Reputation: 6651
I'm trying write simple notify app in bash. I want to read output from mplayer, parse it and display through notify-send.
I can get desired info from mplayer using this:
mplayer <url> | grep ICY
and then parse in using sed.
I create named pipe, tell mplayer to write it and then I'm reading from it. Unfortunately, it doesn't work. Here's my script:
$fifo=~/.rp/fifo
mkfifo $fifo
mplayer <url> 2>/dev/null | grep ICY 1> $fifo &
while read line < $fifo; do
echo $line
done
wait
Program keeps waiting to input from $fifo. I tried following in other terminal, while this script is running:
Run
echo "Test" > .rp/fifo
Terminal with running script shows "Test"
Run
echo "ICY" | grep ICY > .rp/fifo
also works.
Run
mplayer <url> | grep ICY > .rp/fifo
and it doesn't work.
Is I said above, the combination of mplayer | grep works fine. grep > $fifo works fine. I don't understand why mplayer | grep > $fifo doesn't work.
Upvotes: 4
Views: 7544
Reputation: 141
I start mplayer in slave mode, using FIFO file.
mkfifo /tmp/mpfifo
mplayer -slave -input file=/tmp/mpfifo video.mp4
I am able to control the video player from another terminal.
echo "pause" >> /tmp/mpfifo
echo "volume 50" > /tmp/mpfifo
I want to get value (for example current position of playing video). So I tried:
echo "get_time_pos" > /tmp/mpfifo
But no value returned. I searched for hours, but no success. Then I thought to redirect mplayer output to a file:
mplayer -slave -input file=/tmp/mpfifo video.mp4 > /tmp/mpout.txt
After that when like following commands executed:
echo "get_time_pos" > /tmp/mpfifo
echo "get_property length" > /tmp/mpfifo
The outputs in /tmp/mpout.txt was like:
.......
.......
ANS_TIME_POSITION=113.6
ANS_length=2534.602031
If the result of each command would return to the command line would be very nice. Even it may need some works, the output file can be parsed, though.
Upvotes: 2
Reputation: 70967
You could do unbuffered grep with:
$ mplayer ... 2>&1 | grep --line-buffered "ICY"
or better:
$ mplayer ... 2>&1 | sed -une 's/^.*ICY[^:]*: //p'
or even, why not (sed is very nice for grep and formatting),
this will grep ICY
lines and even split line containing -
in a first field of 30 chars length separed by a :
from a second field:
$ mplayer ... 2>&1 |
sed -une "
/ICY/{
s/^.*ICY[^:]*:.*'\([^']*\)';/\1/;
s/^\(.*\) - /\1 - /;
s/^\(.\{30\}\) *- /\1: /;
p;
}"
could give something like:
Artist name : Song title
Other artist : Other song
Unsplited line
Artist : Title
Upvotes: 4
Reputation: 1088
I suspect you might be experiencing the C library's fully buffered mode for streams. You don't say that you're running the GNU userspace, but if you are, you can look into stdbuf(1)
to modify the buffering regime.
You might try first running just grep
as a child of stdbuf(1)
, like this:
mplayer <url> | stdbuf -o L grep ICY > .rp/fifo
If that doesn't work, moar is bettar!
stdbuf -o 0 mplayer <url> | stdbuf -o L grep ICY > .rp/fifo
And if that still doesn't work, then it's possible that mplayer
isn't writing to stdout, but directly to /dev/tty
. In which case, you will need to read up on expect(1)
.
Upvotes: 5