树莓派实现 NAS 家庭服务器(流媒体播放、文件共享及下载机)

发布于 2024-07-21 22:28:08 字数 24460 浏览 21 评论 0

一、家庭服务器实现的主要功能

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

1

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,结果为:

2

这里表示已挂载成功。

3、解决硬盘的自动挂载

每次树莓派重启或者硬盘插拔都需要对硬盘进行重新挂载,比较麻烦,因此需要自动挂载。这里要修改/etc/fstab 文件。有人喜欢用 vi 进行编辑,我比较喜欢直接 vnc 连接上后,用编辑器进行编辑。

image

可以看到,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,如下

4

5、测试 samba 安装效果

在 windows 计算机上,打开我的电脑,在左下角网络点右键,选映射网络驱动器

image

点击完成会提示输入用户名和密码,这里输入设置的共享用户名和密码。

image

最后在计算机下会出现共享的文件夹,点开文件夹,新建 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

返回如下结果为正常。

image

5、在电脑上进行播放

先在树莓派以上对应的 video 等文件夹内存上一些文件(可利用 samba 直接从电脑上考入),然后返回到计算机进行操作。

点击我的电脑下面的网络,出现媒体设备

image

双击进入媒体播放器,在左边的列表栏下方其它媒体库中出现 raspberrypi:root,点击后,可选择音乐,视频等。

image

这时双击就可以欣赏了。

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,如下

3

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,点击右下角的 image,下载后将解压后的文件夹内内容拷贝到/var/www 文件夹下。这时输入树莓派 IP,如果出现以下页面,则表示已经正常工作了。

image

这里可以点 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 里添加一个书签:

image

具体为:

===========================================================

名称为: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,然后点击迅雷页面右上角的配置按钮(小齿轮)。

image

image

image

在上面的窗口中填写 aria2.json-RPC Path,这个值来自于 yaaw 那个页面,具体方法是,输入树莓派 IP 显示 yaaw 页面,点击右上的配置图标,如下图

image

在 set 页面中存在该值:

image

保存好后,在离线页面的每行记录的取回本地后面会出现一个下拉菜单,选择 yaaw 就会直接添加到 yaaw 任务中了。

image

image

到此,树莓派的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

血之狂魔

暂无简介

0 文章
0 评论
23 人气
更多

推荐作者

安静被遗忘

文章 0 评论 0

喔爱吃橙子

文章 0 评论 0

草莓味的萝莉

文章 0 评论 0

梦里兽

文章 0 评论 0

mb_83J3Cyxa

文章 0 评论 0

时间海

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文