家庭网络
2014 年 6 月 22 日
在HG255D OpenWrt上安装ShairPort实现无线音乐播放
本文介绍了如何在OpenWrt设备上安装ShairPort,将苹果设备的音乐通过OpenWrt连接的音响进行播放。只需要一个带USB接口的OpenWrt设备、一个USB声卡和一个音响就可以实现。作者介绍了如何安装USB声卡的硬件外观和软件支持,并详细讲解了在OpenWrt设备上安装ShairPort的过程。此外,对于一些OpenWrt系统上不支持的设备,作者也提供了手动解压安装的方法。
概述
ShairPort是一个Airtunes 模拟器,在OpenWrt设备上安装之后,Apple device就可以将设备的音乐在OpenWrt上(的音响)进行播放,使OpenWrt变成一个无线音响。这么一套
高科技
系统其实只需要3个设备:- 带USB接口的OpenWrt设备
- USB声卡
- 音响
家里的路由器正好安装了OpenWrt系统、音响也是现成的,就差一个USB声卡就可以实现了。花17块大洋从马云那里淘了一个,开始了Shairport折腾之旅。
USB声卡安装
硬件外观
到手的USB声卡,外观还过得去:
内部视图,使用的是
CM108
音频控制芯片,牛屎芯
形式无封装,焊接也是惨不忍睹:软件支持
不管USB声卡内部如何糟糕,看看能不能用。先安装音频支持:
opkg update && opkg install kmod-usb-audio
插上USB声卡后PandoraBox可以直接识别:
同时在/dev目录上也可以看到audio和dsp两个设备,说明系统支持该声卡。
安装ShairPort
我的路由器是HG255D,lintel没有编译Shairport,需要自己编译和安装。而且我是使用trunk版本的openwrt编译的,在HG255D PandoraBox并不能直接安装,需要手动解压安装。
原以为声卡安装很顺利,ShairPort也没什么困难,只要编译Shairport后扔到OpenWrt上运行就可以嘛!但实际难度却远比我想象的复杂多了。
将问题复杂化的,就是该死的模块依赖!Shairport依赖avahi-daemon;avahi-daemon需要libavahi-client;libavahi-client需要dbus支持…
就这样一个个库编译测试,折腾了近4个小时,最后终于搞定Shairport:
折腾总结
需要安装的软件列表
整理出需要安装的下面这些软件和库,Shairport才能正常运行:
- avahi-daemon
- dbus
- libao
- libavahi
- libavahi-client
- libdbus
- libexpat
- shairport
如果OpenWrt软件源里有上面这些软件,可以通过一条命令安装:
opkg install avahi-daemon dbus libao libavahi libavahi-client libdbus libexpat shairport
HG255D Shairport一键安装包
为了方便同样使用HG255D的朋友,我将我路由器上安装Shairport上用到的文件备份打包,这个压缩包可以让实现在HG255D上
一键安装
Shairport。链接地址:http://robots.shuyz.com/openwrt/hg255d/shairport/该压缩包文件列表如下:
lance@debianVM:~/work$ tree
.
├── etc
│ ├── avahi
│ │ ├── avahi-daemon.conf
│ │ └── services
│ │ ├── http.service
│ │ └── ssh.service
│ ├── config
│ │ └── shairport
│ ├── dbus-1
│ │ ├── session.conf
│ │ ├── system.conf
│ │ └── system.d
│ │ └── avahi-dbus.conf
│ └── init.d
│ ├── avahi-daemon
│ └── dbus
└── usr
├── bin
│ ├── dbus-launch
│ ├── dbus-launch.real
│ └── dbus-uuidgen
├── lib
│ ├── ao
│ │ └── plugins-4
│ │ ├── libalsa.so
│ │ └── liboss.so
│ ├── dbus-1
│ │ └── dbus-daemon-launch-helper
│ ├── libao.so.4
│ ├── libao.so.4.0.0
│ ├── libavahi-client.so.3
│ ├── libavahi-client.so.3.2.9
│ ├── libavahi-common.so.3
│ ├── libavahi-common.so.3.5.3
│ ├── libavahi-core.so.7
│ ├── libavahi-core.so.7.0.2
│ ├── libdbus-1.so.3
│ ├── libdbus-1.so.3.5.7
│ ├── libexpat.so.1
│ └── libexpat.so.1.6.0
└── sbin
├── avahi-daemon
├── dbus-daemon
└── shairport
使用下面的命令来安装:
cd /tmp
# 下载压缩包
wget http://robots.shuyz.com/openwrt/hg255d/shairport/Shairport%20%20for%20HG255D.tar.gz -O shairport.tar.gz
# 将压缩包里的文件释放到相应目录
gunzip shairport.tar.gz
tar xvf shairport.tar -C /
# 设置开机启动
/etc/init.d/dbus enable
/etc/init.d/avahi-daemon enable
# 这里没有shairport自启动,因为我改写了shairport通过avahi-daemon来启动
#重启
reboot
#重启之后使用ps命令查看是否有dbus, avahi-daemon 和shairport进程,如果有的话就可以用Apple device连接了
因为这些文件都是手动放到系统的,卸载也非常方便,将下面的命令保存为uninstall.sh后运行就可以了:
#!/bin/sh
/etc/init.d/dbus disable
/etc/init.d/avahi-daemon disable
#avahi-daemon
rm -rf /etc/avahi/
rm /etc/init.d/avahi-daemon
rm /usr/sbin/avahi-daemon
#dbus
rm -rf /etc/dbus-1/
rm /etc/init.d/dbus
rm /usr/bin/dbus-launch
rm /usr/bin/dbus-launch.real
rm /usr/bin/dbus-uuidgen
rm -rf /usr/lib/dbus-1/
rm /usr/sbin/dbus-daemon
#libao
rm -rf /usr/lib/ao/
rm /usr/lib/libao.so.4
rm /usr/lib/libao.so.4.0.0
#libavahi
rm /usr/lib/libavahi-common.so.3
rm /usr/lib/libavahi-common.so.3.5.3
rm /usr/lib/libavahi-core.so.7
rm /usr/lib/libavahi-core.so.7.0.2
#libavahi-client
rm /usr/lib/libavahi-client.so.3
rm /usr/lib/libavahi-client.so.3.2.9
#libdbus
rm /usr/lib/libdbus-1.so.3
rm /usr/lib/libdbus-1.so.3.5.7
#libexpat
rm /usr/lib/libexpat.so.1
rm /usr/lib/libexpat.so.1.6.0
#shairport
rm /etc/config/shairport
#/etc/init.d/shairport
rm /usr/sbin/shairport
遇到的问题总结
我备份的HG255D一键安装包已经解决了下面的这些问题。
avahi-daemon运行时安全策略错误
dbus_bus_request_name(): Connection ":1.0" is not allowed to own the service "or
g.freedesktop.Avahi" due to security policies in the configuration file
这是由于avahi-daemon是用nobody身份运行的,在
/etc/dbus1/system.d
目录下建一个avahi-dbus.conf
文件,内容如下:<!DOCTYPE busconfig PUBLIC
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<!-- Only root or user avahi can own the Avahi service -->
<policy user="nobody">
<allow own="org.freedesktop.Avahi"/>
</policy>
<policy user="root">
<allow own="org.freedesktop.Avahi"/>
</policy>
<!-- Allow anyone to invoke methods on Avahi server, except SetHostName -->
<policy context="default">
<allow send_destination="org.freedesktop.Avahi"/>
<allow receive_sender="org.freedesktop.Avahi"/>
<deny send_destination="org.freedesktop.Avahi"
send_interface="org.freedesktop.Avahi.Server" send_member="SetHostName"/>
</policy>
<!-- Allow everything, including access to SetHostName to users of the group "adm" -->
<policy group="adm">
<allow send_destination="org.freedesktop.Avahi"/>
<allow receive_sender="org.freedesktop.Avahi"/>
</policy>
<policy user="root">
<allow send_destination="org.freedesktop.Avahi"/>
<allow receive_sender="org.freedesktop.Avahi"/>
</policy>
</busconfig>
avahi-daemon协议不可用
SO_REUSEPORT failed: Protocol not available
Failed to create server: No suitable network protocol available
修改
/etc/avahi/avahidaemon.conf
文件,在server段增加一行:disallow-other-stacks=yes
avahi-daemon自启动失败
启动后没有发现avahi-daemon进程,手动运行时提示
Failed to create server: No suitable network protocol available
。
测试发现avahi-daemon必须先于shairport启动,如果shairport先启动,运行avahi-daemon就会出现上述错误,所以我们改写一下/etc/init.d/avahi-daemon
文件,让avahi-daemon启动完之后再启动shairport,里面的方法改成:start() {
killall shairport
[ -f $DEFAULT ] && . $DEFAULT
mkdir -p $RUN_D
$BIN $OPTIONS
/usr/sbin/shairport --daemon -P /var/run/shairport.pid
}
stop() {
killall shairport
$BIN -k
}
最后将shairport自启动取消:
/etc/init.d/shairport disable
。shairport不能调用配置文件
```/etc/init.d/shairport start
调用配置文件是每次都启动失败,所以我直接使用
/usr/sbin/shairport —daemon -P /var/run/shairport.pid`来调用默认配置启动。播放时出现爆音(声音颤抖)
在HG255D上播放正常,在WR703N却出现爆音,在恩山找到解决方案:
#创建一个ALSA配置文件,将采样率从48KHz降低到44.1KHz
vi /etc/asound.conf
#写入以下内容:
defaults.pcm.dmix.rate 44100 # Force 44.1 KHz
defaults.pcm.dmix.format S16_LE # Force 16 bits
最后重启一下。
参考资料
- github, OpenWRT-ShairPort
- Linux USB, List of USB ID’s
- OpenWrt中文网, 让你的RG100A-AA支持AirPlay
- stackoverflow, dbus_bus_request_name (): Connections are not allowed to own the service
- github, avahi 0.6.31-10 -> 0.6.31-11 breaks avahi-daemon #606
- superuser, Create a tarball with a fake `root`
- 恩山论坛, 把TL-WR703N打造成真正的AirPlay播放器
本文为原创文章,未经允许请勿非法盗用资源。我们保护知识产权,尊重每一个创作者的劳动成果。如需转载,请务必注明出处并获得授权,谢谢合作!
作者:Lance | 发表日期:2014 年 6 月 22 日