树莓派 2 Linux 和 Windows10 学习手册(三)
原文:Learn Raspberry Pi 2 with Linux and Windows 10
协议:CC BY-NC-SA 4.0
九、WiPi:无线计算
树莓派的最大优势之一是它很小,可以放入任何你想得到的小角落或缝隙。这就是为什么它一直被吹捧为人们在设计时使用的最佳选择——它可以放在任何地方,只要有合适的外围设备,几乎可以完成任何任务。此外,它的低功耗意味着在这些情况下使用它的障碍更少,因为它不需要大量的电气管道来“工作”也就是说,树莓派是一个超级小机器,为你的钱提供了巨大的帮助!
然而,这并非没有一些附加条件(见图 9-1 )!如果没有少量的外部电力供应,所有这些电力都是徒劳的。虽然 5 伏并不多,但它确实需要神奇地进入你的树莓派中才能打开灯。除了需要电源之外,Pi 本身几乎没有用处,因为除了让电源 LED 点亮和熄灭之外,Pi 在 5 伏电压下几乎没有什么作用。您需要连接设备以使 Pi 有用。要将 Pi 用作简单的家用电脑,您需要(至少)具备以下条件:
图 9-1。
Constrained Pi
- HDMI 或复合视频电缆
- 用于互联网和网络访问的以太网电缆
- 用来输入数据的键盘
- 提供存储的 SD 卡
突然,你明白我的意思了;树莓派,这个小小的独立超级机器实际上被束缚住了。受限于人类可用性和交互性的需求,这些约束意味着将大量电缆连接到您的 Pi,只是为了从中获得一些基本功能。正如您可能猜到的那样,一切还没有结束!有很多方法可以分离你的 Pi,让它更具移动性,让你可以更灵活地使用它。这就是本章的目的:为您提供工具和一些背景知识来移除约束您的 Raspberry Pi 的电线。
准备 WiPi
除了在您的 SD 卡上加载一份 Raspbian 之外,您还需要确保您的 Raspbian 版本已经升级,因为九月份的版本在 WiFi 访问管理方面有了重大改进。要启动这个系统,首先需要运行几个快速命令:
$ sudo apt-get update
$ sudo apt-get upgrade
这两个命令将首先告诉您的apt-get实例进行更新,以了解哪些版本的软件可供您使用。第二个将告诉apt-get比较并安装系统上当前安装的所有软件的每个升级版本。可以想象,定期运行这些命令是一个非常好的主意,因为它可以让您的系统运行最新版本的软件。
简单约束移除
在你开始随意切断电缆之前,你需要明白你想用你的 Pi 实现什么。这将自动对你想用它做什么设置一些限制。我不能预先假定你想用你的圆周率做什么,因为真的有这么多选择。因此,鉴于此,我将尝试在这里提供一些个人的方法,你可以切断绳索(不是字面上的)和解开你的 Pi。你很可能能够利用你新学到的电缆切割技巧和后面章节中的一些内容来改进设计,或者使它们更好地满足你的目的。
移除人工输入设备
从最容易和最低挂的水果开始:显示器,键盘和音频电缆。我知道说一下子去掉三个外围设备是最容易的,这听起来很可笑,但是你真的在等式中去掉了非常不同的东西:你。到目前为止,最容易切断的连接是人机交互设备。事实上,这本书的大部分内容都是为了给你在没有显示器、键盘或扬声器的帮助下使用 Pi 的技巧。这并不是说你不能没有;您可以随时根据需要将它们插回去,以诊断任何真正关键的问题,但是您可以从移除它们并远程管理您的 Pi 开始。这里使用 SSH 是关键,因为您可以使用 SSH 通过网络连接远程连接到您的 Pi。一旦您连接到您的 Pi,您就有完全的命令行访问权来执行您需要的任何任务。还有一个额外的好处是,您可以使用sudo raspi-config改变 Pi 中的内存分配,并将memory_split的值设置为 240/16,这将把大部分内存放入空闲 RAM 供您的系统使用,并尽可能少地放入您通常不会使用的图形显示中。
在你认为这意味着不再使用显示器和键盘之前,停下来。您想用 Pi 做的所有事情都应该在一个工作环境中进行测试和配置,包括键盘、显示器、鼠标等等,所有这些都可以使用。一旦您的系统进入不受您干扰的工作状态,您就可以打开和关闭电源,而无需在每次您知道应该能够移除所有人机界面设备时跳回来进行管理。这对任何人来说都是一个很好的开始:能够移除所有电缆并远程与您的系统交互。这也意味着你可以做其他事情,如通过你的手机或互联网上的工作系统管理你的树莓派。一旦你有了跨越互联网来管理你的机器的感觉,我保证你会问自己以前没有它你是怎么做的。
添加远程 GUI
好吧,虽然我很乐意承认在控制台内工作有一些真正的好处——只是在远程环境中,有些人就是想不通。而且在很多情况下,不管出于什么原因,这都是不切实际的。在这些情况下,最好使用一种叫做虚拟网络计算(VNC)的工具,让您能够从另一台机器上与您的 Pi 桌面进行交互。
为此,您需要在您的 Pi 上安装一个 VNC 服务器,并且在您的机器上需要一个客户机。有许多不同的 VNC 解决方案,只要他们遵守 VNC 协议,他们应该都是兼容的。对于您的 Pi,您将使用 tightvnc,因为它的目标是高效和“紧凑”您可以在 www.tightvnc.com 下载 Windows 和 Linux 系统的客户端。但是在您进入客户机之前,首先要在您的 Pi 上安装服务器。运行以下命令:
$ sudo apt-get install tightvncserver
此命令将使用包管理工具安装 tightvnc 您的输出应该类似于以下内容:
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
x11-xserver-utils xfonts-base xfonts-encodings xfonts-utils
Suggested packages:
tightvnc-java nickle cairo-5c xorg-docs-core
The following NEW packages will be installed:
tightvncserver x11-xserver-utils xfonts-base xfonts-encodings xfonts-utils
0 upgraded, 5 newly installed, 0 to remove and 91 not upgraded.
Need to get 7,824 kB of archives.
After this operation, 11.7 MB of additional disk space will be used.
Do you want to continue [Y/n]?
一旦您安装了紧密的 VNC 服务器,您需要启动它并让它运行,这样您就可以连接。所以继续执行这个命令:
$ tightvncserver
然后会提示您输入一对密码:一个是实际的 VNC 密码,允许您使用鼠标和键盘来操作屏幕;第二个是可选的“仅查看”密码,允许您查看屏幕上的内容,但不能进行交互。执行后,您应该会看到以下内容:
You will require a password to access your desktops.
Password:
Warning: password truncated to the length of 8.
Verify:
Would you like to enter a view-only password (y/n)? n
New ’X’ desktop is raspberrypi:1
Creating default startup script /home/pi/.vnc/xstartup
Starting applications specified in /home/pi/.vnc/xstartup
Log file is /home/pi/.vnc/raspberrypi:1.log
现在您需要做的就是在您希望浏览的机器上连接 tightvnc 客户机。继续启动客户端。我在 Windows 环境下工作,你应该会看到如图 9-2 所示的屏幕。
图 9-2。
TightVNC Client
在图 9-2 中,你可以看到我已经输入了我的树莓派的 IP 地址和:1。通常 IP 地址后的一个冒号代表一个端口号,但在这种情况下,它代表一个屏幕号。如果你回过头来看一下从紧 VNC 启动的输出,你可以看到它说它创建了一个新的桌面raspberrypi:1,这就是我已经连接到的。现在,按下连接键,屏幕上就会出现可爱的粉红色树莓,你可以在树莓 Pi 环境中四处移动。
然而,如果您重新启动,您将再次失去 VNC 服务器,并且运行tightvncserver将再次要求您提供凭证。这不是执行此操作的最佳方式,因此,如果您希望重新启动服务器,可以运行以下命令:
$ vncserver :1 -geometry 1920x1080 -depth 24
该命令要求在尺寸为 1920 x 1080 的屏幕:1上运行一个vncserver,这是您的 Pi(全 1080p 高清)的最大分辨率,并将颜色深度设置为 24 位。如果需要,您可以降低这些值以适合您的客户端屏幕尺寸,或者降低您的 Pi 在托管 VNC 连接时使用的资源数量。除此之外,您可能希望在引导时运行您的 VNC 服务器,这样您就不需要 SSH 来建立视频连接。毕竟那只是多余的!简单的方法是将vncserver命令添加到/etc/rc.local中,因为该文件中的所有内容都会在引导过程中执行。
默认情况下,您的rc.local文件将如下所示:
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
printf "My IP address is %s\n" "$_IP"
fi
exit 0
然后,您可以在exit 0之前添加下面一行来启动 tightvnc:
vncserver :1 -geometry 1920x1080 -depth 24
如果您想要一个正确的启动过程,您可以使用类似下面的脚本作为文件/etc/init.d/tightvnc:
### BEGIN INIT INFO
# Provides: tightvnc
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start Tight VNC Server at boot time
# Description: Start Tight VNC Server at boot time.
### END INIT INFO
#! /bin/sh
# /etc/init.d/tightvnc
USER=pi
HOME=/home/pi
export USER HOME
case "$1" in
start)
echo "Starting Tight VNC Server"
/usr/bin/vncserver :1 -geometry 1920x1080 -depth 24
;;
stop)
echo "Stopping Tight VNC Server"
/usr/bin/vncserver -kill :1
;;
*)
echo "Usage: /etc/init.d/tightvnc {start|stop}"
exit 1
;;
esac
exit 0
创建此文件后,您需要执行以下命令来执行脚本:
$ sudo chmod +x /etc/init.d/tightvnc
然后就可以用/etc/init.d/tightvnc开始和停止脚本了。请注意,第一次运行该脚本时,您必须再次输入 VNC 密码,因为该脚本是以 root 用户而不是 Pi 用户的身份运行的。最后,您可以将脚本设置为自动启动,如下所示:
$ sudo update-rc.d tightvnc defaults:
update-rc.d: using dependency based boot sequencing
既然您已经在 Pi 上安装并配置了 VNC,并且能够消除使用 Pi 对人工输入设备的依赖,那么您就可以进入下一个领域了。
真正的带 WiFi 的 WiPi
从您早期使用 VNC 和 SSH 的工作中,您将逐渐意识到,在删除人工输入设备的过程中,您已经增加了对网络连接的依赖性。这种依赖性以管理的形式出现,因为你不能再通过键盘和显示器直接交互;您需要另一种访问方法:以太网连接。当然,这仍然是一根电线,所以你最好保留输入设备,对吗?这里有一个非常明显的解决方案——WiFi——但令许多人懊恼的是,Raspberry Pi 没有自带 WiFi。如果您想使用无线适配器,您需要出去为您的 Pi 购买一个无线适配器。
好吧,很简单,你说,然后你去当地的计算机硬件商店买一个无线适配器。你环顾四周。有这么多可用的无线适配器!那么,这几十种中哪一种最适合 Pi 呢?他们都可以和 Pi 一起工作吗?虽然大多数人会凭直觉去挑选最便宜的,适合他们家里 WiFi 设置的,但这不是正确的做法,因为还有其他因素在起作用。
首先,所有的 USB 设备都需要电源,正如你所知,树莓 Pi 需要 5 伏的电源。这意味着您将需要一个运行在较低电量的无线设备(如果您在 Pi 的 USB 上放置太多的消耗,您可能会使它崩溃),或者您将需要投资一个连接到外部电源的供电 USB 设备(对您的目的来说不是很好,但我将在稍后介绍这一点,因为它们还有其他用途)。所以你需要留意权力;您还需要注意兼容性,因为一些陌生的无线适配器可能不支持 Linux 系统。我已经包含了一些来自 Raspberry Pi 社区的数据,这些数据是关于他们使用各种无线适配器的体验,以补充我自己的数据。
如图 9-3 所示,我选择使用从当地技术商店购买的 D-Link DWA-131 无线适配器。本例的其余部分将介绍使用 DWA-131 让您的 Pi 与您的本地无线网络通信的一些基础知识。
图 9-3。
D-Link DWA-131 802.11n wireless N nano adapter Note
当您连接无线适配器时,您的 Pi 可能会重新启动,因此请事先保存所有工作。
这并不意味着您需要单独使用这个特定的适配器;一旦您成功地让无线适配器正确注册,大多数无线适配器与您的 Pi 一起工作的设置过程应该是相同的。所以事不宜迟,开始并插入无线适配器,开始工作。板卡的当前状态如图 9-4 所示。
图 9-4。
Three down, two to go!
正如你所看到的,我仍然有我的以太网电缆连接到现在。我将向您展示如何从命令行和 GUI 在您的 Pi 上配置无线。在您直接进入配置之前,您需要确切地知道您正在处理什么,所以进入 shell 并运行lsusb命令,它就像ls命令一样,但是用于 USB 设备。
$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp.
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 004: ID 07d1:3303 D-Link System DWA-131 802.11n Wireless N Nano Adapter(rev.A1) [Realtek RTL8192SU]
完美!您可以从这个命令中看到,我的无线适配器已经被系统识别,应该可以正常工作了——太棒了。如果没有,不要害怕;您只需要为您的特定网卡安装驱动程序。少量的谷歌研究,你应该可以找到无线网卡的芯片组。芯片组是指无线适配器内“运行”无线适配器的小硅芯片。芯片组通常是由完全不同的公司制造的,与设备上显示的公司不同,您需要与芯片组进行交互,从而决定您需要找到哪些驱动程序。一旦你找到了芯片组,快速搜索应该会指出你需要安装什么驱动程序包。一旦您安装了您的驱动程序包,并且您可以在lsusb中看到您的无线适配器,您就可以进入下一步。
因为您已经安装并注册了设备,所以您应该检查该设备是否已正确注册为网络设备。在使用 Linux 时,最常用的网络管理工具是ifconfig。所以继续运行ifconfig并检查输出:
$ ifconfig
eth0 Link encap:Ethernet HWaddr b8:27:eb:8a:46:ba
inet addr:10.0.0.20 Bcast:10.0.0.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:6558 errors:0 dropped:0 overruns:0 frame:0
TX packets:268 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:374403 (365.6 KiB) TX bytes:28129 (27.4 KiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
wlan0 Link encap:Ethernet HWaddr 90:94:e4:51:81:7a
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
之前的配置实际上显示了三个设备的信息,而不仅仅是无线适配器的信息(其中两个您在第三章中看到过):
- 它首先显示了作为物理以太网设备的
eth0设备。 - 接下来是
lo适配器;回想一下,这是系统的内部自引用设备,当您想要将流量从其自身寻址到 Pi(或任何系统)内部时,可以使用该设备。 - 最后你有
wlan0,这是无线设备。您应该能够注意到eth0和lo设备与wlan设备之间的一些差异——它没有 IP 地址(用inet addr表示)或掩码。这些是您需要配置的内容,以便让它与您的无线网络进行对话,以及您的无线网络 SSID 和安全安排的详细信息。所以这将是你的下一步。
如果您的适配器没有出现,但是在lsusb中注册了,重新启动并执行相同的故障诊断步骤。系统可能能够识别您的设备,但无法与之正确连接。为您的系统安装一个驱动程序包可能是这里的解决方案。
首先,让这变得简单,通过 GUI 进行配置,具有讽刺意味的是,这涉及到通过命令行安装某些东西。继续启动apt-get来安装wpa-gui。WPA GUI 是最近添加到 Raspbian 中的一个应用程序,它使无线设备的安装和配置变得非常非常简单。事实上,这是最近的事,这一章需要重写以包含它,因为在第一轮写作中使用的 Raspbian 版本不包含它!如果您不确定是否有正确的版本,您应该运行这个命令,因为这样做没有坏处。安装该应用程序的命令如下:
$ sudo apt-get install wpagui
如果您有包含wpagui的 Raspbian 的最新版本,您将看到下面的输出,表明该包已经安装:
Reading package lists... Done
Building dependency tree
Reading state information... Done
wpagui is already the newest version.
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
如果您尚未安装该软件包,您的安装将如下所示:
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
libaudio2 liblcms1 libmng1 libqt4-svg libqtcore4 libqtgui4 menu
Suggested packages:
nas liblcms-utils qt4-qtconfig menu-l10n
The following NEW packages will be installed:
libaudio2 liblcms1 libmng1 libqt4-svg libqtcore4 libqtgui4 menu wpagui
0 upgraded, 8 newly installed, 0 to remove and 96 not upgraded.
Need to get 8,921 kB of archives.
After this operation, 22.6 MB of additional disk space will be used.
Do you want to continue [Y/n]?
太棒了!现在你已经安装了wpagui,你应该可以通过用户界面很好地利用它。但是在您开始之前,请继续重新启动您的 Pi,因为您已经对 Pi 管理网络连接的方式进行了重大更改,并且您希望在继续之前确保它是防爆的。穿好了吗?你可以运行ifconfig并且输出看起来是一样的,很棒。
现在您可以开始配置您的无线适配器。您将从 GUI 开始,然后看看如何通过命令行来完成。
Note
如果您注意到您的 Pi 变慢或无法连接到 WiFi,可能是您的键盘消耗了太多的电量。尝试移除它并使用 VNC 或 SSH 来配置您的无线网络。
GUI WiFi 配置
登录 GUI,应该会有一个名为 WiFi Config 的新图标,如图 9-5 所示。
图 9-5。
WiFi Config icon
双击此图标打开应用程序,您应该会看到 wpagui 窗口,如图 9-6 所示。
图 9-6。
wpa_gui window
在 wpagui 窗口中,按下扫描按钮。这需要一些时间,但是会弹出另一个窗口,如图 9-7 所示。
图 9-7。
Scan results window
这个窗口应该大家都很熟悉。这是选择无线网络的窗口。找到您的特定网络,然后双击它以打开配置窗口(参见图 9-8 )。
图 9-8。
Network details
我假设您应该准备好了设置配置的详细信息。大部分都是直观的,但有几件事你需要注意:
- SSID 是您的无线网络的“名称”,因此您需要键入此名称。
- 接下来是身份验证,它指定了您正在使用的身份验证类型:WEP、WPA、WPA2 等等。
- 接下来是加密,它选择您将使用的加密模式。
- 最后是 PSK,代表预共享密钥。这是你的 WiFi 密码。
现在转到“无线安全”选项卡,设置您用于 WiFi 的身份验证方法、加密方法和密码。这些信息通常在路由器的配置系统中,但也可以写在路由器本身或路由器手册中。现在点击添加。您的无线设置应该保存到系统中,系统将获取这些设置并开始尝试连接到您的适配器;过一会儿,您应该会看到类似图 9-9 的内容。
图 9-9。
WiFi connected!
如果您没有看到这一点,请查看鼠标悬停消息,它会让您了解您的连接出现了什么问题。检查您的设置是否正确,以及您是否选择了正确的安全方法。如果有疑问,请打开您的路由器配置进行仔细检查。最后,您可以回到控制台,再次发出ifconfig来检查您的无线适配器设置!
wlan0 Link encap:Ethernet HWaddr 90:94:e4:51:81:7a
inet addr:10.0.0.59 Bcast:10.0.0.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:772 errors:0 dropped:10 overruns:0 frame:0
TX packets:35 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:100749 (98.3 KiB) TX bytes:4254 (4.1 KiB)
这看起来更像你所期望的;它有一个 IP 地址、掩码等等。它还显示它一直在无误地发送和接收数据包(即 RX 和 TX 数据包编号)。最后的测试是从第二台机器 ping 那个 IP 地址,就这样。现在,您可以移除以太网电缆了。作为最后的测试,继续并重新启动;重新启动后,您应该能够 ping 通系统的wlan0 IP 地址,这表明您已经成功地保存了重新启动后存储的无线适配器详细信息。现在,您可以移除下一根电缆并重新启动,以确保您的系统默认使用无线适配器。
从命令行管理 WiFi
对于那些不太想使用 GUI 或者认为自己是真正的 Linux 传统的纯粹主义者(只使用命令行来管理系统)的人来说,这正是适合你的地方!为此,您将修改网络管理器配置。NetworkManager 系统决定如何管理以太网设备的基本方法有两种:
- 它检查是否设置了
/etc/NetworkManager/NetworkManager.conf中的managed标志。 - 它接管在
/etc/network/interfaces中配置的任何东西的管理;这些设置说明应该如何管理该设备。
您不希望 NetworkManager 系统从上面接管您的设置,所以您需要确保它不会这样做。只有在您之前安装了 GUI,或者 NetworkManager 与您的 Raspbian 映像捆绑在一起时,这才会是一个问题,但是最好是彻底的。所以继续检查/etc/NetworkManager/NetworkManager.conf并确保managed标志被设置为false。该文件应该类似于:
[main]
plugins=ifupdown,keyfile
[ifupdown]
managed=false
一旦完成,继续重新启动您的 Pi;您希望确保 Pi 正确启动,并且所有现有的以太网连接在第一次重新启动后都工作正常。现在您需要将配置添加到/etc/network/interfaces中,以便它知道如何管理设备并连接到您的 WiFi。所以请继续打开/etc/network/interfaces。您将看到该文件已经部分填充了以下行:
auto lo
iface lo inet loopback
iface eth0 inet dhcp
根据您的系统是否已经进行了一些无线配置,您可能还会在文件中看到以下几行。
allow-hotplug wlan0
iface wlan0 inet manual
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet dhcp
这些行分别对应于 loopback 和eth0设备,并提供一些关于它们管理的简单细节;在这种情况下,环回是一个自动管理的环回设备,eth0设备通过 DHCP 获得一个 IP 地址。您的wlan0设备可能也有一些现有配置;如果它们存在,您应该通过在它们前面添加一个#来注释掉它们,或者从文件中删除它们。您现在需要为wlan0无线设备添加一个新的配置,所以继续将以下内容添加到您的配置中现有内容的下方:
auto wlan0
iface wlan0 inet dhcp
wpa-ssid <Your WiFi SSID>
wpa-psk <Your WiFi password>
这个块表示您将拥有一个自动管理的wlan0设备,它通过 DHCP 获取其连接信息。你还把 SSID 和 PSK 传给它。此配置将适用于 WPA 和 WPA2 网络安全实施。完成后,就该测试您的新设备了,所以继续运行下面的代码,这将启动界面。这可能需要一些时间,但是您的输出应该类似于我的输出:
$ sudo ifdown wlan0
$ sudo ifup wlan0
Internet Systems Consortium DHCP Client 4.2.2
Copyright 2004-2011 Internet Systems Consortium.
All rights reserved.
For info, please visithttps://www.isc.org/software/dhcp/
Listening on LPF/wlan0/90:94:e4:51:81:7a
Sending on LPF/wlan0/90:94:e4:51:81:7a
Sending on Socket/fallback
DHCPDISCOVER on wlan0 to 255.255.255.255 port 67 interval 8
DHCPDISCOVER on wlan0 to 255.255.255.255 port 67 interval 15
DHCPDISCOVER on wlan0 to 255.255.255.255 port 67 interval 9
DHCPREQUEST on wlan0 to 255.255.255.255 port 67
DHCPOFFER from 10.0.0.1
DHCPACK from 10.0.0.1
bound to 10.0.0.59 ˗˗ renewal in 444671 seconds.
所有这些都表明,该设备已经连接到我的无线网络,并通过 DHCP 获得了一个 IP 地址,这正是你告诉它要做的!现在假设你不想用 DHCP,而是宁愿给你的 WiFi 适配器一个静态 IP 地址。你只需要将iface行改为static而不是dhcp,然后添加你的 IP 地址、子网掩码和网关的详细信息。您的配置将改为如下所示:
auto wlan0
iface wlan0 inet static
address 10.0.0.57
netmask 255.255.255.0
gateway 10.0.0.1
wpa-ssid <Your WiFi SSID>
wpa-psk <Your WiFi password>
现在您已经成功地在系统上配置了无线,您可以继续并重新启动您的 Pi 来检查无线适配器是否自动启动。如果没有,返回并确保您设置了auto wlan0并且您在网络管理器配置文件中启用了managed=false标志。
如果这不起作用,请检查 SSID 和 WiFi 密码的配置设置。您可以使用ifup wlan0确认是否可以启动您的无线适配器;如果在连接和获取 IP 地址时出现问题,您的系统应该在这里显示出来,让您有机会找出问题所在。最后,如果你只是不能让它运行,尝试删除任何其他连接的 USB 设备;它们会从您的 WiFi 适配器吸取宝贵的能量。
命令行上最后一件可能对您有帮助的事情是iw系列命令:
- 您可以使用
scan选项运行iwlist来扫描附近无线热点的信息。 - 或者您可以使用
iwconfig来获取关于您的无线适配器的配置细节。
只剩一个
恭喜你,你即将拥有一个完全无线的树莓派!您已经成功消除了对以太网电缆的需求,现在您可以无线访问您的 Pi。现在应该只剩下一根电缆了!(参见图 9-10 )。
图 9-10。
Last cable standing
消除对电源的需求
你能做的很少,以简化为你的树莓派供电的需求;它需要它,而这个问题的解决方案是有限的。到目前为止,最容易和方便的是获得一个大的 USB 电池。如今,这种充电器几乎随处可见,可以为人们经常随身携带的许多设备充电。这里的简单解决方案是将您的 Pi 连接到这些电池中的一个来使用,因为这种电池应该保证向您的 Pi 输出正确的功率水平,因为它们是为 USB 设备供电而设计的。当考虑用电池给你的 Pi 供电时,重要的是要确定它们能提供 1 安培的功率,因为一些 USB 电池可以充电,但不能提供足够的电量给 Pi 供电。图 9-11 显示了最终的 WiPi。
图 9-11。
WiPi at long last!
有一些将可充电电池和太阳能电池板结合起来的方法,对你来说会走得更远,但这些都超出了本书的范围。
供电 USB 适配器
我之前提到过,如果你在你的 Pi 的 USB 上放太多的电源,你可能会使它崩溃,因为它自己只有有限的电源。解决方案是把你的手放在一个通电的 USB 集线器上。这些供电集线器通常有一个输出连接和多个输入连接,还会有一个电源连接来供电。其原理是,人们很少使用 USB 的全部数据传输量,但经常会耗尽电量,因此,有一种方法可以用市电电源补充 USB 设备的电量,这是一种很好的方法,可以让人们更加灵活地使用他们的设备。如果您发现当您连接您的设备时,您的 Pi 会自动关闭,这是一个公平的赌注,您将需要类似这样的东西来帮助分散电力负载(见图 9-12 )。
图 9-12。
Powered USB hub in action
摘要
做了这么多工作,你应该已经看到了很大的回报。您现在应该知道如何配置您的 Pi 以使其无线化。除了正常的 SSH 连接之外,您应该能够通过 VNC 客户端设置并连接到您的 Pi。您已经学习了如何配置您的 Raspberry Pi 来获取无线适配器,并可以将其连接到您现有的无线网络。最后,您应该了解 Pi 在功耗方面的一些限制,以及如何解决这些问题。
十、树莓派
每个人都想成为詹姆斯·邦德。或者至少我知道我有。他似乎陷入了各种各样的情况;然后拿出一个方便的小工具来拯救世界。正如我们所展示的,树莓派对于这样一个小小的硬件来说是极其通用的。这使得它成为一个特工的完美工具,因为只需要一点点能量,你就可以提供一个成熟的技术解决方案,而花费的成本只是雇佣约翰·克立斯的一小部分(不可否认,Pi 并不那么有趣)。考虑到这一点,我们现在可以穿上晚礼服,开始秘密特工的工作了。
所有优秀的特工都知道,你需要能够发现并警惕秘密藏身处的入侵者。因此,这是向您介绍树莓 sPi 的最佳时机!树莓 sPi 是一个间谍相机和警报系统的组合,是发现卑鄙的入侵者进入你的密室的完美解决方案!或者通过互联网监控你的宠物。这里的基本概念是我们将配置我们的 Raspberry Pi。所以事不宜迟,我们开始吧。
所需材料
以下是本项目所需的材料(也见图 10-1 ):
图 10-1。
The Raspberry sPi kit
- 1 个树莓派
- 1 根微型 USB 电缆(用于电源)
- 1x 以太网电缆
- 1 个 USB 网络摄像头
- 1 张 SD 卡
在这一点上,你应该注意到并不是所有的网络摄像头都与 Raspberry Pi 兼容。此文档是用 Logitech C525 网络摄像头创建的。值得庆幸的是,Pi 社区维护了一个兼容硬件的列表,可在 http://elinux.org/RPi_VerifiedPeripherals#USB_Webcams 获得。如果您有疑问,请在那里查看哪些外设可以与您的 Pi 配合使用。
预设
这里没什么特别的;只需连接微型 USB 以获取电源,连接以太网以访问网络,连接 SD 以进行存储,并确保相机保持独立——我们稍后会这样做。此过程的其余部分假设您熟悉以下内容:
- 安装 Raspbian 操作系统
- 了解如何在 Raspbian Linux 环境下工作
如果你对这两者都不熟悉,那也没关系。这就是这本书的目的,所以请回过头来阅读第一章以了解如何开始使用 Raspbian,以及这本书的第二部分以熟悉在 Raspbian Linux 环境中工作。
入门指南
所以,事不宜迟,我们开始吧。继续加载 Raspbian 并将您的 Pi 连接到您的网络。浏览 Raspbian 设置过程,并确保启用 SSH,因为稍后您将需要远程登录。(我们看不到詹姆斯·邦德带着键盘、HDMI 线和显示器,不是吗?)一旦你设置好了,继续 SSH 到你的 Pi(在第三章中讨论)。
好的,一旦你登录,继续发出命令dmesg并查看输出。
dmesg-一般信息
dmesg命令是一个名为驱动程序消息的工具,它向内核显示所有消息的日志输出,包括来自设备和连接到您系统的驱动程序的消息。dmesg在确定连接了哪些设备,以及您应该在哪里以及如何与它们交互方面非常有用。它还列出了在诊断低级问题时非常有用的驱动程序和内核消息。那么,让我们来看看输出的相关部分。
Note
less是更。如果您发现某个命令的输出超出了屏幕的顶部,您再也看不到它了,重新发出该命令,然后通过管道将其发送到less (,即dmesg | less。这应该允许您使用箭头键和空格键向下翻页来浏览任何命令的输出。
[ 1.998581] Waiting for root device /dev/mmcblk0p2...
[ 2.071268] mmc0: new high speed SD card at address 7d37
[ 2.079917] mmcblk0: mmc0:7d37 SD02G 1.83 GiB
[ 2.088723] mmcblk0: p1 p2
[ 2.132278] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null)
[ 2.145275] VFS: Mounted root (ext4 filesystem) on device 179:2.
[ 2.155272] Freeing init memory: 200K
[ 2.187333] usb 1-1: new high speed USB device number 2 using dwc_otg
[ 2.418045] usb 1-1: New USB device found, idVendor=0424, idProduct=9512
[ 2.427750] usb 1-1: New USB device strings: Mfr=0, Product=0, SerialNumber=0
[ 2.438708] hub 1-1:1.0: USB hub found
[ 2.445041] hub 1-1:1.0: 3 ports detected
[ 2.727674] usb 1-1.1: new high speed USB device number 3 using dwc_otg
[ 2.837920] usb 1-1.1: New USB device found, idVendor=0424, idProduct=ec00
[ 2.857413] usb 1-1.1: New USB device strings: Mfr=0, Product=0, SerialNumber=0
[ 2.878968] smsc95xx v1.0.4
[ 2.942985] smsc95xx 1-1.1:1.0: eth0: register ’smsc95xx’ at usb-bcm2708_usb-1.1, smsc95xx USB 2.0 Ethernet, b8:27:eb:8a:46:ba
[ 11.006171] EXT4-fs (mmcblk0p2): re-mounted. Opts: (null)
[ 11.426960] ### snd_bcm2835_alsa_probe c05c88e0 ############### PROBING FOR bcm2835 ALSA device (0):(1) ###############
[ 11.442869] Creating card...
[ 11.448268] Creating device/chip ..
[ 11.454771] Adding controls ..
[ 11.460340] Registering card ....
[ 11.475463] bcm2835 ALSA CARD CREATED!
[ 11.487786] ### BCM2835 ALSA driver init OK ###
[ 18.493739] smsc95xx 1-1.1:1.0: eth0: link up, 100Mbps, full-duplex, lpa 0x45E1
[ 24.672322] Adding 102396k swap on /var/swap. Priority:-1 extents:1 across:102396k SS
如您所见,dmesg的输出有点令人不快,难以理解。许多信息依赖于对dmesg系统如何工作的一些基本原则的理解。首先是方括号[和]内的数值。该值是一个定时器值,用于记录自系统启动以来经过的时间。这是一个很好的方法来跟踪你系统中的事件顺序,并把最近发生的和过去发生的区分开来。
接下来是内容本身。这些行中的大部分单独在诊断上是没有用的,但是它们合在一起形成了一幅非常有趣的画面,描绘了我的 Pi 中到底发生了什么。让我们从第一行开始:
waiting on root device /dev/mmcblk0p2
前几行很明显:系统在等待什么,但什么是/dev/mmcblk0p2?好吧,第一个赠品是/dev;这是 Linux 操作系统列出所有设备的地方,所以我们知道/dev/mmcblk0p2是一个设备。其次是mmcblk0p2,它看起来像一串垃圾,但实际上是一系列缩写。
mmc表示多媒体卡(闪存设备标准)blk表示块存储设备0表示这种类型的第一个逻辑设备p2表示装置的两个隔板
所以我们在等 SD 卡。第二到第四行是我们正在等待的:SD 卡注册,你可以看到它实际上注册为我们提到的每一个子设备,按顺序没有减少!之后,接下来的两行是在这个设备上挂载可读文件系统的设备。继续往下,您可以看到 Pi 的 USB 设备的注册(第 8-15 行),它的以太网端口(第 16、17 和 26 行),最后是一个高级 Linux 声音架构(ALSA)设备,它是音频端口(第 19-25 行)。
现在你明白了我们为什么不一开始就连接网络摄像头,我想看看dmesg输出。既然你知道要找什么,现在继续连接你的网络摄像头并再次运行dmesg。看看出现的新系列。这些应该都和你新附加的网络摄像头有关!下面是我附加我的输出:
[ 8168.793423] usb 1-1.2: new high speed USB device number 4 using dwc_otg
[ 8169.147691] usb 1-1.2: New USB device found, idVendor=046d, idProduct=081d
[ 8169.147736] usb 1-1.2: New USB device strings: Mfr=0, Product=0, SerialNumber=1
[ 8169.147758] usb 1-1.2: SerialNumber: 8627F4C0
[ 8169.314171] Linux video capture interface: v2.00
[ 8169.336482] uvcvideo: Found UVC 1.00 device <unnamed> (046d:081d)
[ 8169.402071] input: UVC Camera (046d:081d) as /devices/platform/bcm2708_usb/usb1/1-1/1-1.2/1-1.2:1.2/input/input0
[ 8169.402280] usbcore: registered new interface driver uvcvideo
[ 8169.402299] USB Video Class driver (1.1.1)
[ 8169.460903] usbcore: registered new interface driver snd-usb-audio
那么,从这些线条中你能看出什么?首先,您可以在dmesg日志中看到这个特定条目的时间差异很大,它代表了从启动到我连接设备之间的延迟。接下来,您将认识到前四行代表 USB 端口接收新连接的设备;事实上,第一行引用了用于完成这个任务的模块dwc_otg(DesignWare Cores 的缩写——On The Go)。第 5 行显示它是一个视频捕获接口,第 6 行显示模块uvcvideo找到了一个它识别并注册的 USB 视频类(UVC)设备。最后,我们还可以看到网络摄像头的麦克风也已经在最后一行注册为snd-usb-audio设备。从这里我们可以看到我的网络摄像头已经连接上了,并通过驱动程序注册到了操作系统中。
既然设备已经注册,我们需要一种方法来引用它,以便它可以被应用程序使用。您会注意到,dmesg输出实际上并没有指定我们添加了哪个设备,所以让我们看一下,看我们是否能以另一种方式匹配它。先来列举一下/ dev的内容(结果如图 10-2 )。
图 10-2。
Contents of /dev directory
$ ls /dev/
那是一些设备。我们可以马上删除一些:所有的tty设备,因为它们是电传打字设备;所有的ram设备,因为那是 Pi 的 RAM 所有的loop设备,因为它们是回环连接器;所有的memblck设备,因为它们与 SD 卡相关;所有的vcs设备,因为它们是虚拟控制台。还是有几个,但是最好看的是video0。我们在找一个网络摄像头,对吗?它注册为视频捕获设备,不是吗?好吧,我们认为这是对的——但是我们怎么知道呢?
udev,更确切地说是udev管理函数,是 Linux 内核的设备管理器。它控制设备如何以及在哪里注册自己,以便它们可以作为操作系统的一部分被应用程序访问。在 Debian(以及 Raspbian)中,udev的内部工作方式可以通过udevadm命令访问,所以让我们开始使用它吧。执行以下操作:
$ udevadm info -a -p $(udevadm info -q path -n /dev/video0)
P: /devices/platform/bcm2708_usb/usb1/1-1/1-1.2/1-1.2:1.2/video4linux/video0
N: video0
S: v4l/by-id/usb-046d_081d_8627F4C0-video-index0
S: v4l/by-path/platform-bcm2708_usb-usb-0:1.2:1.2-video-index0
E: DEVLINKS=/dev/v4l/by-id/usb-046d_081d_8627F4C0-video-index0 /dev/v4l/by-path/platform-bcm2708_usb-usb-0:1.2:1.2-video-index0
E: DEVNAME=/dev/video0
E: DEVPATH=/devices/platform/bcm2708_usb/usb1/1-1/1-1.2/1-1.2:1.2/video4linux/video0
E: ID_BUS=usb
E: ID_MODEL=081d
E: ID_MODEL_ENC=081d
E: ID_MODEL_ID=081d
E: ID_PATH=platform-bcm2708_usb-usb-0:1.2:1.2
E: ID_PATH_TAG=platform-bcm2708_usb-usb-0_1_2_1_2
E: ID_REVISION=0010
E: ID_SERIAL=046d_081d_8627F4C0
E: ID_SERIAL_SHORT=8627F4C0
E: ID_TYPE=video
E: ID_USB_DRIVER=uvcvideo
E: ID_USB_INTERFACES=:010100:010200:0e0100:0e0200:
E: ID_USB_INTERFACE_NUM=02
E: ID_V4L_CAPABILITIES=:capture:
E: ID_V4L_PRODUCT=UVC Camera (046d:081d)
E: ID_V4L_VERSION=2
E: ID_VENDOR=046d
E: ID_VENDOR_ENC=046d
E: ID_VENDOR_ID=046d
E: MAJOR=81
E: MINOR=0
E: SUBSYSTEM=video4linux
E: TAGS=:udev-acl:
E: UDEV_LOG=3
E: USEC_INITIALIZED=8168852755
哇,好吧,这是一大块看起来很吓人的输出。我相信你现在已经猜到了,我们刚刚请求udev系统给我们一个信息查询,查询与名为/dev/video0的设备相关的所有信息,它确实有。然而,在过度换气开始之前,实际上看一看前几行。第一行应该很熟悉——这是我们在dmesg中看到的连接网络摄像头时的设备标识符!事实上,这里的大部分信息都是在dmesg块中引用的数据。好了,既然我们可以将来自dmesg的设备与我们系统中的设备进行匹配,那么可以有把握地说,我们附加的 USB 网络摄像头在文件系统中的名称是/dev/video0。
解决纷争
如果和我的不同,你的网络摄像头在dmesg中注册内核时出现问题,你可能需要安装一个驱动程序。你应该向制造商查询,并上网查看是否有适用于你的摄像头的驱动程序。如果是这样,安装驱动程序,然后尝试重新连接您的网络摄像头,看看它是否可以注册。你甚至可能很幸运,你的设备驱动程序会有一个内核列表,在这个列表中,网络摄像头被注册在dmesg的/dev中——就像前面例子中我的 SD 卡一样。
此外,如果您没有列出像/dev/video0这样的设备,您应该检查其他设备是否与来自dmesg的与您的设备相关的输出相匹配。当 Linux 试图在/dev文件系统的布局上变得明智时,制造商和软件工程师可以做一些有趣的事情来试图脱颖而出——结果是你坐在那里尖叫着你怎么找不到一个设备。因此,请耐心地四处看看,并使用排除法来尝试找出您的设备连接到了哪里。这里的目标是确保您知道哪个/dev文件引用了您的网络摄像头。
动作捕捉
好的,系统配置完毕,检查完毕。已连接网络摄像头,请检查。现在让我们让这一切真正做点什么吧!为了进行网络摄像头捕捉,我们将使用 Linux 动作捕捉,讽刺地命名为运动。因此,让我们继续安装它。运行以下命令,指示 apt-get 下载并安装 motion 包:
$ sudo apt-get install motion
您的输出应该如下所示:
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
ffmpeg libav-tools libavcodec53 libavdevice53 libavfilter2 libavformat53 libavutil51 libdc1394-22 libdirac-You
libjack-jackd2-0 libmp3lame0 libpostproc52 libpq5 libraw1394-11 libschroedinger-1.0-0 libspeex1 libswscale2 libtheora0 libva1
libvpx1 libx264-123 libxvidcore4
Suggested packages:
jackd2 libraw1394-doc speex mysql-client postgresql-client
The following NEW packages will be installed:
ffmpeg libav-tools libavcodec53 libavdevice53 libavfilter2 libavformat53 libavutil51 libdc1394-22 libdirac-encoder0 libgsm1
libjack-jackd2-0 libmp3lame0 libpostproc52 libpq5 libraw1394-11 libschroedinger-1.0-0 libspeex1 libswscale2 libtheora0 libva1
libvpx1 libx264-123 libxvidcore4 motion
0 upgraded, 24 newly installed, 0 to remove and 71 not upgraded.
Need to get 8,365 kB of archives.
After this operation, 17.6 MB of additional disk space will be used.
Do you want to continue [Y/n]? y
我不知道你怎么想,但是我太兴奋了,不想为所有的设置和配置费心;让我们启动 motion,看看它会做什么!以此开始:
$ motion –s
摄像机上的灯亮了,开拍!开始挥舞和移动,因为你想它抓住你!
[1] Changes: 3374 - noise level: 15
[1] Changes: 3198 - noise level: 15
[1] Changes: 3011 - noise level: 15
[1] Changes: 2922 - noise level: 15
[1] Changes: 2555 - noise level: 15
[1] Changes: 2390 - noise level: 15
[1] Changes: 2491 - noise level: 15
[1] Changes: 2874 - noise level: 15
[1] Changes: 2817 - noise level: 15
[1] Changes: 3238 - noise level: 15
[1] Changes: 3093 - noise level: 15
[1] Motion detected - starting event 1
[1] File of type 1 saved to: ./01-20120910203217-05.jpg
[1] Changes: 2912 - noise level: 15
[1] File of type 1 saved to: ./01-20120910203217-06.jpg
[1] Changes: 2480 - noise level: 15
[1] File of type 1 saved to: ./01-20120910203217-07.jpg
就这样,你可以看到它捕捉图像中的变化,并记录你移动时噪声水平的任何变化。最后,它捕捉图像!如果根据您的 SD 卡速度,可能需要一段时间来写出图像文件,请耐心等待。太棒了,工作起来很有魅力,要取消应用程序,您可以继续按 Ctrl+C。如果您愿意,您可以继续使用控制台登录,查看它捕获的任何图像。检查输出通常是一个好主意,因为您的网络摄像头驱动程序可能需要微调,或者可能不会生成有效的输出。如果不想出线缆和 HDMI,可以用scp之类的工具把这些图片复制下来。从 Windows 机器上,您可以使用 winscp 之类的工具来复制任何文件。如果要复制到 Mac 或 Linux 系统,只需发出以下命令来复制文件:
$ scp <raspberry pi’s ip>:/home/pi/*.jpg。
Note
请记住scp命令末尾的句号,这很重要,因为它是命令的目的标识符。
这个命令说要从目录/home/pi中 IP 标识的 Raspberry Pi 上的服务器复制pi用户的主目录和你登录时第一个会到的地方(我说我激动了吧?)并匹配任何以.jpg结尾的文件。末尾的最后一个句点是目的地:在 Linux 中,句点是对当前目录的引用,所以这就是我们要复制的地方。
好了,现在我们已经玩转了图片,让我们进入正题。树莓 sPi 的目标是在没有干预的情况下发挥其功能;这意味着我们将需要有运动应用功能,而不需要我们告诉它。拉斯边已经帮我们处理了大部分的事情,但是还有一些小事我们需要做。
Note
您将需要以 root 用户身份编辑这些文件,所以记得用sudo启动您的文本编辑器。
首先打开并编辑文件/etc/default/motion,将行start_motion_daemon=no改为start_motion_daemon=yes;这个文件决定了当我们发出守护进程的start命令时,守护进程是否会启动,让它按命令运行正是我们想要的。现在我们处理配置,所以继续打开它。文件是/etc/motion/motion.conf,所以打开它。首先你会注意到守护模式将被设置为off,所以继续设置为on,因为我们希望 motion 作为守护启动,这意味着它将在后台运行。接下来要检查的是videodevice行,确保列出的设备与我们之前确认的设备相匹配(对我们大多数人来说,应该是/dev/video0)。
接下来,我们开始深入了解具体情况。首先我们可以修改height、width和framerate。默认设置是以 320 x 240 的分辨率每秒捕捉两幅图像。这将创建一个大约 12 Kb 大小的文件,您可以通过检查我们之前在运动捕捉测试期间生成的文件来进行检查。你可以在你认为合适的时候增加这个数字;请记住,不要超过您的网络摄像头的最大可用分辨率,并且每个文件的大小都会随着分辨率的增加而增加。
接下来是threshold。阈值是捕获图像所需的变化量。您现在可以保留这个值,但以后要记住它,因为您可能希望使捕获更灵敏或更不灵敏。
接下来是ffmpeg_cap_new,它决定你是否要捕捉一个视频文件。我已经把这个关掉了,但是如果你想生成你的动作捕捉的视频文件,你可以开着它。这些文件生成为。swf 文件(想想 YouTube)但是你可以通过编辑ffmpeg_video_codec变量来改变它们。
最后,您可以更改target_dir,它表示当作为守护进程运行时,您将把图像文件输出到哪里。这一点很重要,因为你需要知道从哪里复制文件。此外,重要的是要意识到/tmp目录只是一个临时空间。每次重新启动操作系统时,这个临时空间都会被清空。
这种功能对我们来说是完美的,因为我们不想处理额外的文件,这些文件会留在磁盘上,直到我们把它清理掉;只需重新启动您的树莓 sPi,您就可以再次出发。然而,在某些情况下,我们可能希望在系统重启后保存这些文件——但以后会保存更多。
最后,保存所有更改并退出,这样我们就可以测试新配置了!我的配置显示在这里供您参考:
daemon on
process_id_file /var/run/motion/motion.pid
setup_mode off
videodevice /dev/video0
v4l2_palette 8
input 8
norm 0
frequency 0
rotate 0
width 320
height 240
framerate 2
minimum_frame_time 0
netcam_tolerant_check off
auto_brightness off
brightness 0
contrast 0
saturation 0
hue 0
roundrobin_frames 1
roundrobin_skip 1
switchfilter off
threshold 1500
threshold_tune off
noise_level 32
noise_tune on
despeckle EedDl
smart_mask_speed 0
lightswitch 0
minimum_motion_frames 1
pre_capture 0
post_capture 0
gap 60
max_mpeg_time 0
output_all off
output_normal on
output_motion off
quality 75
ppm off
ffmpeg_cap_new off
ffmpeg_cap_motion off
ffmpeg_timelapse 0
ffmpeg_timelapse_mode daily
ffmpeg_bps 500000
ffmpeg_variable_bitrate 0
ffmpeg_video_codec swf
ffmpeg_deinterlace off
snapshot_interval 0
locate off
text_right %Y-%m-%d\n%T-%q
text_changes off
text_event %Y%m%d%H%M%S
target_dir /tmp/motion
snapshot_filename %v-%Y%m%d%H%M%S-snapshot
jpeg_filename %v-%Y%m%d%H%M%S-%q
movie_filename %v-%Y%m%d%H%M%S
timelapse_filename %Y%m%d-timelapse
webcam_port 8081
webcam_quality 50
webcam_motion off
webcam_maxrate 1
webcam_localhost on
webcam_limit 0
control_port 8080
control_localhost on
control_html_output on
track_type 0
track_auto off
track_motorx 0
track_motory 0
track_maxx 0
track_maxy 0
track_iomojo_id 0
track_step_angle_x 10
track_step_angle_y 10
track_move_wait 10
track_speed 255
track_stepsize 40
这个测试将和之前的一样。我们只想启动 motion,并检查它是否能运行和捕捉图像。然而,这一次我们想要使用配置文件和 Linux start 命令,因为它允许我们模拟 Raspberry sPi 的加电。所以继续执行sudo /etc/init.d/motion start这应该开始运动。你应该看到你的相机灯亮了,如果你四处走动,你应该开始看到图像捕捉几乎立即出现在/tmp/motion(或任何你指向 target_dir 的地方)。您还可以通过键入以下命令来检查正在运行的运动进程,从而检查该进程是否正在运行:
$ ps –ef | grep motion
解决纷争
还不工作?回到连接网络摄像头的部分,拔下它,插回,并检查来自dmesg的输出。验证您在dmesg中看到的输出与您在检查您所说的网络摄像头设备时从udev中得到的匹配。运动套件安装正确吗?检查来自apt-get的输出,看它是否做到了;如果没有,请尝试重新安装或尝试以下方法:
$ apt-get ʧ˗reinstall install motion
用motion –s在命令行执行 motion 会运行吗?如果没有,检查屏幕上的消息,这将有助于您了解哪里出错了。
如果都失败了,检查你的运动配置文件。你是不是不小心设置错了一个变量?是不是忘了把/etc/default/motion里的值设置成yes?运动守护程序正在运行,但你看不到图像出现在你给定的输出目录?如果没有,检查文件/var/log/messages和/var/log/syslog,这是来自系统启动的守护进程的消息的存储库,包括 motion。之前屏幕上的输出现在应该在这个文件中。
我在测试这个设置时遇到的一个问题是,motion 守护程序无法写入到/tmp/motion目录,因为这个目录最初是由 root 用户创建的。我在/var/log/syslog中找到了下面一行,它清楚地显示了这个问题。
Mar 24 20:58:22 raspberrypi motion: [1] Error opening file /tmp/motion/01-20150324205822-01.jpg with mode w: Permission denied
为了解决这个问题,我必须更改该目录的权限,以授予“motion”用户启动 motion 守护程序的访问权限。这是通过下面的chown命令完成的
sudo chown motion /tmp/motion/
提醒自己
到目前为止,我们已经连接了一个网络摄像头,配置了网络摄像头,安装了运动检测软件,并将其配置为随着您的树莓 sPi 自动启动。现在我们有一个完全成熟的监控系统,你可以用它来监控你的敌人,并在入侵者进入你的密室时通知你。嗯,差不多了。您现在需要创建一个系统,允许您向自己发送消息,这样当入侵者进入时,您可以收到警报。
为此,我们将利用有史以来最古老、最有效的信息传递系统之一:电子邮件。然而,我们不会去建立我们自己的邮件服务器和域名;这是一个很大的任务,远远超出了我们在本章要做的范围。相反,我们的目标是建立一个轻量级的邮件客户端,将消息转发到邮件服务,然后通过你用来接收电子邮件的任何方便的间谍工具发送给你。既然你理解了这个计划,我们就开始吧。
安装 SSMTP
我们将用来把邮件发送到邮件服务器的应用程序叫做 SSMTP。SSMTP 是一个高度简化的邮件传输代理(MTA ),当系统管理员需要能够从服务器发送邮件时使用,但不需要设置为完全成熟的邮件域。这里的优势应该是显而易见的:一个明显不太密集的设置过程和低得多的开销——所有这些都应该让你尖叫树莓 Pi。
考虑到这些,我们开始吧。首先发出命令下载并安装 SSMTP 应用程序,然后安装它:
$ sudo apt-get install ssmtp
您的输出应该类似于我的:
$ sudo apt-get install ssmtp
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
libgnutls-openssl27
The following NEW packages will be installed:
libgnutls-openssl27 ssmtp
0 upgraded, 2 newly installed, 0 to remove and 71 not upgraded.
Need to get 272 kB of archives.
After this operation, 279 kB of additional disk space will be used.
Do you want to continue [Y/n]?
一旦我们安装了 SSMTP,我们需要配置它。SSMTP 配置文件是/etc/ssmtp/ssmtp.conf。用你最喜欢的文本编辑器打开它,然后开始。
我们需要配置的第一件事是邮件的目的地。大多数阅读这本书的人会有一些不同的和具体的位置,他们希望他们的邮件去。尽管所有优秀的间谍都希望尽可能高效,但我只能处理我面前的事情,所以我们将为每个人配置最通用和免费的选项:Gmail。
因此,我们需要配置邮件要发送到哪里;在 SSMTP,这由mailhub值决定。该值是我们将用来发送出站邮件的域的邮件服务器的 DNS 名称。这个名字传统上是mail.<yourdomain>.<whatever>,但对我们来说将是smtp.gmail.com:587,这是谷歌的 SMTP 服务器。
设置好 Gmail 服务器后,你可能已经注意到我们在末尾加了一个:587。你们当中好学的人会认出这是一个端口号。更细心的人会知道 587 不是 SMTP 的默认端口(它是端口 25)。这是专用于传输层安全性(TLS)电子邮件的端口(SSL 上的安全电子邮件)。这意味着我们需要添加另一对选项来确保我们拥有加密的通信:
UseTLS=YES
UseSTARTTLS=YES
下一个要配置的选项是hostname选项,这是 Raspberry sPi 列出的主机名。如果您有域,请列出 sPi 的主机名。如果没有,就给它一个raspberry.spi之类的。下一个选项应该是FromLineOverride=yes,如果我们愿意,它允许我们在电子邮件上设置“发件人”字段。
最后,最后一组选项与身份验证相关。这里有三个选项需要配置。前两个是最明显的:用户名和密码。所以继续添加AuthUser=username@gmail.com和AuthPass=password。第三个选项有点复杂,是AuthMethod选项,用于指定允许用户向服务器注册的认证方法。我们将为 Google 使用的方法是LOGIN方法。尽管其他邮件服务器可能不要求指定这个,但是在 Google 中我们应该设置AuthMethod=LOGIN。
就是这样;您的配置现在应该看起来像这样:
root=
Mailhub=smtp.gmail.com:587
UseTLS=YES
UseSTARTTLS=YES
Hostname=raspberry.spi
FromLineOverride=yes
AuthUser=username@gmail.com
AuthPass=password
AuthMethod=LOGIN
Note
这是不言而喻的,但是你应该总是有一个安全的根密码。
要做的最后一个更改是保护这些数据,这样除了我们想要的人之外,没有人可以读取该文件。这非常重要,因为你已经把宝贵的 GMail 密码放在文件里了!解决方案是更改权限,这样除了目标用户,没有人可以读取它。执行以下操作:
$ sudo chmod 640 /etc/ssmtp/ssmtp.conf
这将更改该文件,以便只有 root 用户可以访问它,并且只有邮件组的成员可以访问它。
一旦配置了 SSMTP,您需要做的就是调用它来发送电子邮件,并让它发送捕获的...等等。我们需要更多的东西。我们需要一种方法来调用 SSMTP,以便我们可以告诉它将文件发送到我们的电子邮件,并提醒我们注意入侵者。我们需要一个可以从命令行完成所有这些工作的工具。这里最好的工具是一个叫做mutt的工具。
安装和使用 mutt
这个工具是一个基于文本的电子邮件客户端,有一句绝妙的格言“所有的邮件客户端都很烂”。这个就差一点了。”(我们使用它的原因不是很明显吗?与其他邮件客户端相比,mutt的另一个好处是它很乐意发送文件系统中文件的附件——这是我们让 sPi 发送入侵者图像的关键。
现在您知道我们正在安装的是mutt,继续使用以下命令安装它:
$ sudo apt-get install mutt
您的输出应该如下所示:
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
libgpgme11 libpth20 libtokyocabinet9
Suggested packages:
gpgsm gnupg2 urlview mixmaster
The following NEW packages will be installed:
libgpgme11 libpth20 libtokyocabinet9 mutt
0 upgraded, 4 newly installed, 0 to remove and 71 not upgraded.
Need to get 1,985 kB of archives.
After this operation, 7,181 kB of additional disk space will be used.
mutt安装好了吗?很好。正如我前面提到的,mutt被设计成小巧、简单、易于使用和配置——这是崇高的目标。记住这一点,mutt 的设置过程非常简单:我们只需要告诉mutt如何使用我们的 MTA(也就是 SSMTP)。为此,我们需要创建一个隐藏在 Pi 用户主目录中的文件。文件是.muttrc,它将只包含一行:
set sendmail="/usr/sbin/ssmtp""
代替使用文本编辑器,我们将使用一个“欺骗”来做这件事。运行以下命令:
$ echo "set sendmail=\"/usr/sbin/ssmtp\"" > ∼/.muttrc
就这样。
Note
引号前的反斜杠是转义符。
您可以在 root 用户的主目录中查找文件.muttrc并检查其内容。是的,它就在那里,和预期的一模一样。.muttrc文件是一个配置文件,由mutt用来在启动时自动加载重要的配置选项。许多不同的应用程序使用以rc结尾的隐藏文件,所以如果你想知道一个应用程序是如何存储某些配置选项的,可以在你的主目录中查找以句号打头并以rc结尾的文件。
测试警报系统
既然我们已经安装并配置了 SSMTP 和mutt,我们需要对它们进行组合测试。奇怪的是,使用mutt的方法是运行mutt命令。语法相当简单,所以从命令行给自己发一封电子邮件。执行以下命令:
$ echo "the quick brown fox jumps over the lazy dog" | sudo mutt –s "[INTRUDER ALERT] Test of intruder system" <your email>@gmail.com
我知道这是一个很长的命令,但是不要担心,因为我马上会解释它。继续检查你的电子邮件;你应该有一个来自用户根的,如图 10-3 所示!
图 10-3。
E-mail from the Rasperry sPi
现在我将解释语法,以及我们将如何使用它从 sPi 发送警报消息。前面的消息可以分解成几个更小的片段。我使用的基本语法是:
echo <mail content> | mutt –s <subject> <recipient>
你可能想知道echo的用法。您需要生成将作为输出传递的值,然后让管道将其导入mutt,而不是作为参数提供。
Note
通过用引号将整个句子括起来,可以在 shell 命令中包含带有空格的整个句子。您甚至可以在命令中转义引号,以便在引号中创建引号!
我们还需要能够通过电子邮件发送附件。因为它提供了在发出的电子邮件中附加文件的功能。我选择使用mutt来创建 Raspberry sPi 的原因是因为它不仅易于配置,而且还提供了发送附件的能力。
用我们刚刚发送的电子邮件发送附件的语法如下:
echo <mail content> | mutt –s <subject> -a <filename> ˗˗ <recipient>
是的,就这么简单!–a表示附件,–-用于将附件与收件人分开。
解决纷争
一切都按预期进行了吗?如果没有,尝试从头开始配置 SSMTP 和mutt。当您发送电子邮件时,它是否会输出有关登录详细信息的错误?如果是这样,请仔细检查您的用户名和密码。这是关于不支持的登录类型的错误吗?如果是,检查 TLS 设置和AuthMethod设置。你的邮件服务器拼错了吗?它们的尾部是空白吗?即任何条目末尾的空格或制表符。当您更改权限时,您是否将它们移动得太远,以至于现在您无法再读取该文件?
如果您尝试以pi用户的身份发送电子邮件,而没有发送sudo,您也可能会遇到错误,因为pi用户不是您系统上mail组的成员。如果您希望允许pi用户或任何其他用户,您需要使用gpasswd添加他们,语法如下:
$ gpasswd –a <username> mail
好吧,都搞定了?你可以捕捉到入侵者的存在。你可以通过树莓 sPi 来提醒自己。您可以通过 sPi 将捕获的入侵者图像发送给自己。那还剩下什么?全部自动化。
将这一切结合在一起
到目前为止,我们已经完成了以下工作:
- 将网络摄像头连接到树莓 sPi
- 已安装并配置显示器应用程序以使用网络摄像头
- 使用网络摄像头和显示器应用程序作为运动传感器并捕捉图像
- 将 SSMTP 安装并配置为 MTA
- 安装并配置
mutt邮件应用程序以使用 SSMTP - 使用 SSMTP 和
mutt从命令行向我们自己发送电子邮件
剩下的问题是,我们已经通过人工干预完成了大部分工作。我们需要一种解决方案,能够让图像捕获自动触发发送给我们的附有图像的电子邮件。尽管我确信有人已经想出了解决这个问题的软件方案,但是我们没有理由不能自己写一个解决方案!
理解问题
任何软件设计问题的第一步,不管多么小的工作,都是理解软件解决方案的确切需求是什么。让我们从列出我们的目标开始:
- 新图像的捕获应该触发解决方案
- 应发送包含任何新捕获图像的电子邮件
- 应自动运行,无需手动启动
好吧,这似乎是我们需要的解决方案。但是,有了这两个主要要求,还有其他一些事情需要考虑。这些额外要求是:
- 应该只发送新图像
- 应该只发送由运动捕获的图像
- 应用程序应该一直运行,不需要手动启动,就像 motion 一样
好吧,这似乎好一点了;我们现在非常确定我们的软件解决方案应该做什么。但是它应该如何做呢?也许我们应该对我们将要编写的应用程序如何实现其目标有一点具体的说明。
开发应用程序时我们应该考虑的一些事情包括:
- 我们应该发送图像被捕获的时间
- 我们应该定期检查和发送,但是考虑到电子邮件有延迟,半定期检查就足够了
好了,现在我们做饭。这些看起来像是构建我们的应用程序时需要记住的一些好的需求。我们明确了我们想要什么,以及我们应该如何实现它。既然我们确切地知道了我们的应用程序需要什么,我们就可以进入下一步了。
做决定
在确定了我们想要达到的目标后,下一步是决定如何达到目标。所以,第一个决定:我们应该怎么写?嗯,我们在这里想要实现的大部分是对 shell 命令的操作。我们希望列出图像文件,然后在另一个 shell 命令中使用这些图像文件向我们发送电子邮件警报。此外,您在本书的前面学习了 bash,因此它非常适合我们想要开发的内容。
好的,我们知道我们将用什么语言工作。接下来,我们将如何开始这一个?我认为有两种选择,这两种选择都将决定我们的发展方向:
- 一种是从
motion的启动脚本中执行应用程序,因为我们希望它们一起运行。这意味着我们可以确保它们同时运行,并且脚本需要一直运行,然后定期检查。 - 第二个选项是让脚本定期自动执行。这意味着我们不需要启动它并保持脚本永久运行。这也意味着,如果最坏的情况发生,脚本死亡,我们不需要处理,并重新启动它,因为它会自动再次启动。这确实意味着我们需要一些东西来执行计时器上的脚本,但这可以由 cron 守护进程来处理。
所以,我们有两个选择来决定,但是让我们把这个决定推迟一会儿,因为我们需要首先考虑另一件事。
我们将如何处理这些图像?我们又有两个选择:
- 首先是在发送后删除每张图片。这很好,因为这意味着我们可以节省空间,因为我们清理自己。
- 第二种选择是跟踪我们所有的图片,只发送新的图片。这意味着要跟踪我们库存的图片,这样我们才能决定发送哪些图片。
所以,现在你明白了选项,是时候做决定了。我知道这很难决定,所以让我来帮你。不是四个可能的脚本,让我们把它缩小到两个:
- 一个脚本将从
cron运行,将搜索图像,发送它们,然后删除它们 - 一个脚本,将开始与
motion守护进程,将监测所有的文件,保持运行计数,然后识别何时有一个新的图像。
好了,现在我们有了两个工作设计,让我们进入下一步。
设计解决方案
“等等;你有两个解决方案,但你实际上没有选择一个。你这个大怪人。”我听你这么说,这是真的;我没有。因为我们有两种非常不同的方法来实现我们的目标,所以我们觉得最好是两种都涵盖,给你选择,并分享一些指导。所以,我们先来看看两者的共性;首先,它们都需要有一个文件夹的引用,用来存放motion捕获的文件。我们可以把它保存在一个变量中,当我们改变输出文件夹的时候再编辑它,但是要改变两个完整的文件,这需要很大的努力。这不是 Linux 的方式。所以让我们从motion配置文件中加载它,然后完成它。这意味着我们需要两个变量:一个变量将包含motion配置文件,第二个变量我们将动态创建以包含文件位置。使用MOTIONCONF=/etc/motion/motion.conf,包含文件名的变量足够简单。
Note
接下来的所有工作都是以根用户的身份完成的(您可以sudo su获得一个根 shell ),因为正是根用户将产生motion。
下一步是取出变量,最好的方法是结合使用两个命令:一个是grep,它将在包含特定模式的文件中查找任何信息,在本例中是包含行target_dir的任何行,但是我们还需要确保避免注释,所以我们需要获取以target_dir开头的行。这可以通过简单地添加一个额外的符号来实现,这样grep就可以知道我们正在寻找一个以我们想要的值开始的值。这给了我们一个grep "^target_dir" $MOTIONCONF的命令。如果执行此命令,您将看到以下结果:
root @raspberrypi ∼ $ grep "^target_dir" $MOTIONCONF
target_dir /tmp/motion
现在,我们命令的下一个问题出现了:我们需要去掉target_dir部分,这样我们就只有我们想要的位置了。要删除第一部分,我们需要使用awk命令,默认情况下,它会在空白值处分割给定的数据。这是完美的,然后我们只需要打印结果的第二个值。因此,在我们的命令中构建这个,我们得到这个: ''
root@raspberrypi ∼ $ grep "^target_dir" $MOTIONCONF | awk ’{ print $2}’
/tmp/motion
现在剩下的就是将结果放入一个变量中,这是用反勾符号完成的,给我们一个最终的结果:
MOTIONDIR=’ grep "^target_dir" $MOTIONCONF | awk ’{ print $2}’’
现在,有一件事你可能没有考虑到:如果这个目录没有创建,motion 会在捕捉到第一张图片时创建它,但这可能需要几个小时。我们现在就需要它,所以让我们检查一下它是否存在,如果不存在,就创建它。查看目录是否存在的检查是if [ -d < directory name > ]。我们还需要添加一个注释来查看该目录是否不存在,所以在–d前添加一个感叹号,表示不存在。最后,将这个与一个mkdir混合,你应该得到下面的if语句:
if [ ! -d $MOTIONDIR ]; then
mkdir $MOTIONDIR
fi
在创建目录的同时,您需要确保它属于正确的用户。motion守护进程是由 root 运行的,但是这个所有权被传递给了motion,所以您需要给这个命令添加一个chown,它给出了这个值:
if [ ! -d $MOTIONDIR ]; then
mkdir $MOTIONDIR
chown motion $MOTIONDIR
fi
好了,现在我们有了文件所在的目录,我们需要写一些代码来检查它并计算文件的数量。通常,您会认为“好极了,让我们使用ls来列出目录中的文件。”但是这在没有文件的情况下没有帮助,因为ls会给我们一个错误。为此,我们需要使用find命令。找到所有的。jpg 文件,我们需要向find the following添加一对参数:
- 表示不要在任何子目录中进行搜索
–type f告诉它只搜索文件
我还将命令放在一对括号中,这意味着该文件将被视为一个数组。这给了我们这个命令:
LISTFILES=(’find $MOTIONDIR –maxdepth 1 –type f’)
现在,如果有非图像文件,我们还应该添加一个grep来只取出。jpg 文件。一个简单的grep用于任何以。jpg(使用$操作符)应该足够了。这将为我们提供以下信息:
LISTFILES=(’find $MOTIONDIR –maxdepth 1 –type f | grep jpg$’)
现在我们需要使用wc -l命令获得列表中文件的数量。这将列出一个目录中的所有文件,如果我们用-l参数把它传给wc,我们将得到一个给定文件夹中文件的数量。这给了我们下一行:
NUMFILES=’ find $MOTIONDIR -maxdepth 1 -type f | grep jpg$ | wc -l’
我们现在可以编写最后一段两个脚本通用的代码:发送图像文件和消息的mutt邮件程序行。我们发送的原始文件很好,但是我在这里做了一点修改,为附件添加了一个变量名,即变量IMAGEFILE。我还添加了一个新的–F /root/.muttrc选项,强制mutt使用我们创建的根muttrc文件。新邮件行是这样的:
echo -e "Warning,\nAn intruder was detected at ’date’\nPlease see the image attached for details"| mutt –F /root/.muttrc –s "[INTURDER ALERT] Intruder Detected" -a $IMAGEFILE ˗˗ you@gmail.com
如你所见,有点拗口。我添加了一些漂亮的正文,如下所示:
Warning,
An intruder was detected at Sat Sep 15 22:50:32 EST 2012
Please see the image attached for details
您可能会问自己,我是如何在那里获得这些换行符的,以及我是如何在电子邮件中获得非常好的日期和时间输出的。日期和时间来自 shell date命令,我将它放在反勾号中以给出输出。我还添加了一些\n,它们是对换行符的引用,但是只有当你给 echo 一个–e参数来告诉它解释特殊的转义值的时候。现在我们有了一个代码块,让我们从 1 号脚本开始,cron 执行了 run once 脚本。
脚本 1
首先,让我们回顾一下到目前为止我们所拥有的;我们可以得到正确的工作目录中文件的数量。下一步是检查该数字是否显示确实有文件要处理,也就是说> 0。这意味着我们需要下面的if语句:
if [ $NUMFILES -gt 0 ]; then
有了我们的if语句,我们现在应该知道是否有需要紧急发送的文件。现在我们只需要遍历列表,将每个列表作为电子邮件发送,然后删除它。要遍历任何东西,需要使用循环;在这种情况下,我们将使用一个for循环。这个循环将把列表中的每张图片作为它自己的变量分开,允许我们一个接一个地对每张图片采取行动。该循环将如下所示,其中IMAGEFILE是列表中的当前图像;每次for循环再次开始时,该图像变为列表中的下一个图像。当列表中没有更多的图像需要处理时,for循环将会结束。
for IMAGEFILE in $LISTFILES
Note
记得chmod +x你的脚本,以便它可以被执行!
好吧,就这样。我们有所有的代码块,所以让我们组装。最终的脚本应该是这样的:
#!/bin/bash
MOTIONCONF=/etc/motion/motion.conf
MOTIONDIR=’ sudo grep "^target_dir" $MOTIONCONF | awk ’{ print $2}’’
if [ ! -d $MOTIONDIR ]; then
mkdir $MOTIONDIR
chown motion $MOTIONDIR
fi
LISTFILES=(’find $MOTIONDIR -maxdepth 1 -type f | grep jpg$’)
NUMFILES=’ find $MOTIONDIR -maxdepth 1 -type f | grep jpg$ | wc -l’
if [ $NUMFILES -gt 0 ]; then
for IMAGEFILE in $LISTFILES
do
echo -e "Warning,\nAn intruder was detected at ’date’\nPlease see the image attached for details" \
| mutt -s "[INTURDER ALERT] Intruder Detected" \
–F /root/.muttrc \
-a $IMAGEFILE ˗˗ <your email>
rm $IMAGEFILE
done
fi
脚本 2
因为我们已经讨论完了剧本 1,所以让我们开始写剧本 2。这个稍微复杂一点。我们需要做的第一件事是添加一个计数器,它会告诉我们已经处理了多少图像。最初,我们可以将其设置为 0。所以我们用LASTCOUNT=$ NUMFILES来初始化这个变量。下一步是创建一个简单的循环,让应用程序永远运行下去;事实上,这是最简单的一种循环,简单来说就是while true(关于while循环的更多信息,参见第七章)。
现在在循环中,我们需要更新LASTCOUNT和NUMFILES,所以让这些命令再次运行来更新它们的值。我们需要进行比较,看看我们是否添加了新的东西(例如,NUMFILES大于LASTCOUNT)。如果是,我们需要读出最新的文件并发送出去。通常,这听起来像是一个if语句的位置,但在这种情况下,我们将使用一个while循环,因为我们希望在LASTCOUNT大于NUMFILES时执行操作,所以我们的第二个内部while循环是这样的:
while [ $LASTCOUNT -lt $NUMFILES ]
现在我们只需要更新;首先,我们需要给每个新图像一个文件名。谢天谢地,它们是按顺序排列的,因为运动包是按顺序给它们命名的。这意味着我们只需要去掉顶部的 X 来弥补差额。这意味着我们需要一个迭代器值,这样我们就可以计算出前 X 个值。因此,在第二个循环之外但在第一个循环之内创建一个设置为 0 的ITERATOR,所以我们在每一轮都重置它。
现在我们有了这个迭代器,我们可以用它和LISTFILES来提取每个数字。因为我们将LISTFILES视为一个数组,所以我们只需要使用ITERATOR来访问该数组元素。我们需要用一对花括号将整个数组输出括起来,因为这将执行数组解引用并给出输出值:
IMAGEFILE=${LISTFILES[$ITERATOR]}
最后,我们需要增加LASTCOUNT和ITERATOR,这样它们就可以在我们处理每张图像时计数。这是通过以下方式完成的:
LASTCOUNT=’expr $LASTCOUNT + 1’ and ITERATOR=’expr $ITERATOR + 1’
expr函数将给定的值视为数学表达式并返回它们的结果,这在我们想要将值增加 1 时非常理想。
所以,现在我们需要组装每一项代码。当它们放在一起时,应该是这样的:
#!/bin/bash
MOTIONCONF=/etc/motion/motion.conf
MOTIONDIR=’ sudo grep "^target_dir" $MOTIONCONF | awk ’{ print $2}’’
if [ ! -d $MOTIONDIR ]; then
mkdir $MOTIONDIR
chown motion $MOTIONDIR
fi
LISTFILES=’find $MOTIONDIR -maxdepth 1 -type f | grep jpg$’
NUMFILES=’find $MOTIONDIR -maxdepth 1 -type f | grep jpg$ | wc -l’
LASTCOUNT=0
while true
do
LISTFILES=(’find $MOTIONDIR -maxdepth 1 -type f | grep jpg$’)
NUMFILES=’find $MOTIONDIR -maxdepth 1 -type f | grep jpg$ | wc -l’
ITERATOR=0
while [ $LASTCOUNT -lt $NUMFILES ];
do
IMAGEFILE=${LISTFILES[$ITERATOR]}
echo -e "Warning,\nAn intruder was detected at ’date’\nPlease see the image attached for details" \
| mutt –F /root/.muttrc \
-s "[INTURDER ALERT] Intruder Detected" \
-a $IMAGEFILE ˗˗ <your email> LASTCOUNT=’expr $LASTCOUNT + 1’ ITERATOR=’expr $ITERATOR + 1’ done sleep 1
done
测试
所以,让我们来看看这个超级剧本。确保 motion 启动并运行,然后执行您的脚本。
Note
若要取消运行脚本,请按 Ctrl + c 停止执行。这是停止脚本 2 的唯一方法。
您不应该期望看到任何输出,所以只需查看您的电子邮件收件箱(见图 10-4 )。
图 10-4。
One full inbox!
如你所见,这很有效。事实上,它工作得相当好;我有 18 封来自入侵检测系统的未读邮件。完美!现在,我们已经测试了该脚本可以向我们发送来自 motion 的新图像的电子邮件,我们需要配置该脚本,以便它可以自动启动——这是仍未满足的最后一个要求。回过头来看,我们决定以不同的方式启动这两个脚本:脚本 1 将被添加到cron中,脚本 2 将被添加到运动启动脚本中,这样它将与运动一起运行!
对于脚本 1,事情相当简单。cron将自动评估它是否应该每分钟运行一次,所以我们需要做的就是有一个将一直运行的cron作业。所以以 root 用户身份(因为我们想以 root 用户身份运行它),打开带有crontab –e的cron表,并输入以下内容:
* * * * * /root/script1.sh
就是这样;我们没有添加脚本 1 来每分钟从一个crontab条目开始运行。这样我们每分钟都会检查一下/tmp/motion里有没有文件,发给我们然后删除,这就满足了我们所有的要求。
第二个脚本的launch方法需要修改动作/etc/init.d/motion的launch脚本,所以继续打开它作为 root 编辑。任何这些启动脚本的基本格式都有一个大型 case 语句,用于处理要执行的给定操作,如启动、停止、重启或任何其他数量的必需 case。所以找线start,这是我们要增强的动作。在这里,我们可以看到有许多嵌套的检查和准备工作;我们希望我们的脚本只在 motion 之后启动,这是由start - stop - daemon命令调用的。
因此,在这之后,继续添加一个链接到您的脚本;然后在末尾加一个&。“与”符号表示“运行这个脚本,然后让它在后台运行。”如果我们不这样做,启动脚本会认为它的下一个功能是等待脚本结束,但它不会!您最终更新的开始部分应该如下所示:
start)
if check_daemon_enabled ; then
if ! [ -d /var/run/motion ]; then
mkdir /var/run/motion
fi
chown motion:motion /var/run/motion
log_daemon_msg "Starting $DESC" "$NAME"
if start-stop-daemon ˗˗start ˗˗oknodo ˗˗exec $DAEMON -b ˗˗chuid motion ; then
/root/script2.sh &
log_end_msg 0
else
log_end_msg 1
RET=1
fi
fi
;;
一旦你完成了编辑,就去重启你的 Pi;然后重新登录并执行检查,看看脚本是否正在运行!是吗?太棒了,你现在有了自己的全自动树莓 sPi!
$ ps -ef | grep script
root 2058 1 0 11:23 pts/0 00:00:00 /bin/bash /home/pi/script2.sh
解决纷争
我相信您现在已经意识到,在进行软件开发时,有太多的事情可能会出错。所以有足够的空间进行故障排除。这让我给你建议去哪里找有点困难。也就是说,你可以做很多事情来简化诊断。
我开始写脚本的原因是写出每一小段代码,然后添加进去。这是所谓的隔离测试的一个版本,它涉及尽可能多地隔离代码的特定部分,以使用受控输入来执行它,然后评估输出,以查看它们是否如您所愿地工作。
可以想象,一个模块一个模块地做意味着您可以在应用程序成长的过程中测试它的每一点。
下一件事是利用echo命令输出一个工作值或代码中的一个位置。您可以看到应用程序正在处理什么,以及它在代码中的什么位置运行,这让您可以发现意外的值以及软件在什么地方出现了故障。
最后,如果所有其他方法都失败了,将 shell 从#!/bin/bash更改为#!/bin/bash –x。添加–x会将 bash 实例置于调试模式,并输出它经历的每个变量、每个操作和每个更改。虽然可能会有很多输出,但这是查看一个麻烦的应用程序中发生了什么的理想方式。
从这里去哪里
哇哦。我们已经从起点走了很长一段路。我们有:
- 将网络摄像头连接到我们的树莓 sPi
- 已安装并配置显示器应用程序以使用网络摄像头
- 使用网络摄像头和显示器应用程序作为运动传感器并捕捉图像
- 将 ssmtp 安装和配置为 MTA
- 安装并配置
mutt邮件应用程序以使用 SSMTP - 使用 SSMTP 和
mutt从命令行发送电子邮件给我们自己 - 写了两个脚本来自动获取任何新的图像文件,然后使用上述所有内容通过电子邮件发送给我们自己
这是相当大的成就,但是现在呢?作为间谍,你们都知道适应性是成功的关键。我们在这里所经历的应该是一个如何利用 motion、SSMTP和mutt等软件的指南。你现在应该也熟悉了使用dmesg,以及如何定位新加载的设备,并将它们集成到你的系统中。最后,您应该看到如何使用 bash 编写的脚本来填补应用程序堆栈中的空白并解决复杂的问题。那么你在这里能做什么?
-
你可以添加一个无线适配器,这样你就不需要布线,给你一个无线树莓 sPi,你可以藏在最无害的地方。
-
您可以添加一个 USB 电池组,这样就不需要使用电源插座了。
-
您可以在
/tmp之外更改文件存储的目录。这样,您可以将图像保存到磁盘上,以便日后查看。 -
Or you can go full Bond. I’ve taken my inspiration further afield, modified the software to capture full video, and disabled the image capture. I changed the storage location to be away from
/tmpand I’ve attached a USB battery pack. I then added a little tape to hold this all together and mounted the webcam inside a hat (see Figure 10-5).图 10-5。
Maybe I should have invested in a stetson!
摘要
你应该能看懂dmesg的输出,知道udev是怎么工作的。您还应该能够配置运动应用程序、SSMTP 应用程序和mutt应用程序。最后,您应该能够发送具有不同收件人、正文、主题和附件的电子邮件。
十一、Pi 媒体中心
树莓派的美妙之处在于它是一个非常灵活的设备,它的潜在用途几乎是无限的。您可以使用 Pi 做任何事情,它有一系列外围输入端口,可以很好地使用。
您还应该知道,虽然您的 Pi 可以通过标准 HDMI 显示,但设备的功能并不止于此。它可以以 1920 x 1080 的分辨率显示,通常称为 1080P,这是高清的基准水平。你小小的 Raspberry Pi 能够以全高清分辨率显示视频,由于 HDMI 的声音交错,它还可以在视频的同一频道播放音频。这是本章的目标;我们将利用 Pi 的媒体播放功能来创建两种不同的 Pi 媒体中心。一个是视频播放中心,你可以用它在网络上播放视频。它可以连接到你的电视上,并允许你接入互联网观看视频。第二个是无线播放设备,使您能够远程流式播放您的音乐收藏,并通过网络播放。
与 XBMC 的视频
如前所述,树莓派的一大优势是它可以全高清播放,但我们需要一种方式来利用这一点,这就是 XBMC 的用武之地。
XBMC(XBox Media Center 的缩写)最初是作为最初(胖)XBox 的媒体中心而设计的。人们非常喜欢这个项目,后来它被移植到了世界上几乎所有的操作系统上,包括但不限于 Windows、Android、OS X 和 iOS。甚至有一个名为 XMBCbuntu 的成熟的独立版本,它是 Ubuntu 的一个端口,已经安装、预配置了 XBMC,可以开箱即用。鉴于其广泛的用途、开放源代码的特性和易于使用的特性,它已经被移植和派生了很多次,包括 MediaPortal、Plex、Voddlern 和 Boxee。这显示了媒体中心系统有多受欢迎;再举一个例子,Boxee 制造了一款名为 Boxee Box 的小型设备,售价高达 200 美元。我们正在创造的是一个同样强大的工具,而且只需要 35 美元——圆周率的价格。既然你们都对媒体中心光明灿烂的未来感到兴奋,是时候好好利用它了。
您已经读到了这本书的结尾,所以是时候从应用程序源代码开始进行一次正确的 Linux 安装了。虽然大多数应用程序都是通过apt-get预打包的,但也有一些不是这样,它们需要编译。从源代码安装 XBMC 是一个有点复杂的过程,非常耗时。我们选择从源代码编译它,因为它不仅可以帮助您完成在 Linux 中运行应用程序的一种更复杂的方法,而且还意味着我们的 XBMC 安装针对我们的系统进行了优化,因为我们已经在自己的系统上构建了它。历史上,从源代码进行编译被认为是一个艰巨的过程,但是随着使用 Linux 的人数的增长,对简单易用的安装工具的需求也在增长,预编译二进制安装系统如apt-get也在兴起。但是和所有事情一样,有时使用预编译并不如从头开始,随着时间的推移,编译工具已经发展起来,变得更加容易使用。当有人指导你完成这个过程时,也更容易做到——这就是本书的全部内容。
所以让我们开始吧。首先,我已经离开了 Raspbian 的主要版本,转而使用 Raspbian 的一个稍微精简的版本,名为 Pisces,可以从 Raspbian 的 www.raspbian.org/PiscesImages 获得。我用双鱼座,因为它已经被削减,不包括太多的开销,这意味着更多的权力做我们想做的事情:播放电影!下载并安装这个映像到 SD 卡上(你需要一个 4 GB 的空间),然后启动并把操作系统连接到互联网上,这样你就可以使用它了。默认用户是raspbian,密码也是raspbian,也是 root 密码。
OSMC
让 XBMC 在您的 Pi 上工作有一个简单得多的方法:使用一个名为 OSMC 的 Raspbian 预构建版本(以前的 RaspMC)。你可以下载一个 OSMC 的安装程序,然后把它放到 SD 卡上,就像你在 Raspbian 上做的那样。你可以从 https://osmc.tv/ 下载这张图片。此安装非常简单,需要 15-25 分钟。您只需将您的 Pi 连接到您的网络,打开它,然后安装程序就会运行。它会从网上下载所有需要的东西,然后自己安装。这是目前为止让 XBMC 在你的 Pi 上运行的最简单的方法。对于那些选择使用 OSMC 的人,你可以跳到本章的“开始和使用 XBMC”一节。
Note
如果ifconfig缺失,使用apt-get安装net-tools包。更多关于apt-get的信息,请参见第三章。
一旦你进入了操作系统,是时候发出一些命令并开始安装 XBMC 了。这是一个非常漫长的过程:编译器比使用apt-get要慢得多,因为apt-get安装的所有软件都是预编译的,因此省去了一些步骤。在这种情况下,编译需要大约 12 个小时——是的,几个小时,半天。我发现最好让最终编译通宵运行,这样我就不会忍不住一坐就是几个小时。
由于 ARM 处理器的性质和工作速度,这个过程需要很长时间。这意味着编译需要更长的时间,但我们可以在更低的功率水平上做同样多的工作。
要构建的设置
让我们从构建开始。第一步是确保我们可以将尽可能多的能力和内存转移到编译器上。在核心 Raspbian 中,我们使用了rapsi-config命令,但是 Pisces 没有这个控制脚本,所以您必须手动更改它,用不同的文件替换start.elf文件,这将改变系统资源的分配方式。运行以下命令:
$ sudo cp /boot/arm224_start.elf /boot/start.elf
这将把分配给系统 224 MB 和分配给显卡 32 MB 的版本复制到系统中使用。现在,我们需要在系统中注册这一配置更改,然后通过发出以下两个命令重新启动,使更改生效:
$ sudo rpi-update
$ sudo reboot
一旦您的系统重新启动,并且备份并运行,最好升级操作系统,以确保它运行的是最新版本的软件。为此,我们将利用apt-get,告诉它用来自互联网的最新版本的配置更新自己,然后升级您系统上所有可用的软件包。为此,发出以下命令:
$ sudo apt-get update
$ sudo apt-get upgrade
这个执行需要一点时间,因为它需要下载、解包和替换大量的系统组件。所以让它运行起来,然后去喝杯咖啡;回来的时候应该就完成了,可以继续下一步了。
Note
其中一些软件包可能已经安装在您的系统上。我们包括它们,因为它们可能不是为每个人安装的。
下一步是安装软件包,给我们编译的能力;它们包括基本的构建工具、自动配置工具、压缩和解压缩工具等等。要安装这些工具,请运行以下命令:
$ sudo apt-get install build-essential autoconf ccache gawk gperf mesa-utils zip unzip
Reading package lists... Done
Building dependency tree
Reading state information... Done
build-essential is already the newest version.
The following packages were automatically installed and are no longer required:
libcdio-cdda0 libcdio-paranoia0 libcdio10 libcelt0-0 libdb4.8 librpmio2
Use ’apt-get autoremove’ to remove them.
The following extra packages will be installed:
automake autotools-dev libglew1.7 libsigsegv2
Suggested packages:
autoconf2.13 autoconf-archive gnu-standards autoconf-doc libtool gettext distcc gawk-doc glew-utils
The following NEW packages will be installed:
autoconf automake autotools-dev ccache gawk gperf libglew1.7 libsigsegv2 mesa-utils
The following packages will be upgraded:
unzip zip
2 upgraded, 9 newly installed, 0 to remove and 187 not upgraded.
Need to get 2,647 kB/3,174 kB of archives.
After this operation, 7,143 kB of additional disk space will be used.
Do you want to continue [Y/n]?
一旦您安装了这些基本的软件包,就可以继续进行更大的安装工作了。我们现在需要安装一些软件包,这些软件包将安装视频和解码器库以及专门的图形库。除了所有这些之外,您还需要安装一些其他的软件包,以便能够远程连接到 XBMC。这个命令非常长,所以我建议您从 Apress 网站下载源代码。该包中有一个脚本将为您执行这些命令。安装如此庞大数量的软件包的命令如下:
$ sudo apt-get install autotools-dev comerr-dev dpkg-dev libalsaplayer-dev \
libapt-pkg-dev libasound2-dev libass-dev libatk1.0-dev \
libavahi-client-dev libavahi-common-dev libavcodec-dev libavformat-dev \
libavutil-dev libbison-dev libbluray-dev libboost1.49-dev \
libbz2-dev libc-dev-bin libc6-dev libcaca-dev libcairo2-dev \
libcdio-dev libclalsadrv-dev libcrypto++-dev libcups2-dev libcurl3-gnutls-dev \
libdbus-1-dev libdbus-glib-1-dev libdirectfb-dev libdrm-dev libegl1-mesa-dev \
libelf-dev libenca-dev libept-dev libevent-dev libexpat1-dev libflac-dev \
libfontconfig1-dev libfreetype6-dev libfribidi-dev libgconf2-dev \
libgcrypt11-dev libgdk-pixbuf2.0-dev libgl1-mesa-dev libgles2-mesa-dev \
libglew-dev libglewmx-dev libglib2.0-dev libglu1-mesa-dev \
libgnome-keyring-dev libgnutls-dev libgpg-error-dev libgtk2.0-dev libhal-dev \
libhunspell-dev libice-dev libicu-dev libidn11-dev libiso9660-dev \
libjasper-dev libjbig-dev libjconv-dev libjpeg8-dev libkrb5-dev \
libldap2-dev libltdl-dev liblzo2-dev libmad0-dev libmicrohttpd-dev \
libmodplug-dev libmp3lame-dev libmpeg2-4-dev libmysqlclient-dev \
libncurses5-dev libnspr4-dev libnss3-dev libogg-dev libopenal-dev \
libp11-kit-dev libpam0g-dev libpango1.0-dev libpcre++-dev libpcre3-dev \
libpixman-1-dev libpng12-dev libprotobuf-dev libpthread-stubs0-dev \
libpulse-dev librtmp-dev libsamplerate0-dev \
libsdl-image1.2-dev libsdl1.2-dev libslang2-dev \
libsm-dev libsmbclient-dev libspeex-dev \
libsqlite3-dev libssh-dev libssh2-1-dev libssl-dev libstdc++6-4.6-dev \
libtagcoll2-dev libtasn1-3-dev libtiff4-dev libtinfo-dev libtinyxml-dev \
libts-dev libudev-dev libv8-dev libva-dev libvdpau-dev \
libvorbis-dev libvpx-dev libwebp-dev libwibble-dev \
libx11-dev libx11-xcb-dev libxapian-dev libxau-dev \
libxcb-glx0-dev libxcb-render0-dev libxcb-shm0-dev \
libxcb1-dev libxcomposite-dev libxcursor-dev libxdamage-dev \
libxdmcp-dev libxext-dev libxfixes-dev libxft-dev libxi-dev \
libxinerama-dev libxml2-dev libxmu-dev libxrandr-dev \
libxrender-dev libxslt1-dev libxss-dev libxt-dev \
libxtst-dev libxxf86vm-dev libyajl-dev libzip-dev linux-libc-dev \
lzma-dev mesa-common-dev python-dev python2.7-dev x11proto-composite-dev \
x11proto-core-dev x11proto-damage-dev x11proto-dri2-dev x11proto-fixes-dev \
x11proto-gl-dev x11proto-input-dev x11proto-kb-dev x11proto-randr-dev \
x11proto-record-dev x11proto-render-dev x11proto-scrnsaver-dev \
x11proto-xext-dev x11proto-xf86vidmode-dev x11proto-xinerama-dev xtrans-dev \
zlib1g-dev
这份包裹清单末尾有许多斜线;它们是换行符,表示应该执行当前的命令,然后会有另一行命令跟在后面。当你需要把长命令分成很多行时,换行符非常有用,就像我在这里做的那样。这个命令需要一段时间来运行,因为有大量的软件包需要下载和安装。所以执行这个命令,去做晚饭,然后回来。
一旦你安装了所有这些软件包,你需要复制一些特殊的文件到适当的位置,并创建其他链接到正确位置的文件,这样它们就可以被使用了。同样,它们将包含在我们创建的脚本中,以帮助简化这些命令的执行。
第一个是将 VideCoreIV include 文件从 Raspberry Pi 固件复制到/usr/include中。该目录是一个特殊的目录,编译器将从该目录中搜索要包含在构建中的库和文件。要将所有这些文件复制到正确的位置,请执行以下命令:
$ sudo cp -R /opt/vc/include/* /usr/include
$ sudo cp /opt/vc/include/interface/vcos/pthreads/* /usr/include/interface/vcos
现在,除了将这些文件复制到适当的位置之外,我们还需要将一些文件正确地链接到正确的位置,以便它们可以被读取。在上一个步骤中,我们复制了主要是源代码的包含文件,这次我们需要将固件的预编译部分链接到正确的位置,以便编译器在编译时读取。我们不是复制,而是链接,因为我们很乐意使用文件的当前位置并节省一些空间。运行以下命令:
$ sudo ln -fs /opt/vc/lib/libEGL.so /usr/lib/libEGL.so
$ sudo ln -fs /opt/vc/lib/libEGL.so /usr/lib/arm-linux-gnueabihf/libEGL.so
$ sudo ln -fs /opt/vc/lib/libEGL.so /usr/lib/arm-linux-gnueabihf/libEGL.so.1
$ sudo ln -fs /opt/vc/lib/libEGL_static.a /usr/lib/libEGL_static.a
$ sudo ln -fs /opt/vc/lib/libEGL_static.a /usr/lib/arm-linux-gnueabihf/libEGL_static.a
$ sudo ln -fs /opt/vc/lib/libGLESv2.so /usr/lib/libGLESv2.so
$ sudo ln -fs /opt/vc/lib/libGLESv2.so /usr/lib/arm-linux-gnueabihf/libGLESv2.so
$ sudo ln -fs /opt/vc/lib/libGLESv2.so /usr/lib/arm-linux-gnueabihf/libGLESv2.so.2
$ sudo ln -fs /opt/vc/lib/libGLESv2_static.a /usr/lib/libGLESv2_static.a
$ sudo ln -fs /opt/vc/lib/libGLESv2_static.a /usr/lib/arm-linux-gnueabihf/libGLESv2_static.a
$ sudo ln -fs /opt/vc/lib/libbcm_host.so /usr/lib/libbcm_host.so
$ sudo ln -fs /opt/vc/lib/libbcm_host.so /usr/lib/arm-linux-gnueabihf/libbcm_host.so
$ sudo ln -fs /opt/vc/lib/libvchiq_arm.a /usr/lib/libvchiq_arm.a
$ sudo ln -fs /opt/vc/lib/libvchiq_arm.a /usr/lib/arm-linux-gnueabihf/libvchiq_arm.a
$ sudo ln -fs /opt/vc/lib/libvchiq_arm.so /usr/lib/libvchiq_arm.so
$ sudo ln -fs /opt/vc/lib/libvchiq_arm.so /usr/lib/arm-linux-gnueabihf/libvchiq_arm.so
$ sudo ln -fs /opt/vc/lib/libvcos.a /usr/lib/libvcos.a
$ sudo ln -fs /opt/vc/lib/libvcos.a /usr/lib/arm-linux-gnueabihf/libvcos.a
$ sudo ln -fs /opt/vc/lib/libvcos.so /usr/lib/libvcos.so
$ sudo ln -fs /opt/vc/lib/libvcos.so /usr/lib/arm-linux-gnueabihf/libvcos.so
Note
我们发现,这些链接可以被其他进程删除,有时通过重新启动;如果有,您需要重新创建它们。
现在,您已经将所有文件链接到正确的位置,接下来获取源代码。使用以下命令将目录更改为您的主目录:
$ cd ∼
如果您不能键入波浪号(∼),您可以尝试使用dpkg-reconfigure keyboard-configuration重新配置 Pi 键盘布局,然后重新启动 Pi。你也可以只使用cd而不使用参数,因为它也会带你到你的主目录。波浪号只是一个引用当前用户主目录的符号。
现在您已经进入了您的主目录,是时候下载源代码了,这样您就可以使用它并正确地编译一切。令人欣慰的是,一个现代工具的出现使得下载源代码变得更加容易:Git,它是以 Linux 内核的 Linus Torvalds 命名的。Git 用于源代码管理和版本控制;所有用户都可以下载一组源代码的当前源代码版本,并将修改提交回中央存储库。
Note
这意味着我们总是下载最新的版本,但是如果 Git 中的当前版本有问题,我们可能会得到一个不太稳定的版本。大多数开发人员努力让他们的 Git 仓库保持良好的工作状态,但是这是需要注意的。
此时,我们要做的就是将源代码下载到我们的主目录中来使用它。为此,使用git命令,告诉它将源代码库克隆到系统上。我们还在命令中添加了–-depth 1,表示我们只想克隆源代码的最近 1 次修订(代码的绝对最新版本),避免获得大量额外的和不需要的历史代码。
通过运行以下命令启动克隆:
$ git clone ˗˗depth 1 git://github.com/xbmc/xbmc-rbp.git
Cloning into ’xbmc-rbp’...
remote: Counting objects: 35172, done.
remote: Compressing objects: 100% (22895/22895), done.
remote: Total 35172 (delta 15265), reused 27885 (delta 10698)
Receiving objects: 100% (35172/35172), 158.26 MiB | 385 KiB/s, done.
Resolving deltas: 100% (15265/15265), done.
既然我们已经克隆了 XBMC 的源代码,我们需要开始构建应用程序。这是迄今为止耗时最长的部分。将目录更改为新创建的xbmc-rbp目录,因为我们还需要完成最后几个步骤。
使用 Sed 和正则表达式更改文件
在我们开始构建我们的 XBMC 应用程序之前,我们需要对源代码做一些小的调整,以便它按照我们想要的方式编译。我们将使用名为 Sed(流编辑器的缩写)的工具,而不是手动进行这些更改。顾名思义,它接受一个文本流,然后对该文本进行编辑。Sed 的棘手之处在于它使用了一种高度专业化的语言,称为正则表达式,用于执行相当于查找和替换的功能。
正则表达式是从验证一组给定的数据以查看它是否符合给定的标准并在找到给定的例子时进行编辑的需要中发展而来的。虽然在编辑文本时,简单的查找和替换对于大多数人来说已经足够了,但是当您只想编辑给定句子中以 T 开头的第三个字母的单词时,如何执行查找和替换呢?电子邮件可能是正则表达式最简单的例子之一。您希望确认一个给定的字符串是一封有效的电子邮件:一封电子邮件将包含一个用户名(它来自谁)、一个域(它来自哪里,例如 Hotmail 或 Gmail),并且在它们之间将有一个 at ( @)符号。好的,我们可以只用一个通配符来实现,比如*。所以看起来像*@*的东西会是一封电子邮件,对吗?我们用来表示任何东西的*会拾取任何东西。甚至空格、数字、奇怪的符号等等。因此,我们需要一种方法来挑选由一串有效的电子邮件字符(字母、数字、句点、下划线)组成的内容,然后是@,,最后是有效的域。这将是一个字母集合,后跟一个句点,然后可能是另一组(或几组)字母。描述这些是令人疲惫的,这就是为什么我们有专门的语言来执行它们。
现在您已经理解了我们想要实现的目标,运行下面两个命令来修改文件tools/rbp/setup-sdk.sh。这些sed命令利用了–i选项,它表示编辑给定的文件:
$ sed -i ’s/USE_BUILDROOT=1/USE_BUILDROOT=0/’ tools/rbp/setup-sdk.sh
$ sed-I ' s/tool chain = /usr /local /BCM-gcc/tool chain = /usr/' tools/RBP/setup-SDK . sh。这些命令将变量USE_BUILDROOT从值1更改为值0,并使用TOOLCHAIN=/usr替换短语TOOLCHAIN=/usr/local/bcm-gcc的任何实例。编辑完tools/rbp/setup-sdk.sh文件后,您应该使用以下命令执行它:
$ sudo sh tools/rbp/setup-sdk.sh
该命令将生成一个 makefile,但不会在屏幕上显示任何内容。一旦完成,就该编辑新创建的tools/rbp/depends/xbmc/Makefile。然后,您需要做的就是在文件上运行最后一个sed,将一个#添加到任何cd $(SOURCE); $(CONFIGURE)实例的开头:
$ sed -i ’s/cd $(SOURCE); $(CONFIGURE)/#cd $(SOURCE); $(CONFIGURE)/’ tools/rbp/depends/xbmc/Makefile
$ sudo sed -i ’s/#include "vchost_config.h"/#include "linux\/vchost_config.h"/’ \ /usr/include/interface/vmcs_host/vcgencmd.h
$ sed -i ’s/-DSQUISH_USE_SSE=2 -msse2//’ lib/libsquish/Makefile.in
$ sed -i ’s/-DSQUISH_USE_SSE=2 -msse2//’ lib/libsquish/Makefile
我们所做的是改变我们的系统编译 XBMC 软件的方式,让它使用我们的一些系统库,而不是使用那些可以在 XBMC 源代码中找到的系统库。
既然 Makefile 已经创建好了,现在是编译的时候了!
编译源代码
大多数编译使用一个非常简单的逻辑:运行命令./configure来生成一个配置文件,它知道系统的组成。这会生成一个名为 makefile 的文件。这个文件使用稍微专业一点的语言,描述了对集合进行编译的方式。它本身不是一个执行代码的脚本;它是 make 应用程序将使用的方向的集合。
不幸是,这个编译器稍微高级一些。在运行配置和编译之前,我们需要使我们的配置工具与我们试图进行的设置相匹配。这需要一点时间来执行,所以开始吧,再喝一杯。
要执行的命令如下:
$ make -C tools/rbp/depends/xbmc/
该命令将在目录tools/rbp/depends/xbmc/中运行 make,这将生成配置文件。这个输出很长,但是当它成功完成时,您应该在控制台窗口上看到类似这样的内容:
examples/Makefile.am: installing ’./depcomp’
Makefile.am: installing ’./INSTALL’
autoreconf: Leaving directory ’lib/libdvd/libdvdnav’
Please (re)run configure...
#cd ../../../../; ./configure ˗˗prefix=/opt/xbmc-bcm/xbmc-bin ˗˗build=i686-linux ˗˗host=arm-bcm2708-linux-gnueabi ˗˗enable-gles ˗˗disable-sdl ˗˗disable-x11 ˗˗disable-xrandr ˗˗disable-openmax ˗˗disable-optical-drive ˗˗disable-dvdcss ˗˗disable-joystick ˗˗disable-debug ˗˗disable-crystalhd ˗˗disable-vtbdecoder ˗˗disable-vaapi ˗˗disable-vdpau ˗˗disable-pulse ˗˗disable-projectm ˗˗with-platform=raspberry-pi ˗˗disable-optimizations ˗˗enable-rpi-cec-api
#cd ../../../../; make -j 1
#cd ../../../../; make install
make: Leaving directory ’/home/raspbian/xbmc-rbp/tools/rbp/depends/xbmc’
既然配置实用程序的编译已经完成了执行配置的时间。这个configure命令非常长,同样,您可以在 Apress 源代码库中找到执行该命令的代码,这个configure命令是:
$ ./configure ˗˗prefix=/usr ˗˗build=arm-linux-gnueabihf ˗˗host=arm-linux-gnueabihf \
˗˗localstatedir=/var/lib ˗˗with-platform=raspberry-pi ˗˗disable-gl ˗˗enable-gles \
˗˗disable-x11 ˗˗disable-sdl ˗˗enable-ccache ˗˗enable-optimizations \
˗˗enable-external-libraries ˗˗disable-goom ˗˗disable-hal ˗˗disable-pulse \
˗˗disable-vaapi ˗˗disable-vdpau ˗˗disable-xrandr ˗˗disable-airplay \
˗˗disable-alsa ˗˗enable-avahi ˗˗disable-libbluray ˗˗disable-dvdcss \
˗˗disable-debug ˗˗disable-joystick ˗˗enable-mid ˗˗disable-nfs ˗˗disable-profiling \
˗˗disable-projectm ˗˗enable-rsxs ˗˗enable-rtmp ˗˗disable-vaapi \
˗˗disable-vdadecoder ˗˗disable-external-ffmpeg ˗˗disable-optical-drive
为configure命令指定多个参数,这些参数指定了安装的位置(˗˗prefix=/usr)、要构建的架构(˗˗build=arm-linux-gnueabihf)、保存其运行文件的位置(˗˗localstatedir=/var/lib)和平台(˗˗with-platform=raspberry-pi),以及一系列禁用和电子邮件选项,以删除 CD 驱动器和操纵杆等功能,并启用优化和 Avahi 外围设备自动检测等功能。最终,当命令执行完毕时,屏幕上的输出应该如下所示:
XBMC Configuration:
Debugging: No
Profiling: No
Optimization: Yes
Crosscomp.: No
target ARCH: arm
target CPU: arm1176jzf-s
OpenGLES: Yes
ALSA: No
DBUS: Yes
VDPAU: No
VAAPI: No
CrystalHD: No
VDADecoder: No
VTBDecoder: No
OpenMax: No
Joystick: No
XRandR: No
GOOM: No
RSXS: Yes
ProjectM: No
Skin Touched: No
X11: No
Bluray: No
TexturePacker:Yes
MID Support: Yes
ccache: Yes
ALSA Support: No
PulseAudio: No
HAL Support: No
DVDCSS: No
Avahi: Yes
Non-free: Yes
ASAP Codec: No
MySQL: Yes
Webserver: Yes
libRTMP support: Yes
libsmbclient support: Yes
libnfs client support:No
libafpclient support: No
AirPLay support: No
AirTunes support: No
Optical drive: No
libudev support: Yes
libusb support: No
libcec support: No
libmp3lame support: Yes
libvorbisenc support: Yes
libcap support: No
External FFmpeg: No
prefix: /usr
该配置指定了我们在安装中要求的所有标志,旨在充分利用 Raspberry Pi。现在,我们已经完成了实际编译的配置。这个命令本身对于它要做的事情来说非常虎头蛇尾:告诉系统花接下来的 12 个小时为我们的系统生成代码。与这个编译要运行多长时间相比,所有这些花费一点时间的工作根本不算什么。所以准备好,执行这个简单的四个字母的命令m a k e:
$ make
如果您看到类似下面这样的行,请不要惊慌:
/tmp/ccGvUe1g.s:507: Warning: swp{b} use is deprecated for this architecture
唯一会停止编译的是一个严重错误或成功。这些警告与 XBMC 编译中使用的一些函数有关,这些函数对我们的 Pi 来说有点老了。编译成功后,您应该会看到以下内容:
XBMC built successfully
这表明我们已经成功地构建了 XBMC,可以进行这个过程中的最后一步了,那就是安装我们新编译的软件。make 系统实际上也会负责安装。要安装,您只需运行make install,它会将所有新编译的二进制文件复制到您操作系统中的正确位置。您需要给它加上前缀sudo,因为我们要复制的位置(/usr)也是一个系统位置,只有 root 用户被授予写权限。您的输出应该如下所示:
$ sudo make install
Copying XBMC binary to /usr/lib/xbmc/xbmc.bin
You can run XBMC with the command ’xbmc’
Copying support and legal files...
Done!
Copying system files to /usr/share/xbmc
我们完了。虽然它很长,需要一点点工作来开始,但实际的编译过程相对来说是没有痛苦的,你知道,除了等待的痛苦。现在 XBMC 已经安装好了,我们该如何使用它呢?
解决纷争
在我们开始运行 XBMC 之前,我们应该先看看您可能会遇到的一些问题。这些步骤中的大部分应该会自行完成,因为这种设置是通用的,可以在任何 Pi 上工作,因为它们都共享相同的硬件。如果你有疑问,删除 xbmc-rbp 目录并重新开始。确保您完整地执行了副本和链接。我发现在进行 git 克隆时,有些东西有时会卡住而不能移动。
在这种情况下,最好使用 Ctrl + C 停止当前作业,删除目录,重新启动,然后重新开始。在编译和安装阶段最好从系统中移除外围设备,因为太多的外围设备会导致我的系统出现负载问题。此外,您应该确保您的命令输出(如configure)与给定的相匹配,因为这些标志在编译时可以发挥更大的作用,并为您省去一个令人头疼的问题和另一个 12 小时的编译工作。最后,确保所有的apt-get都成功运行并完成,因为这些包需要提供您的 Pi 在构建 XBMC 时将使用的库。
启动和使用 XBMC
既然我们已经完成了大型编译过程,是时候启动 XBMC 了!不过,首先,我们需要重置之前设置的选项,将更多的内存放入系统 RAM。我们将需要去图形设备,因为我们想做一些严重的显示工作与 XBMC。执行以下命令来切换 Pi 引导系统:
$ sudo cp /boot/arm128_start.elf /boot/start.elf
返回并检查前面提到的链接文件是否正确。现在我们还可以对/boot/config.txt文件进行一些修改,因为它控制了 Pi 的底层硬件如何运行。要做的最简单的改变是添加行disable_overscan=1,因为它将消除进行过扫描处理的需要,因为过扫描处理将使我们回放的视频量更大,从而消耗更多资源。完成这些更改后,发出以下命令,最后一次重新配置并重新启动 Pi:
$ sudo rpi-update
$ sudo reboot
现在,您已经将设置更改回 50/50 资源分配,通过以 root 用户身份登录并发出以下命令来启动 XBMC:
$ /usr/lib/xbmc/xbmc.bin
你的屏幕会定格片刻,图 11-1 会问候你。
图 11-1。
XBMC boot screen
你应该会看到 XBMC 菜单,看起来如图 11-2 。
图 11-2。
XBMC main menu
在主菜单中,有选择不同播放类型的选项,XBMC 是一个完全图形化的系统,当你在其中时,它会为你提供获取文件的选项和位置。只要您的媒体可以在网络上访问,XBMC 应该能够访问它并播放它!现在关于回放的话题,你可能会坐在那里想,“我会一直用这个键盘来回放吗?”答案是响亮的不!有两种解决方案:
- 购买一个 USB 遥控器,并将其连接到您的 Pi。
- 第二种更偷偷摸摸:用你的智能手机!
大多数智能手机都有下载 XBMC 遥控应用程序的功能,只需与 XBMC 系统配对即可运行。为此,我们需要在 XBMC 内启用两个选项,以允许它接收远程控制。进入“设置”菜单,然后进入“服务”,将遥控器设置更改为“允许其他系统上的程序控制 XBMC”一旦你允许远程控制,你需要进入网络服务器并设置“允许通过 HTTP 控制 XBMC”;您还应该继续设置用户名和密码,这样只有拥有密码的人才能控制您的 XMBC 实例,而不是网络上任何使用 XBMC 应用程序的人!
一旦您启用了这些远程控制选项,只需从您喜爱的应用程序商店下载应用程序,然后在应用程序中设置选项即可。你应该只需要给应用程序你的 Pi 的本地地址,你可以通过系统➤系统信息菜单看到,设置端口为 8080,并提供 XBMC 的实例名和用户名/密码,如图 11-3 所示。
图 11-3。
XBMC remote application
一旦你给出了所有的细节,你的手机应该变成你的 XBMC 实例的遥控器!配有一整套方向按钮和回放控制,如图 11-4 所示。
图 11-4。
XBMC remote in action!
靴子上的 XBMC
虽然到目前为止我们已经手动启动了 XBMC,但大多数人会希望它自动发生,因为你每次想要启动它时都需要将键盘插入媒体中心,这有什么意义呢?
下面是一个简单的start脚本,它将允许您使用start脚本执行 XBMC。在文件/etc/init.d/xbmc中创建这个文件(像所有其他长文件一样,它可以在本书的 press 库中找到):
#! /bin/sh
### BEGIN INIT INFO
# Provides: xbmc
# Required-Start: $all
# Required-Stop: $all
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start XBMC
# Description: Start XBMC
### END INIT INFO
DAEMON=/usr/bin/xinit
DAEMON_OPTS="/usr/lib/xbmc/xbmc.bin"
NAME=xbmc
DESC=XBMC
RUN_AS=root
PID_FILE=/var/run/xbmc.pid
test -x $DAEMON || exit 0
set -e
case "$1" in
start)
echo "Starting $DESC"
start-stop-daemon ˗˗start -c $RUN_AS ˗˗background ˗˗pidfile $PID_FILE ˗˗make-pidfile ˗˗exec $DAEMON ˗˗ $DAEMON_OPTS
;;
stop)
echo "Stopping $DESC"
start-stop-daemon ˗˗stop ˗˗pidfile $PID_FILE
;;
restart|force-reload)
echo "Restarting $DESC"
start-stop-daemon ˗˗stop ˗˗pidfile $PID_FILE
sleep 5
start-stop-daemon ˗˗start -c $RUN_AS ˗˗background ˗˗pidfile $PID_FILE ˗˗make-pidfile ˗˗exec $DAEMON ˗˗ $DAEMON_OPTS
;;
*)
echo "Usage: /etc/init.d/$NAME{start|stop|restart|force-reload}" >&2
exit 1
;;
esac
exit 0
创建该文件后,运行以下命令使其可执行,并将其加载到 Pi 的引导进程中:
$ sudo chmod +x /etc/init.d/xbmc
$ sudo update-rc.d xbmc defaults
现在继续并重新启动您的系统;它会自动把你带到 XBMC!恭喜你;至此,您应该已经拥有了一个功能齐全的 XBMC 实例,并且可以使用 smartphone remote!
解决纷争
因为您成功地从源代码编译,所以启动和运行您的 XBMC 实例应该没有任何问题。首先要检查的是编译确实完全完成了,安装也是如此。他们是两个最有可能的罪犯。如果启动 XBMC 实例,您可能会看到如下警告:
libEGL warning: DRI2: xcb_connect failed
如果这样做,您必须重新运行以前的复制和链接命令。此问题与无法加载这些库文件有关。
使用 Airplay 播放流媒体音乐
人们通常希望将 Raspberry Pi 用作流媒体音乐系统,这意味着它连接到一组扬声器,可以远程控制,并从中央控制系统向其传输音乐。已经有大量的系统可以进行这种播放,但对我们来说,计划是利用苹果 AirPlay 协议。你可以继续在双鱼座工作,或者你可以回复到最初的拉斯扁。这种安装方式在两种设备上都是一样的。
这种设置比视频更新容易得多;我们仍然需要做一些编译工作,但是我们不需要运行./configure,因为活动的部分要少得多。此外,我们希望能够播放音频到给定的设备,所以你需要确保你有扬声器连接。
首先要做的是安装以下前驱包:
$ sudo apt-get install build-essential libssl-dev libcrypt-openssl-rsa-perl libao-dev libio-socket-inet6-perl libwww-perl avahi-utils pkg-config alsa-utils libwww-perl avahi-utils
Reading package lists... Done
Building dependency tree
Reading state information... Done
build-essential is already the newest version.
libio-socket-inet6-perl is already the newest version.
libio-socket-inet6-perl set to manually installed.
libssl-dev is already the newest version.
libwww-perl is already the newest version.
libwww-perl set to manually installed.
pkg-config is already the newest version.
pkg-config set to manually installed.
The following packages were automatically installed and are no longer required:
libcdio-cdda0 libcdio-paranoia0 libcdio10 libcelt0-0 libdb4.8 librpmio2
Use ’apt-get autoremove’ to remove them.
The following extra packages will be installed:
alsa-base avahi-daemon libao-common libao4 libavahi-core7 libcrypt-openssl-bignum-perl libdaemon0 libnss-mdns
Suggested packages:
alsa-oss oss-compat avahi-autoipd libaudio2 libesd0 libesd-alsa0
The following NEW packages will be installed:
alsa-base alsa-utils avahi-daemon avahi-utils libao-common libao-dev libao4 libavahi-core7 libcrypt-openssl-bignum-perl libcrypt-openssl-rsa-perl libdaemon0
libnss-mdns
0 upgraded, 12 newly installed, 0 to remove and 139 not upgraded.
Need to get 1,699 kB of archives.
After this operation, 3,702 kB of additional disk space will be used.
Do you want to continue [Y/n]?
一旦你安装了所有这些软件包,加载声音模块到系统中来利用它。要加载一个模块,使用modprobe命令。在这个实例中,加载snd_bcm2835模块,它是 Pi 中的 Broadcom 声音适配器。发出以下命令:
$ sudo modprobe snd_bcm2835
该命令将会运行,但是它不会生成任何输出来告诉我们执行的状态或其他任何信息。我们需要检查模块是否已经加载。就像ls命令用于目录和lsusb用于列出 USB 设备一样,还有一个lsmod命令用于列出当前安装在系统中的模块。发出lsmod命令,检查您是否可以看到snd_bcm2835模块加载到您的系统中(像我的一样):
$ lsmod
Module Size Used by
snd_bcm2835 21485 0
snd_pcm 82208 1 snd_bcm2835
snd_page_alloc 5383 1 snd_pcm
snd_seq 59808 0
snd_seq_device 6920 1 snd_seq
snd_timer 21905 2 snd_seq,snd_pcm
snd 57668 5 snd_timer,snd_seq_device,snd_seq,snd_pcm,snd_bcm2835
ipv6 290227 34
r8712u 182646 0
spi_bcm2708 4815 0
i2c_bcm2708 3818 0
因为您是第一次加载声音模块,所以您还需要选择正在使用的音频设备(因为以前没有使用过)。要改变器件,使用如下的amixer命令:
$ sudo amixer cset numid=3 1
numid=3,iface=MIXER,name=’PCM Playback Route’
; type=INTEGER,access=rw˗˗˗˗˗˗,values=1,min=0,max=3,step=0
: values=1
我们将 PCM 播放路径的numid=3值更改为等于 3.5 插孔的值1。你可以把末端的1改成2,这表示你应该使用 HDMI 的内置音频通道来发送声音。
既然硬件已经整理好了,是时候通过从互联网上的存储库下载 shairport 软件来处理软件了。到目前为止,最简单的方法是使用wget(Web GET 的缩写)命令下载给定 URL 上的所有可用内容。通过这种方式,我们可以用一个简单的 URL 从互联网上下载整个软件包。执行以下操作:
$ wgethttps://github.com/albertz/shairport/zipball/master
˗˗2012-09-30 18:13:36˗˗https://github.com/albertz/shairport/zipball/master
Resolving github.com (github.com)... 207.97.227.239
Connecting to github.com (github.com)|207.97.227.239|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location:https://nodeload.github.com/albertz/shairport/zipball/master
˗˗2012-09-30 18:13:42˗˗https://nodeload.github.com/albertz/shairport/zipball/master
Resolving nodeload.github.com (nodeload.github.com)... 207.97.227.252
Connecting to nodeload.github.com (nodeload.github.com)|207.97.227.252|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 46413 (45K) [application/zip]
Saving to: ’master’
100%[==================================================>] 46,413 60.1K/s in 0.8s
2012-09-30 18:13:50 (60.1 KB/s) - ’master’ saved [46413/46413]
现在我们已经下载了 shairport 软件,我们需要使用它。文件名为master,我们整理一下,正确命名。只需使用move命令来更改文件名。一旦你移动了文件,用unzip命令和cd解压到新创建的albertz-shairport-b58f156目录中:
$ mv master albertz-shairport-b58f156.zip
$ unzip albertz-shairport-b58f156.zip
$ cd albertz-shairport-3892180
现在您需要构建应用程序,所以运行make命令。幸运的是,这个应用程序比 XBMC 的简单得多,因此不需要预先配置。
$ make
cc -O2 -Wall -c alac.c -o alac.o
cc -O2 -Wall -DHAIRTUNES_STANDALONE hairtunes.c alac.o -o hairtunes -lm -lpthread -lssl -lcrypto -lao
cc -O2 -Wall -c socketlib.c -o socketlib.o
cc -O2 -Wall -c shairport.c -o shairport.o
cc -O2 -Wall -c hairtunes.c -o hairtunes.o
cc -O2 -Wall socketlib.o shairport.o alac.o hairtunes.o -o shairport -lm -lpthread -lssl -lcrypto -lao
一旦编译完成,就是测试的时候了;shairport 是通过执行shairport.pl文件来运行的。请按如下方式执行:
$ ./shairport.pl
Can’t locate Net/SDP.pm in @INC (@INC contains: /usr/lib/perl5/site_perl /usr/share/perl5/site_perl /usr/lib/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib/perl5/core_perl /usr/share/perl5/core_perl .) at ./shairport.pl line 45.
呜呜!有一个错误与 Perl 系统执行安装所需的特定代码模块不可用有关。在这种情况下,我们需要安装的是 Net/SDP 模块。
不幸的是,apt-get不能修复这个问题,所以你必须从 Perl CPAN 库(它很像一个巨大的 Perl 软件库,开发者可以借用和使用)下载模块,然后安装它。你将再次使用wget从网上下载文件。发出以下命令:
$ wgethttp://search.cpan.org/CPAN/authors/id/N/NJ/NJH/Net-SDP-0.07.tar.gz
˗˗2012-09-30 19:01:11˗˗http://search.cpan.org/CPAN/authors/id/N/NJ/NJH/Net-SDP-0.07.tar.gz
Resolving search.cpan.org (search.cpan.org)... 199.15.176.161
Connecting to search.cpan.org (search.cpan.org)|199.15.176.161|:80... connected.
HTTP request sent, awaiting response... 302 Found
Location:http://mirror.westfield.com.au/cpan/authors/id/N/NJ/NJH/Net-SDP-0.07.tar.gz
˗˗2012-09-30 19:01:11˗˗http://mirror.westfield.com.au/cpan/authors/id/N/NJ/NJH/Net-SDP-0.07.tar.gz
Resolving mirror.westfield.com.au (mirror.westfield.com.au)... 203.42.62.21
Connecting to mirror.westfield.com.au (mirror.westfield.com.au)|203.42.62.21|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 20679 (20K) [application/x-gzip]
Saving to: ’Net-SDP-0.07.tar.gz’
100%[===========================================================================>] 20,679 ˗˗.-K/s in 0.05s
2012-09-30 19:01:12 (382 KB/s) - ’Net-SDP-0.07.tar.gz’ saved [20679/20679]
一旦文件被下载,您需要用tar命令提取它。发出一个带有参数–zxvf的tar命令来解压文件,解压缩这个 tarball。然后切换到新创建的Net-SDP-0.07目录:
$ tar –zxvf Net-SDP-0.07.tar.gz
$ cd Net-SDP-0.07
现在包已经在这里了,您只需要在这里向 Perl 构建系统发出命令。第一个是执行Build.PL脚本来生成构建文件:
$ perl Build.PL
Created MYMETA.yml and MYMETA.json
Creating new ’Build’ script for ’Net-SDP’ version ’0.07’
一旦创建了构建文件,您需要用下面的代码运行它:
$ ./Build
Building Net-SDP
构建完成后,通过向build脚本发出test命令来运行内置测试以确保没有问题:
$ ./Build test
t/00use.t ....... ok
t/10generate.t .. ok
t/10parse.t ..... ok
t/20repeat.t .... ok
t/30asstring.t .. ok
All tests successful.
Files=5, Tests=69, 5 wallclock secs ( 0.97 usr 0.05 sys + 3.40 cusr 0.29 csys = 4.71 CPU)
Result: PASS
最后,您需要安装模块,因此向build脚本发出install命令(您可能需要在命令后按 Enter 来完成安装并显示):
$ sudo ./Build install
[sudo] password for raspbian:
Building Net-SDP
Installing /usr/local/man/man1/sdp2rat.1p
Installing /usr/local/share/perl/5.14.2/Net/SDP.pm
Installing /usr/local/share/perl/5.14.2/Net/SDP/Time.pm
Installing /usr/local/share/perl/5.14.2/Net/SDP/Media.pm
Installing /usr/local/man/man3/Net::SDP::Media.3pm
Installing /usr/local/man/man3/Net::SDP::Time.3pm
Installing /usr/local/man/man3/Net::SDP.3pm
Installing /usr/local/bin/sdp2rat
一旦构建完成,再次运行shairport.pl脚本是一件简单的事情,这一次它应该可以工作了!输出应该如下所示:
$ cd..
$ ./shairport.pl
Established under name ’891BEA3BF8A1@ShairPort 2113 on pisces’
现在,您需要与应用程序建立连接,并测试您是否可以向它发送音乐。打开 iTunes,然后在 iTunes 的右下角更改输出目的地(参见图 11-5 )。您应该会在那里看到一个 shairport 名称。选择它,然后按下播放您最喜爱的歌曲和 presto:流媒体音乐!
图 11-5。
ShairPort enabled
解决纷争
和 XBMC 一样,这个过程相当容易,因为 Raspberry Pi 有一个固定的硬件平台,如果没有所有这些变量,就没有那么多需要担心的事情——事情应该会正常工作。
如果您发现扬声器连接后没有声音,请检查您是否正确发出了modprobe和amixer命令,因为这两个命令都是实现音频功能所必需的。
除了这个问题之外,大多数命令都应该可以工作。如果没有,您应该删除任何下载的内容并重新开始。
机场开机
与使用 XBMC 实例一样,如果不需要手动登录到您的 Pi 并启动应用程序,大多数人不会希望在他们的系统中启动 shairport。这对于我们来说很容易,因为 shairport 安装程序已经捆绑了所有需要的文件!为此,首先安装 shairport 系统:运行sudo make install,您的输出应该如下所示:
$ sudo make install
install -D -m 0755 hairtunes /usr/local/bin/hairtunes
install -D -m 0755 shairport.pl /usr/local/bin/shairport.pl
install -D -m 0755 shairport /usr/local/bin/shairport
安装完成后,您可以将提供的init脚本复制到正确的位置:
$ sudo cp shairport.init.sample /etc/init.d/shairport
既然文件已经被复制,您需要做一个小的修改:在启动 shairport 应用程序之前,将前面的modprobe命令——】添加到/etc/init.d/shairport文件中。start部分应该是这样的:
start() {
echo -n "Starting shairport: "
modprobe snd_bcm2835
start-stop-daemon ˗˗start ˗˗quiet ˗˗pidfile "$PIDFILE" \
˗˗exec "$DAEMON" -b ˗˗oknodo ˗˗ $DAEMON_ARGS
log_end_msg $?
}
我们需要运行的最后一个命令是:
$ sudo chmod +x /etc/init.d/shairport
$ sudo update-rc.d shairport defaults
这些命令使新的start脚本可写,并更新引导序列以包含新的 shairport 脚本!重新启动您的 Pi,shairport 应该会在启动时为您启动并运行!恭喜你。
摘要
在这一全面的章节中,您安装了整个 precursor 应用程序课程,并学习了如何下载源代码、配置源代码和编译源代码。这是相当多的工作,XBMC 编译花费了超过 12 个小时!
您还创建并安装了start脚本来让这些新的媒体回放系统在引导时在 Pi 上运行,避免了手动干预的需要。
最后,您将XBMC实例连接到智能手机的远程控制应用程序。这一章的工作量令人难以置信,干得好!