---------------------7.23日更新-----------------
没有作什么变化,按照ee的莫名其妙的提示用gzexe压了一个玩玩。
---------------------6.20日更新-----------------
已经更改代码:DAlpha.Roc 写了:一些在非中文语言设置环境下使用的问题,语言环境为英语:
1。系统在转换gb变量时,会自动在字符串结尾加上 %0a% ,不清楚原因,只好添加了一段 sed 's/%0a%//' 做替换。
2。gb 转换时使用 gb2312 似乎不能转换繁体字标题的歌曲,转为使用 gb18030,似乎能解决此问题。
---------------------6.14日更新-----------------
修正了当歌词里面有*时会把当前目录的所有文件名显示出来的问题
改进了获得歌曲题目的代码(这有赖于solcomo的mlrc脚本的启发)
现在任何时候启动脚本均可显示歌词了
---------------------6.1日更新-------------------
改进了搜索算法,现在显示歌词完全不产生临时文件了。
精简了代码,效率明显提高
------------------------------------------------------
1,信息直接从dbus-monitor中读取,故而理论上其他的播放器也可以支持,不过我只有Rythmbox可供做试验,如果需要的话可以
代码: 全选
dbus-monitor
2,因为mpd/mpc不是用dbus-monitor传递信息,故而不支持,用mpd/mpc的筒子可以另外去下另一个solcomo写的脚本:viewtopic.php?t=124574
3,不要sh ./lrcdis这样运行,先下载附件》解压》chmod +x ./lrcdis》./lrcdis
4,默认采用gnome-osd显示,需要安装之,直接
代码: 全选
sudo apt-get install gnome-osd
5,默认lrc文件下载到~/.lyrics文件夹,可以自己改。歌词是从百度下载的。
6,可能有很多bug,个人测试有限,欢迎大家踊跃当小白鼠:D
代码: 全选
#!/bin/bash
#******************
# coded by xiooli
#******************
LRCDIR=~/.lyrics #lrc文件保存文件夹,可以自己改
[ ! -d "$LRCDIR" ] && mkdir "$LRCDIR"
#下载歌词的函数
DOWNLRC(){
NM="$1"
#判断当前locale,utf-8的locale将要使用编码转换
[ `locale |grep "LANG=.*UTF-8"` ] && lang=1
#将歌曲名字转换为urlencode,utf-8的locale必须先转换为gb的编码
if [ "$lang" ];then
#od的输出为每行16组,如果太长则会截断成两行,故而应该删除可能出现的换行符。
gb=`echo "$NM" | iconv -c -f utf-8 -t gbk | od -t x1 -A n |tr "\n" " " |tr " " % |sed 's/%%/%/g;s/%0a%$//'`
else
gb=`echo "$NM" | od -t x1 -A n |tr "\n" " " |tr " " % |sed 's/%%/%/g;s/%0a%$//'`
fi
#从百度搜索里面找出当前歌曲的歌词下载页
wget "http://www.baidu.com/s?wd="$gb"+filetype%3Alrc&cl=3" -O /dev/shm/lrc_file -T 10 -q
LINK=`cat /dev/shm/lrc_file |grep "LRC" |awk -F"href="" '{print $2}' |awk -F""" '{print $1}'`
while [ "$LINK" ] && [ ! -s "$LRCDIR/$NM.lrc" ];do
if [ "$lang" ];then
wget "$LINK" -O /dev/shm/lrctmp -T 5 -t 2 -q
[ -s /dev/shm/lrctmp ] && iconv -f gbk -t utf-8 -c /dev/shm/lrctmp -o "$LRCDIR/$NM.lrc"
else
wget "$LINK" -O "$LRCDIR/$NM.lrc" -T 5 -t 2 -q
fi
[ -s "$LRCDIR/$NM.lrc" ] && sed -i'' "s/\r/\n/g" "$LRCDIR/$NM.lrc" #去掉dos字符
> /dev/shm/lrctmp
done
}
#获取当前播放的歌曲标题
GET_TITLE() {
TITLE=`dbus-send --session --print-reply --dest=org.gnome.Rhythmbox /org/gnome/Rhythmbox/Player org.gnome.Rhythmbox.Player.getPlayingUri \
|grep "string" |perl -p -e 's/%(..)/pack("c", hex($1))/eg' |awk -F"." '{ i=1;while(i<NF) {printf $i".";i++}}' \
|sed 's/.*\///g;s/\.$//'` && title_changed=1
}
#分割lrc文件的函数(仅取出时间信息并转换成秒)
LRC_SPLIT() {
tm_arr=`cat "$1" |grep "\[[0-9]" |while read LINE
do
echo $LINE |sed "s/\[0/\[/g;s/\]\[/ /g;s/\[//g;s/\][^\[].*//g;s/:0/:/g;s/\]//g"
done`
for i in ${tm_arr[@]};do
min=`echo $i |sed 's/:.*//'`
sec=`echo $i |sed 's/\..*//;s/^.*://'`
echo $(($min*60+$sec))
done
}
#根据播放时间找出lrc中对应的时间(lrc时间中小于播放时间的最大时间)
FIND_LRC_TIME() {
if [ "${TIME_LIST[0]}" ];then
pltm="$1"
let tmp=-1
for lrctm in ${TIME_LIST[@]};do
if [ "$tmp" -lt "$pltm" ] && [ "$tmp" -lt "$lrctm" ] && [ "$pltm" -ge "$lrctm" ];then
let tmp="$lrctm"
fi
done
fi
[ "$tmp" ] && printf '%.2d:%.2d' $(($tmp/60)) $(($tmp%60))
}
#osd模式显示(未安装gnome-osd则终端输出)
let n=1
OSD_SHOW() {
if [ `which gnome-osd-client` ];then
gnome-osd-client -f "<message id='lrcdis' hide_timeout='10000'>`echo "$*"`</message>"
else
[ "$n" -eq 1 ] && clear && echo -e "\033[;32m******"$TITLE"****** \033[0m " && let n=5
echo "$*" && let n="$n"-1
fi
}
#显示歌词函数
DISPLAY() {
if [ "$1" ] && [ "$2" ];then
lrc_line=`printf "$1" |awk -F"$2" '{print $2}' |sed "s/@.*//g;s/^.*\]//g;s/*/\\\*/g"`
if [ "$lrc_line" ] && [ "$line" != "$lrc_line" ];then
OSD_SHOW "$lrc_line"
line="$lrc_line"
fi
fi
}
MAIN() {
GET_TITLE
dbus-monitor --session |while read a;do
[ "$a" = "byte 0" ] && killall dbus-monitor && break #dbus会在歌曲变化时会输出一堆(上千行)byte 0,此时先跳出循环,歇会儿。
[ "`echo "$a" |grep "^uint"`" ] || continue
if [ "$a" = "uint32 0" ];then
LRC=""
TIME_LIST=""
elif [ "$a" = "uint32 1" ];then
go_on=1
else
go_on=2
fi
#找到歌曲题目
if [ "$go_on" = 1 ];then
[ "$title" != "$TITLE" ] && title="$TITLE" && GET_TITLE
go_on=""
fi
if [ "$title_changed" ];then
[ `which gnome-osd-client` ] && OSD_SHOW "******"$TITLE"******"
notfound="no" && TIME_LIST="" && TIME="0" && sleep 1
[ -s "$LRCDIR/$TITLE.lrc" ] && TIME_LIST=($(LRC_SPLIT "$LRCDIR/$TITLE.lrc")) \
&& LRC=$(cat "$LRCDIR/$TITLE.lrc" |grep "^\[" |tr "\n" "@" )
title_changed=""
fi
[ "$notfound" = yes ] && continue
#下载歌词
if [ ! -s "$LRCDIR/$TITLE.lrc" ] && [ "$TITLE" ];then
DOWNLRC "$TITLE"
[ ! -s "$LRCDIR/$TITLE.lrc" ] && OSD_SHOW "$TITLE:未找到lrc文件" && notfound="yes"
[ -s "$LRCDIR/$TITLE.lrc" ] && TIME_LIST=($(LRC_SPLIT "$LRCDIR/$TITLE.lrc"))\
&& LRC=$(cat "$LRCDIR/$TITLE.lrc" |grep "^\[" |tr "\n" "@" )
fi
#取得播放时间并显示歌词
if [ "$go_on" = 2 ];then
t=`echo "$a" |sed 's/.*\ //g'`
[ "$t" ] && [ -s "$LRCDIR/$TITLE.lrc" ] && TIME="$(FIND_LRC_TIME "$t")" && t="" \
&& DISPLAY "$LRC" "$TIME"
go_on=""
fi
done
}
#*******main******
while true;do
MAIN
sleep 1.5
done