bash 将mplayer的输出写入fifo并读取

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13111633/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 03:39:44  来源:igfitidea点击:

Write mplayer's output to fifo and read it

bashshellpipe

提问by Tomá? Ehrlich

I'm trying write simple notify app in bash. I want to read output from mplayer, parse it and display through notify-send.

我正在尝试在 bash 中编写简单的通知应用程序。我想从 mplayer 读取输出,解析它并通过通知发送显示。

I can get desired info from mplayer using this:

我可以使用以下方法从 mplayer 获取所需信息:

mplayer <url> | grep ICY

and then parse in using sed.

然后使用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:

我创建了命名管道,告诉 mplayer 编写它,然后我正在读取它。不幸的是,它不起作用。这是我的脚本:

$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:

程序一直在等待来自 $fifo 的输入。我尝试在其他终端中执行以下操作,而此脚本正在运行:

  1. Run

    echo "Test" > .rp/fifo
    

    Terminal with running script shows "Test"

  2. Run

    echo "ICY" | grep ICY > .rp/fifo
    

    also works.

  3. Run

    mplayer <url> | grep ICY > .rp/fifo
    

    and it doesn'twork.

  1. echo "Test" > .rp/fifo
    

    带有运行脚本的终端显示“测试”

  2. echo "ICY" | grep ICY > .rp/fifo
    

    也有效。

  3. mplayer <url> | grep ICY > .rp/fifo
    

    不起作用

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.

是我上面说的mplayer的组合吗?grep 工作正常。grep > $fifo 工作正常。我不明白为什么 mplayer | grep > $fifo 不起作用。

回答by Bernd Jendrissek

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.

我怀疑您可能正在体验 C 库的全缓冲流模式。您并不是说您正在运行 GNU 用户空间,但是如果您是,您可以考虑stdbuf(1)修改缓冲机制。

You might try first running just grepas a child of stdbuf(1), like this:

您可以尝试grep像 的孩子stdbuf(1)一样首先运行,如下所示:

mplayer <url> | stdbuf -o L grep ICY > .rp/fifo

If that doesn't work, moar is bettar!

如果那不起作用,moar 就是赌注!

stdbuf -o 0 mplayer <url> | stdbuf -o L grep ICY > .rp/fifo

And if that still doesn't work, then it's possible that mplayerisn't writing to stdout, but directly to /dev/tty. In which case, you will need to read up on expect(1).

如果这仍然不起作用,那么可能mplayer不是写入 stdout,而是直接写入/dev/tty. 在这种情况下,您需要阅读expect(1).

回答by F. Hauri

You could do unbuffered grep with:

您可以使用以下命令执行无缓冲 grep:

$ 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 ICYlines and even split line containing -in a first field of 30 chars length separed by a :from a second field:

甚至,为什么不呢(sed 对于 grep 和格式化非常好),这将 grepICY行甚至拆分包含-在 30 个字符长度的第一个字段中的行,该字段由 a:与第二个字段分隔:

$ mplayer ...  2>&1 |
    sed -une "
        /ICY/{
            s/^.*ICY[^:]*:.*'\([^']*\)';//;
            s/^\(.*\) - /                              - /;
            s/^\(.\{30\}\) *- /: /;
            p;
    }"

could give something like:

可以给出类似的东西:

Artist name                  : Song title
Other artist                 : Other song
Unsplited line
Artist                       : Title

回答by podcast

I start mplayer in slave mode, using FIFO file.

我使用 FIFO 文件以从属模式启动 mplayer。

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 输出重定向到一个文件:

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:

/tmp/mpout.txt 中的输出如下:

.......
.......
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.

如果每个命令的结果都能返回到命令行就好了。即使它可能需要一些工作,但可以解析输出文件。