折腾mplayer

2010-03-22 11:42

这篇文章记录了我用mplayer来播放电脑里的音乐的一点心得.

需求: 能够无序不停地播放电脑里的音乐. 能够通过电脑上的多媒体控制键来控制mplayer的播放. 要实现这个需求, amaroK可能会是一个完全不需要折腾的选择,可惜KDE4里的amaroK比较笨重, 而且界面不符合我的审美观. 顺道缅怀下amaroK 1.x的版本...

播放列表生成及基本播放

这个部分是在上个星期的业余时间内完成的, 一共花了半个小时.

首先是生成播放列表, 这个不算难, 我的音乐全部放在"/mnt/archive/我的音乐/"下面, 用tree命令遍历这个文件夹就可以了:

tree -fi /mnt/archive/我的音乐 -P "*.mp3|*.m4a" -F | grep -v /$ | sed "s/*$//g" > /home/xiaket/.xiaket/var/playlist

这样, 生成的播放列表文件是"/home/xiaket/.xiaket/var/playlist".

接下来只需要播放这个播放列表就可以了, 我写了一个简单的脚本, 名为song, 来完成这个工作. (免得每次输一个很长的命令嘛~):

#!/bin/bash   

mplayer -shuffle -playlist /home/xiaket/.xiaket/var/playlist > /dev/null 2>&1 &

这个命令行做了三件事情: 无序循环播放, 从播放列表播放, 丢弃所有输出.

这样切歌比较讨厌, 于是我又写了另一个脚本, 名为next, 每次切歌时只需要在命令行下输入next即可.

#!/bin/bash

# kill existing process
kill -9 `ps aux | grep /home/xiaket/.xiaket/var/playlist | grep -v grep | awk '{print $2}'`

song

注意, 上面的脚本只是一个自己用的毛坯.

控制mplayer

今天早上听歌时, 连切了几首歌, 都让人不爽, 于是打算折腾下用键盘上的多媒体控制键来完成控制mplayer的工作.

首先是man了下mplayer长长的文档, 发现有个"-slave"的参数, 又Google到这篇文章, 基本还是很简单的, 做一个有名管道出来就能让mplayer接受控制字符了:

# make a named pipe
mkfifo /home/xiaket/.xiaket/var/mplayer.fifo
# start mplayer in background
mplayer -slave -shuffle -playlist /home/xiaket/.xiaket/var/playlist -input file=/home/xiaket/.xiaket/var/mplayer.pipe > /dev/null 2>&1 &
# now open a NEW CONSOLE and type some command to the named pipe
echo "pause" > /home/xiaket/.xiaket/var/mplayer.pipe
# mplayer would then stop playing
echo "pause" > /home/xiaket/.xiaket/var/mplayer.pipe
# mplayer would now resume

做完这一步, 我们接下来只需要设定KDE让我的键盘上的媒体播放键能够传递适当的信号给mplayer就可以了.

媒体播放键的设置

首先用"xmodmap -pke"查看下目前键位的对应关系:

# output of xmodmap -pke
... (some text omitted)
keycode 171 = XF86AudioNext NoSymbol XF86AudioNext
keycode 172 = XF86AudioPlay XF86AudioPause XF86AudioPlay XF86AudioPause
keycode 173 = XF86AudioPrev NoSymbol XF86AudioPrev
keycode 174 = XF86AudioStop XF86Eject XF86AudioStop XF86Eject
... (more text omitted)

还不是完全放心, 用xev确认了一下, 都没问题.

既然媒体播放键都是正常工作的, 我们只需要将mplayer对应的控制命令对应到这些键就可以了. mplayer详细的控制命令可以用"mplayer -input cmdlist"来看到, 和我有关的有下面这些:

# output of mplayer -input cmdlist
pausing_keep_force pt_step 1
pause
pausing_keep_force pt_step -1
stop

讨厌的是由于mplayer对无序播放的处理算法不对上一首播放的歌曲进行记录, 因此上一首歌的按键没用... 不过无所谓了, 我能接受这一点.

接下来只需要将媒体播放键映射到这些控制字符串即可, 这在KDE4下面可以通过修改KMenu, 添加一个新命令, 并对其指定快捷键来实现. 首先我们创建一个控制脚本:

#!/bin/bash

#ENVS
PLAYLIST=/home/xiaket/.xiaket/var/playlist
PIPE=/home/xiaket/.xiaket/var/mplayer.pipe

#check if mplayer is running
mplayer=`ps aux | grep -v grep | grep -c $PLAYLIST`

if [ $mplayer == '1' ]; then
#mplayer is running, control it
echo "pause" > $PIPE
else
#no mplayer running, start one
mplayer -slave -shuffle -playlist $PLAYLIST -input file=$PIPE > /dev/null 2>&1 &
fi

我将这个脚本命名为mplayer.pause, 加上执行权限, 并将其放到了PATH下面. 然后在KMenu-多媒体那一类里面新建了一个项目, 名字还是mplayer.pause, 命令指到前面建立的脚本, 指定快捷键时按下键盘上方的多媒体键就可以了. 剩下的两个脚本依次类推.