3

问题:我找不到任何方法来可靠地获取 MPlayer 播放列表中的当前播放文件。

这是我已经走了多远。这个工作的 ash 脚本监视一个带有当前播放列表路径的文本文件。当我更新文件时,脚本会关闭 MPlayer 的旧实例并使用新播放列表打开一个新实例:

# 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

我最初的计划只是使用“-identify”标志并解析日志文件。这实际上非常有效,直到我需要截断日志文件以防止它变得太大。一旦我的截断脚本运行,MPlayer 就会停止写入日志文件:

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

我已经搜索和搜索,但无法找到任何其他方式来获取当前正在播放的文件。

我尝试将输出通过管道传输到另一个命名管道,然后对其进行监视,但只能工作几秒钟,然后 MPlayer 完全冻结。

我也尝试过使用 bash(而不是 ash)并将输出传递到如下函数,但遇到了同样的冻结问题:

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 &

我怀疑我在这里遗漏了一些非常明显的东西,所以任何帮助、想法、正确方向的观点都将不胜感激。

饲料

4

5 回答 5

2

好吧,那我也发一下我的。

试试这个(假设只有一个实例在运行,比如在 fodder 的机器上):

basename "$(readlink /proc/$(pidof mplayer)/fd/* | grep -v '\(/dev/\|pipe:\|socket:\)')"

这可能是更安全的方法,因为文件描述符在所有系统上的顺序可能并不总是相同。但是,这可以缩短,但有一点风险:

basename "$(readlink /proc/$(pidof mplayer)/fd/*)" | head -1

你可能也想安装这个:http: //mplayer-tools.sourceforge.net/

于 2014-09-08T22:17:30.133 回答
1

好吧,我放弃了从 MPlayer 本身获取曲目。

我的“解决方案”可能太老套了,但可以满足我的需要,因为我知道我的机器只会运行一个 MPlayer 实例:

lsof -p $(pidof mplayer) | grep -o "/path/to/my/assets/.*"

如果有人有更好的选择,我当然仍然有兴趣以正确的方式做到这一点,我只是无法让任何方法发挥作用。

饲料

于 2013-02-20T20:51:31.603 回答
1

您可以使用该run命令。

把这个放在~/.mplayer/input.conf

DEL run "echo ${filename} ${stream_pos} >> /home/knarf/out"

现在,如果您在播放文件时按下删除键,它将执行您所期望的操作,即将播放的当前文件和流中的位置附加到~/out文件中。您可以替换echo为您的程序。

有关更多信息,请参阅slave mod 文档(Ctrl-F somevar)。

于 2014-09-05T12:46:03.997 回答
0

关于从 MPlayer 获取属性

我使用了一个非优雅的解决方案,但它对我有用。

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

等等..

它在另一个过程中,这就是为什么我使用文件来带来属性

'stdbuf' 是为了不错过任何东西

于 2015-06-03T23:25:07.493 回答
0

我开始组建一个 bash 库来处理这样的任务。基本上,您可以通过将 mplayer 输出转储到文件来完成此操作。然后,您将该转储 grep 为“正在播放”,并使用尾部获取最后一个结果。这应该为您提供当前正在播放或上次完成播放的文件的名称。

看看我的 bash 代码。您需要根据需要修改该playMediaFile功能,但该getMediaFileName功能应该完全按照您的要求进行。你会在我的 github上找到代码。

于 2018-11-19T08:12:09.963 回答