3

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

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

mplayer <url> | grep ICY

然后使用 sed 解析。

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

$fifo=~/.rp/fifo
mkfifo $fifo

mplayer <url> 2>/dev/null | grep ICY 1> $fifo &

while read line < $fifo; do
    echo $line
done

wait

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

  1. echo "Test" > .rp/fifo
    

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

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

    也有效。

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

    不起作用

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

4

3 回答 3

5

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

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

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

如果这不起作用,moar is bettar!

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

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

于 2012-10-28T18:35:19.783 回答
4

您可以使用以下方法进行无缓冲 grep:

$ mplayer ...  2>&1 | grep --line-buffered "ICY"

或更好:

$ mplayer ...  2>&1 | sed -une 's/^.*ICY[^:]*: //p'

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

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

可以给出类似的东西:

Artist name                  : Song title
Other artist                 : Other song
Unsplited line
Artist                       : Title
于 2012-10-29T00:27:15.403 回答
1

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

mkfifo /tmp/mpfifo

mplayer -slave -input file=/tmp/mpfifo video.mp4

我可以从另一个终端控制视频播放器。

echo "pause" >> /tmp/mpfifo
echo "volume 50" > /tmp/mpfifo

我想获得价值(例如播放视频的当前位置)。所以我尝试了:

echo "get_time_pos" > /tmp/mpfifo

但是没有返回值。我搜索了几个小时,但没有成功。然后我想将 mplayer 输出重定向到一个文件:

mplayer -slave -input file=/tmp/mpfifo video.mp4 > /tmp/mpout.txt

之后,当执行以下命令时:

echo "get_time_pos" > /tmp/mpfifo
echo "get_property length" > /tmp/mpfifo

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

.......
.......
ANS_TIME_POSITION=113.6
ANS_length=2534.602031

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

于 2015-05-11T08:31:32.013 回答