树莓派用AirPlay播放实现WiFi连无线音响外放

转:http://shumeipai.nxez.com/2014/12/10/raspberry-pi-using-airplay-wireless-audio-playback-achieve-even-putting-wifi.html

之前有一篇文章介绍了如何使用蓝牙实现手机连接无线音箱外放,在网上搜索相关资料的过程中,我发现了树莓派另外一个强大的功能,那就是可以实现苹果(Apple)的AirPlay播放技术,简单的介绍一下,AirPlay类似于蓝牙音响播放,但是其是建立在WiFi局域网基础上的,在接入有AirPlay播放技术的局域网上,苹果的设备就会显示支持AirPlay。综合AirPlay的优势,我开始在Raspberry Pi(树莓派)上实现相关功能。

同样的,关于树莓派一些好玩的功能国外资料较为丰富,经过查阅后《Raspberry Pi Airplay Tutorial》(原文超级详细)这一篇文章对我帮助较大,具体步骤如下。

1. 升级Raspberry Pi系统的软件

1
2
sudo apt-get update
sudo apt-get upgrade

2. 将音频输出变更为默认的音频输出口

通常情况下树莓派的音频输出使用的是HDMI接口,我们需要下面的命令将其变更为普通音频输出口:

1
sudo amixer cset numid=3 1

这一步我遇到一个错误:

1
2
3
ALSA lib pulse.c:243:(pulse_connect) PulseAudio: Unable to connect: Access denied
 
amixer: Control default openerror: Connection refused

提示没有权限,如果不使用sudo则没有这类问题,比较郁闷。如果你也遇到同样的问题,先跳过,我们继续下面的步骤。

3. 安装系统所必需的软件包

1
2
3
sudo apt-get install git libao-dev libssl-dev
sudo apt-get install libcrypt-openssl-rsa-perl libio-socket-inet6-perl
sudo apt-get install libwww-perl avahi-utils libmodule-build-perl

4. 安装Perl Net-SDP协议软件

1
2
3
4
5
6
7
8
cd ~
git clone https://github.com/njh/perl-net-sdp.git perl-net-sdp
cd perl-net-sdp
perl Build.PL
sudo ./Build
sudo ./Buildtest
sudo ./Buildinstall
cd..

5. 使用Shairport将树莓派设置为AirPlay接收器

1
2
3
4
cd ~
git clone https://github.com/hendrikw82/shairport.git
cd shairport
make

6. 启动Shairport以支持AirPlay

1
./shairport.pl -a WangyePi

这里我们指定了一个名字叫做WangyePi,大家可以根据实际进行修改,自此,你可以使用苹果设备来访问AirPlay了,当然每次使用这个命令略显不便,下面介绍如何将其变成系统服务。

7. 将Shairport设置为系统服务

1
2
3
4
5
6
7
cd shairport
sudo makeinstall
sudo cpshairport.init.sample /etc/init.d/shairport
 
cd /etc/init.d
sudo chmoda+x shairport
sudo update-rc.d shairport defaults

好了,上面的步骤将移植Shairport到系统路径下,同时创建名称为shairport的服务,你可以使用sudo service控制这个服务。

接下来编辑这个启动文件:

1
sudo nano /etc/init.d/shairport

找到DAEMON_ARGS="-w $PIDFILE"这行,并且修改成DAEMON_ARGS="-w $PIDFILE -a WangyePi",同样的这里WangyePi为你的AirPlay名字。

启动AirPlay看看效果吧:

1
sudo service shairport start

8. 一些问题
如果上面步骤完成后一切正常的话,那么恭喜你,这一步可以略过了。我亲自试验下来没有那么顺利,假如AirPlay不能播放的话,建议使用tail /var/log/syslog命令查看系统日志以便于确定问题原因,比如我就遇到下面的错误:

May 11 04:57:05 raspberrypi pulseaudio[2563]: [pulseaudio] protocol-native.c: Denied access to client with invalid authorization data.

具体的处理方式如下,之前我注意到sudo amixer cset numid=3 1命令会导致pulseaudio拒绝访问报错,特诡异,居然管理员权限还有不能访问的资源。

