树莓派实现 NAS 家庭服务器(流媒体播放、文件共享及下载机)
一、家庭服务器实现的主要功能
1、流媒体播放服务:利用 DLNA 实现电视、手机、电脑播放其上面的媒体文件。
2、文件共享:利用 samba 实现手机、电脑等终端与服务器的文件共享。
3、自动下载:利用 aria2c 实现自动下载。
先上几张效果图:
用 orico 的包装盒做了个机箱。
内部效果,线还是有些凌乱
放在桌上,感觉还不错,呵呵
二、准备工作
1、树莓派 B+
2、安装 raspbian 系统,具体安装方法见: 树莓派学习笔记(1):入手树莓派 。
3、设置固定 IP 为 192.168.1.120,设置方法见: 树莓派学习笔记(3):利用 VNC 远程控制树莓派。
4、安装 vnc 软件,安装方法见: 树莓派学习笔记(3):利用 VNC 远程控制树莓派。
5、准备了一块旧移动硬盘(80G)
6、准备了可外接供电的 usb hub 一个,树莓派本身输出电流较小,很难保证移动硬盘的运行,所以加了一个可外接供电的 usb hub。
三、安装 samba 实现文件共享
1、准备硬盘
硬盘进行分区和格式化,这里我直接就分了一个区,格式化为 ext4 格式,据网上介绍说如果是 fat 或者 ntfs 等格式可能会出现权限问题,于是干脆直接格式化为 ext4 格式。硬盘在树莓派上格式化会比较慢,我就在电脑上进行了格式化。电脑操作系统是 windows7,利用软件 MiniTool Partition Wizard Home Edition 8.0,下载地址: http://www.partitionwizard.com/download.html 。具体使用方法是先将原分区删除,然后点击 creat,在格式那里选 ext4,类型我选的 primary,label 用的 nas,然后点击 apply 就开始格式化硬盘了。(如果用容量较小的 U 盘,可以直接用树莓派格式化,命令为:mkfs -t ext4 /dev/sdb1)
2、将硬盘挂载到树莓派上
树莓派开机后,用 putty 连接(连接方法见 树莓派学习笔记(1):入手树莓派 )后,为方便操作直接进行 root 用户(具体方法见 http://www.cnblogs.com/xiaowuyi/p/3980037.html 一楼评论处),然后运行 df –h,查看硬盘挂载情况。
root@raspberrypi:/home/pi# df -h Filesystem Size Used Avail Use% Mounted on rootfs 2.9G 2.4G 387M 87% / /dev/root 2.9G 2.4G 387M 87% / devtmpfs 183M 0 183M 0% /dev tmpfs 38M 792K 37M 3% /run tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 75M 0 75M 0% /run/shm /dev/mmcblk0p1 56M 9.7M 47M 18% /boot /dev/sda1 70G 24M 67G 1% /media/nas
最后一行/dev/sda1 说明硬盘已经挂载。为下一步安装 samba,将共享文件夹设为/samba。于是新建文件夹:
mkdir /samba
设置访问权限:
shmod 777 /samba
将硬盘挂载到/samba 文件夹,具体步骤:
umount /dev/sda1 #取消挂载 mount /dev/sda1 /samba
这里再查看 df -h,结果为:
这里表示已挂载成功。
3、解决硬盘的自动挂载
每次树莓派重启或者硬盘插拔都需要对硬盘进行重新挂载,比较麻烦,因此需要自动挂载。这里要修改/etc/fstab 文件。有人喜欢用 vi 进行编辑,我比较喜欢直接 vnc 连接上后,用编辑器进行编辑。
可以看到,fstab 文件其实就是一个表格,表格各列的含意如下:
第一列:磁盘分区名/卷标,一般是/dev/sdaN(N 表示正整数)
第二列:挂载点,我们在这里把/dev/sda1 挂到/samba 上。
第三列:缺省设置,一般用 defautls。
第四列:是否备份:0——表示不做 dump 备份;1——表示要将整个 <fie sysytem> 里的内容备份;2 也表示要做 dump 备份,但该分区的重要性比 1 小。
第五列:检测顺序:0——不进行检测;根分区(/),必须填写 1,其它的都不能填写 1。如果有分区填写大于 1 的话,则在检查完根分区后,从小到大依次检查下去。
具体填写方法在图中已注明。
4、安装 samba
更新一下源:
sudo apt-get update
安装 samba
sudo apt-get install samba samba-common-bin
安装完成后,配置/etc/samba/smb.conf 文件
在其最后添加以下命令:
#================================================ [share] #共享文件的名称,将在网络上以此名称显示 path = /samba #共享文件的路径 valid users = root pi #允许访问的用户,这里我用的是 root 和 pi 两个用户 browseable = yes #允许浏览 public = yes #共享开放 writable = yes #可写 #================================================
保存后,重启 samba 服务,输入
/etc/init.d/samba restart
最后添加共享用户:
smbpasswd –a pi #这里我用的 pi。
设置开机自启动,编辑/etc/rc.loca,如下
5、测试 samba 安装效果
在 windows 计算机上,打开我的电脑,在左下角网络点右键,选映射网络驱动器
点击完成会提示输入用户名和密码,这里输入设置的共享用户名和密码。
最后在计算机下会出现共享的文件夹,点开文件夹,新建 test.txt 文件进行一下测试,如果能正常建立,就说明 ok 了,如果不行,应该是权限问 题,可再重新设置一下/samba 文件夹权限。这里注意,如果在/samba 文件夹下新建新的文件夹,也需要设置权限,可以用 vnc 连接后,用管理员浏 览,点右键设置文件夹权限为 read and write,也可以用 chmod 命令设置。
四、安装 DLNA 实现流媒体服务器
DLNA 主要面向媒体资源(比如视频、音乐)实现网内共享,具体步骤如下:
1、安装 minidlna
更新一下安装源
sudo apt-get update
安装 minidlna
sudo apt-get install minidlna
2、设置配置文件
设置/etc/minidlna.conf 文件,在文件尾部添加如下内容:
#=================================================================================== media_dir=A,/samba/DLNA/Music #A 表示这个目录是存放音乐的,当 minidlna 读到配置文件时,它会自动加载这个目录下的音乐文件 media_dir=P,/samba/DLNA/Picture media_dir=V,/samba/DLNA/Video db_dir=/samba/DLNA/db #配置 minidlna 的数库数据的存放目录 log_dir=/samba/DLNA/log #配置日志目录 #=======================================================================================
3、建立文件夹
在/samba 文件夹下,建立以上文件夹,并设置好权限为 read and write。
4、重启 minidlna
/etc/init.d/minidlna restart
测试:
/etc/init.d/minidlna status
返回如下结果为正常。
5、在电脑上进行播放
先在树莓派以上对应的 video 等文件夹内存上一些文件(可利用 samba 直接从电脑上考入),然后返回到计算机进行操作。
点击我的电脑下面的网络,出现媒体设备
双击进入媒体播放器,在左边的列表栏下方其它媒体库中出现 raspberrypi:root,点击后,可选择音乐,视频等。
这时双击就可以欣赏了。
6、手机上进行播放
手机上实现网络共享,可安装 es file explorer 软件,在其网络处进行设置,设置方法与电脑基本一样,这里不再详述。设置后,文件均可浏览,媒体文件双击可以在线播放。
也可以直接使用 updp 播放器,这里我安装的是 moliplayer,可以在其附近设备里,直接找到 raspberrypi:root,访问其媒体问题,注意,这里是访问的 DLNA 共享,所以不需要再输入密码。
7、智能电视进行播放
智能电视一般都是用的 android 系统,与手机基本一样。
五、安装 aria2 实现下载机功能
1、安装 aria2
更新一下安装源
sudo apt-get update
安装 aria2
sudo apt-get install aria2
2、创建配置文件
在/etc 目录下创建 aria2 目录用来存放配置文件:
sudo mkdir /etc/aria2
创建空白的 aria2.session 文件:
sudo touch /etc/aria2/aria2.session
创建配置文件
sudo nano /etc/aria2/aria2.conf
在该文件中输入以下内容:
#=========文件保存目录自行修改 dir=/samba disable-ipv6=true #打开 rpc 的目的是为了给 web 管理端用 enable-rpc=true rpc-allow-origin-all=true rpc-listen-all=true #rpc-listen-port=6800 continue=true input-file=/etc/aria2/aria2.session save-session=/etc/aria2/aria2.session max-concurrent-downloads=3
这里为了方便共享,我直接设置将文件下载到 samba 共享文件夹。
3、启动 aria2
sudo aria2 –conf-path=/etc/aria2/aria2.conf
如果没有提示任何错误信息,那就按 ctrl+c 停止上面的语句,转为后台运行:
sudo aria2 –conf-path=/etc/aria2/aria2.conf -D
同时其此句写到开机启动中,编辑/etc/rc.loca,如下
4、安装 appache
为了能 web 管理 aria2 进行下载,需要安装 yaaw 和 appache 环境。
安装 appach
sudo apt-get install appache2
修改/var/www 的权限
chmod 777 /var/www
5、安装 yaaw
从 https://github.com/binux/yaaw 下载 yaaw,点击右下角的 ,下载后将解压后的文件夹内内容拷贝到/var/www 文件夹下。这时输入树莓派 IP,如果出现以下页面,则表示已经正常工作了。
这里可以点 add 添加下载任务,具体方法不再详述。
6、实现迅雷的离线下载
很多网站都介绍了 aria2 实现迅雷离线下载的方法,这里也做一下描述。我以 firefox 浏览器为例,chrome 浏览器本身有一个迅雷离线增加插件,可以从 https://chrome.google.com/webstore/detail/mbl%E8%BF%85%E9%9B%B7%E7%A6%BB%E7%BA%BF%E5%A2%9E%E5%BC%BA%E8%84%9A%E6%9C%AC/bcbkegabebafalcgckcdphlpainejkja 进行安装,安装后就和 firefox 基本一样了。
在 firefox 里添加一个书签:
具体为:
===========================================================
名称为:ThunderLixianExporter
地址为:javascript:void((function(){var d=document;var s=d.createElement('script');s.src='http://s.binux.me/tle.js';s.id='TLE_script';d.body.appendChild(s)})())
==================================================================
登录迅雷离线网站:lixian.xunlei.com,登录后,点一下书签中的 ThunderLixianExporter,然后点击迅雷页面右上角的配置按钮(小齿轮)。
在上面的窗口中填写 aria2.json-RPC Path,这个值来自于 yaaw 那个页面,具体方法是,输入树莓派 IP 显示 yaaw 页面,点击右上的配置图标,如下图
在 set 页面中存在该值:
保存好后,在离线页面的每行记录的取回本地后面会出现一个下拉菜单,选择 yaaw 就会直接添加到 yaaw 任务中了。
到此,树莓派的 NAS 服务器搭建完成,试了一下效果,还是很满意的。
六、制作外壳
1、外壳
直接从家里找了一个 orico 的包装盒,大小正好合适,而且外壳比较硬,外观也比较不错。
2、加装 1602 显示屏
加装一个 1602 显示屏,目的是显示时间和 CPU 温度,当然也可以显示其它内容,我这里只显示了这两项。这里还需要加装一个电位器(也就是可变电阻,如果没有,可以加一个 10K 的电阻)
(1)1602 硬件连接
1602 共 16 个端口,只用其中 12 个,具体接法如下:
LCD1602 液晶屏模块提供了 16 个引脚,我们只需接其中的 12 个即可:
VSS,接地 |
VDD,接 5V 电源 |
VO,液晶对比度调节,接电位器中间的引脚,电位器两边的引脚分别接 5V 和接地。 |
RS,寄存器选择,接 GPIO14 |
RW,读写选择,接地,表示写模式 |
EN,使能信号,接 GPIO15 |
D0,数据位 0,4 位工作模式下不用,不接 |
D1,数据位 1,4 位工作模式下不用,不接 |
D2,数据位 2,4 位工作模式下不用,不接 |
D3,数据位 3,4 位工作模式下不用,不接 |
D4,数据位 4,接 GPIO17 |
D5,数据位 5,接 GPIO18 |
D6,数据位 6,接 GPIO27 |
D7,数据位 7,接 GPIO22 |
A,液晶屏背光+,接 5V |
K,液晶屏背光-,接地 |
注意:1、这里的 VSS、VDD 等在有些 1602 的板子上会标明,有些则只标了数字,如一端写着 1,一端写着 16,1 对应的就是 VSS 端,16 对应的就是 K 端,因此依次连接就可以了。
2、GPIO 各端口及 5V、接地等端口见下图,因为我用的是 B+的板了,因此这里的图也是 B+的端口图。
3、连接通电后,1602 会亮起,其中一行为黑色方格,一行什么也不显示,如果全不显示,可调节一下电位器
(2)代码
对于 1602 板子的操作,已经有人做了一个示例,这样用起来就比较简单了。示例代码下载地址:https://github.com/lifanxi/rpimenu.git,解压后有 Adafruit_CharLCD.py 文件,此文件在 LCD 上会显示两行字符:LCD 1602 Test, 123456789ABCDEF。这里只需要在此文件上进行一下修改就可以了。
#!/usr/bin/python #<span style="font-family: 宋体; font-size: 12px;">转载请注明:@小五义<a href="http://www.cnblogs.com/xiaowuyi">http://www.cnblogs.com/xiaowuyi</a> QQ 群:64770604</span> # # based on code from lrvick and LiquidCrystal # lrvic - https://github.com/lrvick/raspi-hd44780/blob/master/hd44780.py # LiquidCrystal - https://github.com/arduino/Arduino/blob/master/libraries/LiquidCrystal/LiquidCrystal.cpp # #from time import sleep import time,os class Adafruit_CharLCD: # commands LCD_CLEARDISPLAY = 0x01 LCD_RETURNHOME = 0x02 LCD_ENTRYMODESET = 0x04 LCD_DISPLAYCONTROL = 0x08 LCD_CURSORSHIFT = 0x10 LCD_FUNCTIONSET = 0x20 LCD_SETCGRAMADDR = 0x40 LCD_SETDDRAMADDR = 0x80 # flags for display entry mode LCD_ENTRYRIGHT = 0x00 LCD_ENTRYLEFT = 0x02 LCD_ENTRYSHIFTINCREMENT = 0x01 LCD_ENTRYSHIFTDECREMENT = 0x00 # flags for display on/off control LCD_DISPLAYON = 0x04 LCD_DISPLAYOFF = 0x00 LCD_CURSORON = 0x02 LCD_CURSOROFF = 0x00 LCD_BLINKON = 0x01 LCD_BLINKOFF = 0x00 # flags for display/cursor shift LCD_DISPLAYMOVE = 0x08 LCD_CURSORMOVE = 0x00 # flags for display/cursor shift LCD_DISPLAYMOVE = 0x08 LCD_CURSORMOVE = 0x00 LCD_MOVERIGHT = 0x04 LCD_MOVELEFT = 0x00 # flags for function set LCD_8BITMODE = 0x10 LCD_4BITMODE = 0x00 LCD_2LINE = 0x08 LCD_1LINE = 0x00 LCD_5x10DOTS = 0x04 LCD_5x8DOTS = 0x00 def __init__(self, pin_rs=14, pin_e=15, pins_db=[17, 18, 27, 22], GPIO = None): # Emulate the old behavior of using RPi.GPIO if we haven't been given # an explicit GPIO interface to use if not GPIO: import RPi.GPIO as GPIO GPIO.setwarnings(False) self.GPIO = GPIO self.pin_rs = pin_rs self.pin_e = pin_e self.pins_db = pins_db self.GPIO.setmode(GPIO.BCM) self.GPIO.setup(self.pin_e, GPIO.OUT) self.GPIO.setup(self.pin_rs, GPIO.OUT) for pin in self.pins_db: self.GPIO.setup(pin, GPIO.OUT) self.write4bits(0x33) # initialization self.write4bits(0x32) # initialization self.write4bits(0x28) # 2 line 5x7 matrix self.write4bits(0x0C) # turn cursor off 0x0E to enable cursor self.write4bits(0x06) # shift cursor right self.displaycontrol = self.LCD_DISPLAYON | self.LCD_CURSOROFF | self.LCD_BLINKOFF self.displayfunction = self.LCD_4BITMODE | self.LCD_1LINE | self.LCD_5x8DOTS self.displayfunction |= self.LCD_2LINE """ Initialize to default text direction (for romance languages) """ self.displaymode = self.LCD_ENTRYLEFT | self.LCD_ENTRYSHIFTDECREMENT self.write4bits(self.LCD_ENTRYMODESET | self.displaymode) # set the entry mode self.clear() def begin(self, cols, lines): if (lines > 1): self.numlines = lines self.displayfunction |= self.LCD_2LINE self.currline = 0 def home(self): self.write4bits(self.LCD_RETURNHOME) # set cursor position to zero self.delayMicroseconds(3000) # this command takes a long time! def clear(self): self.write4bits(self.LCD_CLEARDISPLAY) # command to clear display self.delayMicroseconds(3000) # 3000 microsecond sleep, clearing the display takes a long time def setCursor(self, col, row): self.row_offsets = [ 0x00, 0x40, 0x14, 0x54 ] if ( row > self.numlines ): row = self.numlines - 1 # we count rows starting w/0 self.write4bits(self.LCD_SETDDRAMADDR | (col + self.row_offsets[row])) def noDisplay(self): """ Turn the display off (quickly) """ self.displaycontrol &= ~self.LCD_DISPLAYON self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol) def display(self): """ Turn the display on (quickly) """ self.displaycontrol |= self.LCD_DISPLAYON self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol) def noCursor(self): """ Turns the underline cursor on/off """ self.displaycontrol &= ~self.LCD_CURSORON self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol) def cursor(self): """ Cursor On """ self.displaycontrol |= self.LCD_CURSORON self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol) def noBlink(self): """ Turn on and off the blinking cursor """ self.displaycontrol &= ~self.LCD_BLINKON self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol) def noBlink(self): """ Turn on and off the blinking cursor """ self.displaycontrol &= ~self.LCD_BLINKON self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol) def DisplayLeft(self): """ These commands scroll the display without changing the RAM """ self.write4bits(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVELEFT) def scrollDisplayRight(self): """ These commands scroll the display without changing the RAM """ self.write4bits(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVERIGHT); def leftToRight(self): """ This is for text that flows Left to Right """ self.displaymode |= self.LCD_ENTRYLEFT self.write4bits(self.LCD_ENTRYMODESET | self.displaymode); def rightToLeft(self): """ This is for text that flows Right to Left """ self.displaymode &= ~self.LCD_ENTRYLEFT self.write4bits(self.LCD_ENTRYMODESET | self.displaymode) def autoscroll(self): """ This will 'right justify' text from the cursor """ self.displaymode |= self.LCD_ENTRYSHIFTINCREMENT self.write4bits(self.LCD_ENTRYMODESET | self.displaymode) def noAutoscroll(self): """ This will 'left justify' text from the cursor """ self.displaymode &= ~self.LCD_ENTRYSHIFTINCREMENT self.write4bits(self.LCD_ENTRYMODESET | self.displaymode) def write4bits(self, bits, char_mode=False): """ Send command to LCD """ self.delayMicroseconds(1000) # 1000 microsecond sleep bits=bin(bits)[2:].zfill(8) self.GPIO.output(self.pin_rs, char_mode) for pin in self.pins_db: self.GPIO.output(pin, False) for i in range(4): if bits[i] == "1": self.GPIO.output(self.pins_db[::-1][i], True) self.pulseEnable() for pin in self.pins_db: self.GPIO.output(pin, False) for i in range(4,8): if bits[i] == "1": self.GPIO.output(self.pins_db[::-1][i-4], True) self.pulseEnable() def delayMicroseconds(self, microseconds): seconds = microseconds / float(1000000) # divide microseconds by 1 million for seconds time.sleep(seconds) def pulseEnable(self): self.GPIO.output(self.pin_e, False) self.delayMicroseconds(1) # 1 microsecond pause - enable pulse must be > 450ns self.GPIO.output(self.pin_e, True) self.delayMicroseconds(1) # 1 microsecond pause - enable pulse must be > 450ns self.GPIO.output(self.pin_e, False) self.delayMicroseconds(1) # commands need > 37us to settle def message(self, text): """ Send string to LCD. Newline wraps to second line""" for char in text: if char == '\n': self.write4bits(0xC0) # next line else: self.write4bits(ord(char),True) if __name__ == '__main__': while 1: lcd = Adafruit_CharLCD() lcd.clear() cputemp=os.popen('vcgencmd measure_temp').readline() sumcputemp=cputemp.replace("temp=","CPU:").replace("'C\n","") lcdout=time.strftime('%Y-%m-%d %H:%M',time.localtime(time.time()))+"\n"+sumcputemp lcd.message(lcdout) time.sleep(30)
3、开面自启动上面的程序
将以上文件命名为 1602.py,保存在/home/pi 下面,修改/etc/rc.loca,添加上 sudo python /home/pi/1602/py。树莓派开机时,插上电源,当 1602 能正常显示 CPU 温度时,表示机器已经启动完成,各项功能可正常使用。
4、一些其它的想法
(1)本想再加装一个风扇用来散热,结果手上没有 3.3V 的风扇了,所以就没加。感兴趣的朋友可以自己加一下,因为树莓派输出为 3.3V,所以最好是直接买 3.3V 的,如果买 5V 的,就一定要带个 3.3V 的继电器,要不没法对风扇控制。如果风扇一直常开那就无所谓了,5V 就可以,直接接正负级。我原 本的想法是 CPU 上了 50 度,风扇再运转,这样可以降温,同时噪音也不会大。
(2)这个家庭服务器搭建起来以后,后面还有很多文章可做,比如可以依托他建立家庭监控系统,装上两个摄像头什么的,也可以做一些外网访问的设置,这样就可以直接从外网进行操作了。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论