总结下最近两个月在我新买的树莓派3B+上运行的项目。
1)第一个想法是在树莓派接入有线网络、电源、usb接口的移动硬盘的硬件后,搭建基于aria2+aria2 webui的远程下载机;
Aria2是一个占用系统资源比较小的命令行下载机,支持http,https,种子,磁力链接等多种下载方式。项目的github地址:https://github.com/aria2/aria2
经过源代码的clone、make编译后,就可以配置启动aria2了,其中aria2.conf的配置文件内容如下:
dir=/home/wwwroot/file/share/Movies continue=true min-split-size=10M max-connection-per-server=5 input-file=/home/pi/app/aria2/aria2.session save-session=/home/pi/app/aria2/aria2.session enable-rpc=true rpc-allow-origin-all=true rpc-listen-all=true rpc-secret=mspace listen-port=51413 enable-dht=true dht-listen-port=6881-6999 enable-dht6=false enable-peer-exchange=true peer-id-prefix=-TR2770- user-agent=Transmission/2.77 seed-ratio=1.0 bt-seed-unverified=true bt-save-metadata=true
具体的搭建过程这里不多赘述,为了实现aria2的开机自启,我这里设置方法为在/lib/systemd/system里面新建aria.service,内容为:
[Unit] Description=Aria2 Service After=network.target [Service] User=pi Type=forking ExecStart=/usr/bin/aria2c --conf-path=/home/pi/app/aria2/aria2.conf -D [Install] WantedBy=multi-user.target
然后systemctl enable aria && systemctl restart aria,以应对重启后的服务启动问题。
Aria2 WebUI是一个以网页形式来管理aria2的程序,为了搭建其运行必要的服务器环境,我在树莓派上安装了轻量级的nginx,然后把Aria2 WebUI的源程序拖到相应的文件夹,绑定本地端口,实现服务的正常运行。Aria2 WebUI的Github项目地址:https://github.com/ziahamza/webui-aria2
2)利用mjpg-streamer + usb 720P摄像头实现家中的远程监控;
之前为了实现网络远程监控的想法通过了两个项目来实现:motion与mjpg-streamer,前者在我尝试了在我的树莓派3B+上配置了之后,通过局域网访问还是有监控画面延迟高、帧率低的情况,不知道是我的motion配置的问题还是小派的性能限制,就选择了mjpg-streamer,运行良好。
项目的Github地址:https://github.com/jacksonliam/mjpg-streamer
为了mjpg-streamer的开机自启,我的做法是在树莓派的/etc/init.d文件夹下新建webcam文件,内容为:
#!/bin/sh # /etc/init.d/webcam ### BEGIN INIT INFO # Provides: webcam # Required-Start: $network # Required-Stop: $network # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: mjpg_streamer for webcam # Description: Streams /dev/video0 to http://IP/?action=stream ### END INIT INFO DAEMON=/home/pi/mjpg-streamer/mjpg-streamer-experimental WC_USER=your_user_name WC_PASSWORD=your_password WC_PORT=8080 f_message(){ echo "[+] $1" } # Carry out specific functions when asked to by the system case "$1" in start) f_message "Starting mjpg_streamer" $DAEMON/mjpg_streamer -b -i "$DAEMON/input_uvc.so -r 1280x720 -f 30 " -o "$DAEMON/output_http.so -w $DAEMON/www -c $WC_USER:$WC_PASSWORD -p $WC_PORT" sleep 2 f_message "mjpg_streamer started" ;; stop) f_message "Stopping mjpg_streamer…" killall mjpg_streamer f_message "mjpg_streamer stopped" ;; restart) f_message "Restarting daemon: mjpg_streamer" killall mjpg_streamer $DAEMON/mjpg_streamer -b -i "$DAEMON/input_uvc.so -r 1280x720 -f 30 " -o "$DAEMON/output_http.so -w $DAEMON/www -c $WC_USER:$WC_PASSWORD -p $WC_PORT" sleep 2 f_message "Restarted daemon: mjpg_streamer" ;; status) pid=`ps -A | grep mjpg_streamer | grep -v "grep" | grep -v mjpg_streamer. | awk '{print $1}' | head -n 1` if [ -n "$pid" ]; then f_message "mjpg_streamer is running with pid ${pid}" f_message "mjpg_streamer was started with the following command line" cat /proc/${pid}/cmdline ; echo "" else f_message "Could not find mjpg_streamer running" fi ;; *) f_message "Usage: $0 {start|stop|status|restart}" exit 1 ;; if [ -n "$pid" ]; then f_message "mjpg_streamer is running with pid ${pid}" f_message "mjpg_streamer was started with the following command line" cat /proc/${pid}/cmdline ; echo "" else f_message "Could not find mjpg_streamer running" fi ;; *) f_message "Usage: $0 {start|stop|status|restart}" exit 1 ;; esac exit 0
最后ssh中输入sudo update-rc.d webcam defaults,实现服务开机自启。
3)在搭建aria2下载机的同时,还需要解决Raspbian下ntfs格式的移动硬盘的读写问题。然后我还在小派上搭建了Samba服务,用于硬盘文件的局域网共享。
usb移动硬盘的挂载问题是通过在小派上安装ntfs-3g来解决,项目网址:https://www.tuxera.com/命令为:
sudo apt-get install ntfs-3g
然后设置挂载点:
sudo mount -t ntfs-3g /dev/sda1 /home/wwwroot/file/share
为了实现开机自动挂载并设置好相应权限,需要在/etc/fstab中写入:
/dev/sda1 /home/wwwroot/file/share ntfs-3g utf8,noexec,uid=1004,gid=1002,umask=0000 0 0
接下来的部分是在小派上配置Samba以实现局域网共享硬盘文件的目的:
首先通过sudo apt-get install samba安装软件,配置方法nano /etc/samba/smb.conf,然后再最后一行加入:
[share] path = /home/wwwroot/file/share browseable = yes public = yes writable = yes guest ok=yes comment= mobile HDD for share
实现Samba开机自启的方法是编辑/etc/rc.local文件,最后一行加入:
sudo /etc/init.d/samba restart
这样,就可以方便地在树莓派与Windows间传输文件了。
4)我在树莓派上安装了一个usb供电的小音箱,然后打算利用gmrender-resurrect & shairplay实现局域网下的基于UPnP/DLNA & Airplay的流媒体播放:
首先是gmrender-resurrect,通过git clone, 编译和安装,就可以在支持DLNA的安卓设备上,将音乐串流到连接到树莓派音频接口的小音箱了。其GitHub项目地址:https://github.com/hzeller/gmrender-resurrect
其开机自启的方法是编辑/etc/init.d/gmediarenderer文件,里面加入:
#!/bin/sh ### BEGIN INIT INFO # Provides: gmediarender # Required-Start: $remote_fs $syslog $all # Required-Stop: $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start GMediaRender at boot time # Description: Start GMediaRender at boot time. ### END INIT INFO # User and group the daemon will be running as. On the Raspberry Pi, let's use # the default user. DAEMON_USER="gmediarender:audio" # Device name as it will be advertised to and shown in the UPnP controller UI. # Some string that helps you recognize the player, e.g. "Livingroom Player" UPNP_DEVICE_NAME="DLNA-Raspberry" # Initial volume in decibel. 0.0 is 'full volume', -10 correspondents to '75' on # the exported volume scale (Note, this does not change the ALSA volume, only # internal to gmrender. So make sure to leave the ALSA volume always to 100%). INITIAL_VOLUME_DB=-10 # If you explicitly choose a specific ALSA device here (find them with 'aplay -L'), then # gmediarenderer will use that ALSA device to play audio. # Otherwise, whatever default is configured for gstreamer for the '$DAEMON_USER' is # used. ALSA_DEVICE="sysdefault" #ALSA_DEVICE="iec958" # Path to the gmediarender binary. BINARY_PATH=/usr/local/bin/gmediarender if [ -n "$ALSA_DEVICE" ] ; then GS_SINK_PARAM="--gstout-audiosink=alsasink" GS_DEVICE_PARAM="--gstout-audiodevice=$ALSA_DEVICE" fi # A simple stable UUID, based on this systems' first ethernet devices MAC address, # only using tools readily available to generate. UPNP_UUID=`ip link show | awk '/ether/ {print "salt:)-" $2}' | head -1 | md5sum | awk '{print $1}'` USER=root HOME=/root export USER HOME case "$1" in start) echo "Starting GMediaRender" start-stop-daemon -x $BINARY_PATH -c "$DAEMON_USER" -S -- -f "$UPNP_DEVICE_NAME" -d -u "$UPNP_UUID" $GS_SINK_PARAM $GS_DEVICE_PARAM --gstout-initial-volume-db=$INITIAL_VOLUME$ ;; stop) echo "Stopping GMediaRender" start-stop-daemon -x $BINARY_PATH -K ;; HOME=/root export USER HOME case "$1" in start) echo "Starting GMediaRender" start-stop-daemon -x $BINARY_PATH -c "$DAEMON_USER" -S -- -f "$UPNP_DEVICE_NAME" -d -u "$UPNP_UUID" $GS_SINK_PARAM $GS_DEVICE_PARAM --gstout-initial-volume-db=$INITIAL_VOLUME$ ;; stop) echo "Stopping GMediaRender" start-stop-daemon -x $BINARY_PATH -K ;; *) echo "Usage: /etc/init.d/gmediarender {start|stop}" exit 1 ;; esac exit 0
然后sudo update-rc.d gmediarenderer defaults,就可以随时找到树莓派无线小音箱啦 : )
接下来是在小派上安装Shairplay以支持IOS设备的串流,GitHub项目地址为:https://github.com/juhovh/shairplay同理根据项目说明,编译安装好所需要的依赖环境和软件后,命令行输入shairplay -a Raspberry,手机连上家中的路由器,就可以在airplay中找到叫做Raspberry的无线音箱了。开机自启同样为编辑/etc/init.d/shairport,加入以下代码:
#! /bin/sh # To use this script, you must create a shairport user in the audio group: # sudo useradd -g audio shairport ### BEGIN INIT INFO # Provides: shairport # Required-Start: $remote_fs $networking # Required-Stop: $remote_fs $networking # Should-Start: pulseaudio alsa-utils hostname avahi # Should-Stop: pulseaudio alsa-utils hostname avahi # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 ### END INIT INFO # Do not modify this file. Edit /etc/default/shairport instead ! PATH=/sbin:/usr/sbin:/bin:/usr/bin DESC="Shairport Airtunes emulator" NAME=shairport DAEMON=/usr/local/bin/shairport # Configuration defaults USER=shairport GROUP=audio LOGFILE=/var/log/$NAME.log ERRFILE=/var/log/$NAME.err PIDFILE=/var/run/$NAME.pid AP_NAME=Airplay-Raspberry NICE=0 test -f /etc/default/shairport && . /etc/default/shairport DAEMON_ARGS="--daemon --pidfile $PIDFILE --log $LOGFILE" [ -z "$ERRFILE" ] || DAEMON_ARGS="$DAEMON_ARGS --error $ERRFILE" [ -z "$AP_NAME" ] || DAEMON_ARGS="$DAEMON_ARGS --name $AP_NAME" [ -z "$BUFFER_FILL" ] || DAEMON_ARGS="$DAEMON_ARGS -b $BUFFER_FILL" [ -z "$RUN_ONSTART" ] || DAEMON_ARGS="$DAEMON_ARGS --on-start "$RUN_ONSTART"" [ -z "$RUN_ONSTOP" ] || DAEMON_ARGS="$DAEMON_ARGS --on-stop "$RUN_ONSTOP"" [ -z "$OUTPUT" ] || DAEMON_ARGS="$DAEMON_ARGS --output $OUTPUT" [ -z "$MDNS" ] || DAEMON_ARGS="$DAEMON_ARGS --mdns $MDNS" [ -z "$OUTPUT_OPTS" ] || DAEMON_ARGS="$DAEMON_ARGS -- $OUTPUT_OPTS" # Exit if the package is not installed [ -x "$DAEMON" ] || { echo "$NAME is not installed" >&2 ; exit 1; } id -u "$USER" >/dev/null 2>&1 || { echo "User $USER does not exist" >&2; exit 1; } # Load the VERBOSE setting and other rcS variables . /lib/init/vars.sh # Define LSB log_* functions. # Depend on lsb-base (>= 3.2-14) to ensure that this file is present # and status_of_proc is working. . /lib/lsb/init-functions do_start() { # Let the daemon write to the pid/log/error files touch $PIDFILE $LOGFILE $ERRFILE chown root:$GROUP $PIDFILE $LOGFILE $ERRFILE chmod 660 $PIDFILE $LOGFILE $ERRFILE start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --chuid $USER:$GROUP --nicelevel $NICE -- $DAEMON_ARGS } do_stop() { start-stop-daemon --stop --quiet --pidfile $PIDFILE --exec $DAEMON --name $NAME --retry=TERM/10/KILL/5 } do_reload() { [ -f $PIDFILE ] && kill -HUP $(cat $PIDFILE) || return 1 } case "$1" in start) log_daemon_msg "Starting $DESC" "$NAME" do_start log_end_msg $? ;; stop) log_daemon_msg "Stopping $DESC" "$NAME" do_stop log_end_msg $? ;; reload) log_daemon_msg "Reloading $DESC" "$NAME" do_reload log_end_msg $? ;; status) status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $? ;; restart|force-reload) log_daemon_msg "Restarting $DESC" "$NAME" do_stop case "$?" in 0|1) do_start case "$?" in 0) log_end_msg 0 ;; 1) log_end_msg 1 ;; # Old process is still running *) log_end_msg 1 ;; # Failed to start esac ;; *) # Failed to stop log_end_msg 1 ;; esac ;; *) echo "Usage: $0 {start|stop|status|restart|force-reload}" >&2 exit 3 ;; esac :
最后也同样sudo update-rc.d shairport defaults,实现开机自启。
5)有了可以实现局域网串流的无线小音箱,少了树莓派的音乐盒功能怎么能行?基于Python的网易云音乐命令行版本你值得拥有:https://github.com/darknessomi/musicbox
按照readme配置好musicbox后,登陆自己的云音乐账号,就可以实现在线播放音乐了。值得一提的是该音乐盒支持命令行方式滚动歌词播放。
6)使用DNSPOD API和Python实现免费的DDNS。之前给电信客服打电话给家里的网络申请了公网IP,但是该公网IP的地址每隔一段时间就会重新分配,于是我萌生了使用定时任务每隔一段时间检测并将树莓派公网IP绑定到我的域名上的想法。具体的做法是新建一个.py文件放在小派中,然后设置其隔一段时间运行一次,py文件的内容为:
#!/usr/bin/env python #-*- coding:utf-8 -*- import httplib import urllib import socket import json import time ID = "your_ID" Token = "your_ID token" params = dict( login_token=("%s,%s" % (ID, Token)), format="json", domain_id=your_domain_id, record_id=your_record_id, sub_domain="your_sub_domain", record_line="默认", ) current_ip = None def ddns(ip): params.update(dict(value=ip)) headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/json"} conn = httplib.HTTPSConnection("dnsapi.cn") conn.request("POST", "/Record.Ddns", urllib.urlencode(params), headers) response = conn.getresponse() print response.status, response.reason data = response.read() print data conn.close() return response.status == 200 def getip(): sock = socket.create_connection(('ns1.dnspod.net', 6666), 20) ip = sock.recv(16) sock.close() return ip if __name__ == '__main__': while True: try: ip = getip() print ip if current_ip != ip: if ddns(ip): current_ip = ip except Exception as e: print e pass time.sleep(30)
然后再使用sudo crontab -e编辑定时任务,最后一行加入:
*/30 * * * * python /home/pi/ddns/file_name.py >> /home/pi/ddns/file_name.log 2>&1
这样就实现了每隔30min的自动ddns。
7)在树莓派上搭建基于nextcloud的个人私有云盘(NAS)。Nextcloud作为前老牌个人私有云程序owncloud的继任者,在各种私人网盘建设的方案中脱颖而出。这里我的建站环境也选择了较为方便的lnmp,他们的地址看这里:https://lnmp.org。安装完成了后就可以创建虚拟主机,加载网站程序了。Nextcloud支持私人网盘中音乐、视频的在线播放,文档的在线阅读,多用户管理以及文件分享,可以说是相当强大。