然后我检查了pulseaudio和shairport启动的用户,发现pulseaudio是以pulse账户启动的,而shairport是以root身份启动的,很有可能问题出在这儿,我们只需要让两个都以pulse账户启动就万事大吉了。

命令sudo nano /etc/init.d/shairport修改shairport启动文件,将PIDFILE=/var/run/$NAME.pid改为PIDFILE=/var/run/shairport/$NAME.pid,然后找到两处start-stop-daemon,分别加上-c pulse参数,我的最终修改如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#!/bin/bash
#
# This starts and stops shairport
#
### BEGIN INIT INFO
# Provides:          shairport
# Required-Start:    $network
# Required-Stop:
# Short-Description: shairport - Airtunes emulator!
# Description:       Airtunes emulator!
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
### END INIT INFO
 
# Source function library.
. /lib/lsb/init-functions
 
NAME=shairport
DAEMON="/usr/local/bin/shairport.pl"
PIDFILE=/var/run/shairport/$NAME.pid
DAEMON_ARGS="-w $PIDFILE -a AirPi"
 
[ -x $binary ] || exit0
 
RETVAL=0
 
start() {
    echo-n "Starting shairport: "
    start-stop-daemon -c pulse --start --quiet --pidfile "$PIDFILE"\
                      --exec"$DAEMON"-b --oknodo -- $DAEMON_ARGS
    log_end_msg $?
}
 
stop() {
    echo-n "Shutting down shairport: "
    start-stop-daemon -c pulse --stop --quiet --pidfile "$PIDFILE"\
                --retry 1 --oknodo
    log_end_msg $?
}
 
restart() {
    stop
    sleep1
    start
}
 
case"$1"in
    start)
        start
    ;;
    stop)
        stop
    ;;
    status)
        status shairport
    ;;
    restart)
        restart
    ;;
    *)
        echo"Usage: $0 {start|stop|status|restart}"
    ;;
esac
 
exit0

然后创建PID所在文件夹并设置权限:

1
2
sudomkdir/var/run/shairport
sudochownpulse /var/run/shairport

最后重启shairport服务,看看是不是正常了。

1
sudoservice shairport restart

参考文档

2014年5月12日更新

在上面第8点有些问题的叙述上需要更正一下,今天发现建立在/var/run路径下的shairport目录消失,导致shairport启动失败,于是我将启动文件/etc/init.d/shairport修改如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#!/bin/bash
#
# This starts and stops shairport
#
### BEGIN INIT INFO
# Provides:          shairport
# Required-Start:    $network
# Required-Stop:
# Short-Description: shairport - Airtunes emulator!
# Description:       Airtunes emulator!
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
### END INIT INFO
 
# Source function library.
. /lib/lsb/init-functions
 
NAME=shairport
DAEMON="/usr/local/bin/shairport.pl"
PIDDIR=/var/run/shairport
PIDFILE=$PIDDIR/$NAME.pid
DAEMON_ARGS="-w $PIDFILE -a AirPi"
 
[ -x $binary ] || exit 0
 
RETVAL=0
 
start() {
    echo -n "Starting shairport: "
    if [ ! -d $PIDDIR ]; then
        mkdir -p $PIDDIR
        chown pulse:pulse $PIDDIR
    fi
    start-stop-daemon -c pulse --start --quiet --pidfile "$PIDFILE" \
                      --exec "$DAEMON" -b --oknodo -- $DAEMON_ARGS
    log_end_msg $?
}
 
stop() {
    echo -n "Shutting down shairport: "
    start-stop-daemon -c pulse --stop --quiet --pidfile "$PIDFILE" \
                --retry 1 --oknodo
    log_end_msg $?
}
 
restart() {
    stop
    sleep 1
    start
}
 
case "$1" in
    start)
        start
    ;;
    stop)
        stop
    ;;
    status)
        status shairport
    ;;
    restart)
        restart
    ;;
    *)
        echo "Usage: $0 {start|stop|status|restart}"
    ;;
esac
 
exit 0

    A+
发布日期:2016年01月24日  所属分类:未分类

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: