LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   bash how to send keystrokes via fifo to mpg123 in background (http://www.linuxquestions.org/questions/programming-9/bash-how-to-send-keystrokes-via-fifo-to-mpg123-in-background-891899/)

porphyry5 07-15-2011 11:32 AM

bash how to send keystrokes via fifo to mpg123 in background
 
The script below runs mpg123 in background and accepts user input from the keyboard, some of which it sends on to mpg123 through the fifo pipem. The pipe seems properly formed and contains the keystroke input specific to mpg123. But mpg123 never responds to the piped input. Could someone kindly explain why?
Code:

#!/bin/bash

# Start music playing from rand.m3u
cd /home/g/Documents
echo s show tune name and weight, w to change tune weight
echo q quit, space pause/unpause, f next, d previous, b restart tune
mpg123 --fifo /home/g/Documents/pipem -b 2048 --smooth -C -@ rand.m3u > mpg123.dat 2>&1 &
if [ ! -e "pipem" ]; then mkfifo pipem; fi
sleep 1
# show current tune and its weight, or communicate with mpg123
while read line; do
        if [ "$line" == "w" ]; then
                rxvt -title ChangeTuneWeight -e bash /home/g/Scripts/chwt.sh &
                continue
        fi
        if [ "$line" != "s" ]; then
                cat <<< "$line" > pipem                # send keystroke to mpg123
                continue
        fi
        cur=$(awk '{ if ($1=="Playing") print $7 }' mpg123.dat|tail -n 1)
        wt=($(grep $cur 3.n3u |awk '{ print $1 + 0 }'))
        echo " "$wt"  "$cur        # show weight and name of tune playing
done

Following is start of mpg123 output sent to mpg123.dat
Code:

High Performance MPEG 1.0/2.0/2.5 Audio Player for Layers 1, 2 and 3
        version 1.12.1; written and copyright by Michael Hipp and others
        free software (LGPL/GPL) without any warranty but with best wishes
Can't get terminal attributes

Directory: /home/g/Music/

Terminal control enabled, press 'h' for listing of keys and functions.

Playing MPEG stream 1 of 50: WoodyGuthrie-GoodOldHobo.mp3 ...
MPEG 1.0 layer III, VBR, 44100 Hz stereo

[2:35] Decoding of WoodyGuthrie-GoodOldHobo.mp3 finished.


Terminal control enabled, press 'h' for listing of keys and functions.

Playing MPEG stream 2 of 50: PeterPaulAndMary-IfYouMissTheTrainImOn.mp3 ...
MPEG 1.0 layer III, VBR, 44100 Hz stereo

[2:46] Decoding of PeterPaulAndMary-IfYouMissTheTrainImOn.mp3 finished.


SigTerm 07-16-2011 06:54 AM

Quote:

Originally Posted by porphyry5 (Post 4415801)
The script below runs mpg123 in background and accepts user input from the keyboard, some of which it sends on to mpg123 through the fifo pipem. The pipe seems properly formed and contains the keystroke input specific to mpg123. But mpg123 never responds to the piped input. Could someone kindly explain why?
Code:

#!/bin/bash
...
mpg123 --fifo /home/g/Documents/pipem -b 2048 --smooth -C -@ rand.m3u > mpg123.dat 2>&1 &
...
if [ ! -e "pipem" ]; then mkfifo pipem; fi
...
                cat <<< "$line" > pipem                # send keystroke to mpg123

Following is start of mpg123 output sent to mpg123.dat[CODE]

IMO, you're writing commands into wrong file. "/home/g/Documents/pipem" is one file and "pipem" is another. If I remember correctly "mkfifo pipem" will create pipe within current dir, and "/home/g/Documents/pipem" is different pipe located within different directory. You can query location of current dir with pwd command.

porphyry5 07-16-2011 08:53 AM

Quote:

Originally Posted by SigTerm (Post 4416428)
IMO, you're writing commands into wrong file. "/home/g/Documents/pipem" is one file and "pipem" is another. If I remember correctly "mkfifo pipem" will create pipe within current dir, and "/home/g/Documents/pipem" is different pipe located within different directory. You can query location of current dir with pwd command.

The first commands of the script are
Code:

cd /home/g/Documents
echo s show tune name and weight, w to change tune weight
echo q quit, space pause/unpause, f next, d previous, b restart tune
mpg123 --fifo /home/g/Documents/pipem -b 2048 --smooth -C -@ rand.m3u > mpg123.dat 2>&1 &
if [ ! -e "pipem" ]; then mkfifo pipem; fi

so "pipem" and "/home/g/Documents/pipem" refer to the same file. It is the only pipem on the system
Code:

g  locate pipem
/home/g/Documents/pipem
g


ntubski 07-16-2011 11:38 AM

After a bit experimentation, I found that you need to pass -R or --remote in addition to --fifo for it to work. And mpg123 will create the fifo, so you don't need to do that in the script.

porphyry5 07-16-2011 02:41 PM

Quote:

Originally Posted by ntubski (Post 4416593)
After a bit experimentation, I found that you need to pass -R or --remote in addition to --fifo for it to work. And mpg123 will create the fifo, so you don't need to do that in the script.

Many thanks. I did originally write it expecting mpg123 to create the fifo, but when it didn't, figured I'd misread the manual and that my script had to create the pipe for it, but no luck that way either. Thank you again.

Unfortunately, it seems to work that way only if one feeds it individual filenames, give it a playlist and it just hangs.

SigTerm 07-16-2011 04:05 PM

Quote:

Originally Posted by porphyry5 (Post 4416756)
Unfortunately, it seems to work that way only if one feeds it individual filenames, give it a playlist and it just hangs.

mpg123 is opensource, so you can modify program behavior to suit your needs (requires programming experience). Or you could hire a freelancer to do that for you (requires money).

porphyry5 07-17-2011 01:02 PM

Well, if you can't do it one way, there's usually a workaround. The script below does everything I wanted, except be able to repeat the previous tune.
Code:

#!/bin/bash
 
# Play music from rand.m3u with mpg123
cd /home/g/Documents
echo Mod4+w to change tune weight, Ctrl+c twice to quit
echo space pause/unpause, f next tune, b restart tune
tunes=($(cat rand.m3u))
len=${#tunes[@]}
# play each tune individually from the playlist
for (( i=0; i<=$len; i++ )); do
        wt=($(grep ${tunes[$i]} 3.n3u |awk '{ print $1 + 0 }'))
        echo -e "\033]2; $wt  ${tunes[$i]} \007"        # tune weight & name into xterm title bar
        mpg123 -b 2048 -C ${tunes[$i]} > mpg123.dat 2>&1
        sleep 1
# wait until mpg123 closes before continuing loop to start next tune
        while [ "$list" =~ mpg123 ] 2>/dev/null; do list=$(ps aux|grep mpg123); done
done



All times are GMT -5. The time now is 09:10 AM.