查看: 986|回复: 0

[教程] 树莓派+Flask实现视频流媒体WEB服务器

[复制链接]

主题

好友

616

积分

举人

  • TA的每日心情
    擦汗
    昨天 11:15
  • 签到天数: 8 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    发表于 2018-9-18 17:36:02 |显示全部楼层
    在这个项目中我们将主要学习两个模块。
    • 流式传输视频
    • 将视频集成到Web服务器上
    1.jpg

    材料清单
    1、树莓派V3 X1
    2、树莓派3 B型带NoIR夜间相机 X1
    3、DHT22温度传感器 X1
    4、DHT22相对湿度传感器 X1
    5、电阻4K7欧姆 X1
    在这个项目中,我使用的是夜间相机,你也可使用普通的树莓派相机(或任何USB相机)来替代。DHT22为可选。在教程中,我将演示如何将视频流传输到WEB页面,并用传感器来显示历史数据。

    安装摄像机
    2.jpg


    1、关闭树莓派,将相机安装在其特定端口上,如下所示:


    2、打开你的树莓派并转到树莓派配置工具的主菜单上,并确认相机接口是否开启:
    如果你需要开启它,请按[确定]并重新启动你的树莓派。
    4.jpg


    做一个简单的测试来验证一切是否正常:
    1. raspistill -o /Desktop/image.png
    复制代码
    你会看到,在到你树莓派桌面上会出现一个图像图标。 点击打开它。 如果出现图像,说明已准备好流式传输视频!如果你想获得更多关于相机的信息,可点击 Getting started with picamera.。

    安装FLASK
    有好几种方法可以流式传输视频。我认为最好的(也是“更轻松”)方法是使用Miguel Grinberg开发的Flask。有关Flask如何执行此操作的详细说明,请参阅他的精彩教程:flask-video-streaming-revisited。
    在我这个教程中:Python Web服务器将借助Flask和树莓派。我们要更详细地了解了Flask是如何工作、如何实现Web服务器以及从传感器上捕获数据并在网页上显示其状态。在本教程中的第一部分就是发送到我们前端的数据的视频流。

    创建一个Web服务器环境:
    首先要做的是在你的树莓派上安装Flask。 如果没有,去终端并输入:

    1. sudo apt-get install python3-flask
    复制代码
    当你开始一个新项目时,最好的办法就是创建一个文件夹来保存你的文件。 例如:
    回到主页,到你的工作目录:
    1. cd Documents
    复制代码
    新建文件夹,例如:
    1. mkdir camWebServer
    复制代码
    按照上面的命令,创建一个名为“camWebServer”的文件夹,并在这里保存我们的python脚本:
    1. /home/pi/Document/ camWebServer
    复制代码
    现在,在这个文件夹上,我们将创建两个子文件夹:静态的CSS、最终的JavaScript文件以及HTML文件的模板。 转到你的新创建的文件夹:
    1. cd camWebServer
    复制代码
    并创建2个新的子文件夹:
    1. mkdir static
    复制代码

    1. mkdir templates
    复制代码
    最终的目录“树”,如下所示:
    1. ├── Documents
    2.          ├── camWebServer
    3.                   ├── templates
    4.                   └── static
    复制代码
    完成!让我们在创建好的的环境下,用Python Web 服务器应用程序来流式传输视频。

    创建视频流媒体服务器
    5.jpg


    首先,下载Miguel Grinberg的树莓派相机软件包:camera_pi.py并将其保存在创建的目录camWebServer上。 这是我们项目的核心,Miguel的安装包相当的不错。

    现在,使用Flask,让我们调整原始的Miguel的web服务器应用程序(app.py),创建一个特定的python脚本来渲染我们的视频。 我们可以命名为appCam.py
    1. from flask import Flask, render_template, Response

    2. # Raspberry Pi camera module (requires picamera package, developed by Miguel Grinberg)
    3. from camera_pi import Camera

    4. app = Flask(__name__)

    5. @app.route('/')
    6. def index():
    7.     """Video streaming home page."""
    8.     return render_template('index.html')

    9. def gen(camera):
    10.     """Video streaming generator function."""
    11.     while True:
    12.         frame = camera.get_frame()
    13.         yield (b'--frame\r\n'
    14.                b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')

    15. @app.route('/video_feed')
    16. def video_feed():
    17.     """Video streaming route. Put this in the src attribute of an img tag."""
    18.     return Response(gen(Camera()),
    19.                     mimetype='multipart/x-mixed-replace; boundary=frame')

    20. if __name__ == '__main__':
    21.     app.run(host='0.0.0.0', port =80, debug=True, threaded=True)
    复制代码
    以上脚本将你的摄像机视频流式传输到index.html页面上,如下所示:
    1. <html>
    2.   <head>
    3.     <title>MJRoBot Lab Live Streaming</title>
    4.     <link rel="stylesheet" href='../static/style.css'/>
    5.   </head>
    6.   <body>
    7.     <h1>MJRoBot Lab Live Streaming</h1>
    8.     <h3><img src="{{ url_for('video_feed') }}" width="90%"></h3>
    9.     <hr>
    10.     <p> @2018 Developed by MJRoBot.org</p>
    11.   </body>
    12. </html>
    复制代码
    index.html最重要的一行是:
    1. <img src="{{ url_for('video_feed') }}" width="50%">
    复制代码

    视频将会在这里“反馈”到我们的网页上。
    你还必须在静态目录中包含style.css文件,以便以这种形式获得上述结果。
    所有文件都可以从我的GitHub仓库下载获得:camWebServer。
    确保所有的文件都在正确的位置,所有数据更新后,检查一下我们的环境:
    1. ├── Documents
    2.           ├── camWebServer
    3.                      ├── camera_pi.py
    4.                      ├── appCam.py
    5.                      ├── templates
    6.                      |        ├── index.html
    7.                      └── static
    8.                               ├── style.css
    复制代码
    现在,在终端上运行python脚本:
    1. <p>sudo python3 appCam.py</p>
    复制代码
    转到你的网络中的任何浏览器,并输入 http://树莓派的IP地址/
    注意:如果你不能确定你的树莓派IP地址,请在你的终端上运行:
    1. ifconfig
    复制代码
    在wlan0:部分你会找到它。
    就是这样了!从现在开始,唯一的问题是需要一个复杂的页面,将你的视频嵌入到另一个页面等。

    安装温度和湿度传感器
    6.jpg


    让我们创建一个使用真实数据记录的页面,其中如包含空气温度和相对湿度数据。因此我们将使用旧的、功能完好的DHT22。

    要点概述
    低成本的DHT温度和湿度传感器具有一般的基础功能、速度不快,但对于进行基本数据记录的爱好者来说非常适合。DHT传感器由两部分组成,即电容式湿度传感器和热敏电阻。 内部还有一个非常基本的芯片,它可以进行一些模数转换,并能读取温度和湿度的数字信号。 数字信号很容易用任何微控制器读取。

    DHT22主要特点:
    • 低成本
    • 3至5V电源和I/O
    • 转换期间最大电流为2.5mA
    • 适用于0-100%湿度读数,精度为2-5%
    • 适用于-40至125°C温度读数,精度为±0.5°C
    • 不超过0.5 Hz的采样率(每2秒一次)
    • 尺寸15.1mm x 25mm x 7.7mm
    • 0.1″间距带4个引脚

    一般情况下,你会在距离小于20米的地方使用传感器,在数据引脚和VCC引脚之间连接一个4K7欧姆的电阻。DHT22输出数据引脚将连接到树莓派的GPIO16。检查传感器连接到树莓派引脚的电路表,如下:
    1、引脚1 – Vcc ==> 3.3V
    2、引脚2 – 数据 ==> GPIO 16
    3、引脚3 – 未连接
    4、引脚4 – Gnd ==> Gnd
    一旦传感器连接好,我们必须在树莓派上安装它的库。

    安装DHT库:
    在你的树莓派上,从/home 到 /Documents
    1. cd Documents
    复制代码
    创建一个目录来安装库并移至此处:
    1. mkdir DHT22_Sensor
    2. cd DHT22_Sensor
    复制代码
    在你的浏览器上,转到Adafruit GitHub仓库:
    https://github.com/adafruit/Adafruit_Python_DHT
    通过下载zip link下载该库,并在你的树莓派最近创建的文件夹中解压缩文件。然后转到库的目录(当你解压缩文件时自动创建的子文件夹),然后执行以下命令:
    1. sudo python3 setup.py install
    复制代码
    从我的GitHub仓库中打开一个测试程序(DHT22_test.py)。
    1. import Adafruit_DHT
    2. DHT22Sensor = Adafruit_DHT.DHT22
    3. DHTpin = 16
    4. humidity, temperature = Adafruit_DHT.read_retry(DHT22Sensor, DHTpin)

    5. if humidity is not None and temperature is not None:
    6.     print('Temp={0:0.1f}*C  Humidity={1:0.1f}%'.format(temperature, humidity))
    7. else:
    8.     print('Failed to get reading. Try again!')
    复制代码
    使用以下命令执行程序:
    1. python3 DHT22_test.py
    复制代码
    下面的终端打印屏幕显示的结果。
    7.jpg


    为数据和视频显示创建一个Web服务器应用程序
    让我们用Flask创建另一个python 网络服务器,它将处理传感器和视频流捕获的数据。
    一旦我们的代码变得越来越复杂,我建议用Geany作为集成开发环境,你可以同时处理不同类型的文件(.py,.html和.css)
    下面的代码是在我们的Web服务器上使用的python脚本:
    1. from flask import Flask, render_template, Response
    2. app = Flask(__name__)

    3. # Raspberry Pi camera module (requires picamera package)
    4. from camera_pi import Camera

    5. import Adafruit_DHT
    6. import time

    7. # get data from DHT sensor
    8. def getDHTdata():      
    9.     DHT22Sensor = Adafruit_DHT.DHT22
    10.     DHTpin = 16
    11.     hum, temp = Adafruit_DHT.read_retry(DHT22Sensor, DHTpin)
    12.      
    13.     if hum is not None and temp is not None:
    14.         hum = round(hum)
    15.         temp = round(temp, 1)
    16.     return temp, hum


    17. @app.route("/")
    18. def index():
    19.     timeNow = time.asctime( time.localtime(time.time()) )
    20.     temp, hum = getDHTdata()
    21.      
    22.     templateData = {
    23.       'time': timeNow,
    24.       'temp': temp,
    25.       'hum' : hum
    26.     }
    27.     return render_template('index.html', **templateData)

    28. @app.route('/camera')
    29. def cam():
    30.     """Video streaming home page."""
    31.     timeNow = time.asctime( time.localtime(time.time()) )
    32.     templateData = {
    33.       'time': timeNow
    34.     }
    35.     return render_template('camera.html', **templateData)


    36. def gen(camera):
    37.     """Video streaming generator function."""
    38.     while True:
    39.         frame = camera.get_frame()
    40.         yield (b'--frame\r\n'
    41.                b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')


    42. @app.route('/video_feed')
    43. def video_feed():
    44.     """Video streaming route. Put this in the src attribute of an img tag."""
    45.     return Response(gen(Camera()),
    46.                     mimetype='multipart/x-mixed-replace; boundary=frame')


    47. if __name__ == '__main__':
    48.     app.run(host='0.0.0.0', port =80, debug=True, threaded=True)
    复制代码
    你可以从我的GitHub仓库获得python脚本appCam2.py。
    以上代码主要内容:
    • 每当有人点击 “clicks””on “”/”,即我们网页的主页面(index.html),就会生成请求;
    • 通过此请求,代码中的第一件事是使用函数从DHT读取传感器数据。
    • 接下来,从系统中检索用的实际时间。
    • 通过手头的数据,我们的脚本返回到网页(index.html):时间,温度和湿度对之前的请求的反馈。
    • 另外,当用户想要看到视频流时,可以调用页面“/相机”。在这种情况下,3个路径都会在最后一步中显示。并渲染camera.html。
      因此,我们来看看将用于构建前端的index.html,camera.html和style.css文件:
    index.html

    1. <!doctype html>
    2. <html>
    3. <head>
    4.     <title>MJRoBot Lab Sensor Data</title>
    5.     <link rel="stylesheet" href='../static/style.css'/>
    6. </head>
    7. <body>
    8.     <h1>MJRoBot Lab Sensor Data</h1>
    9.     <h3> TEMPERATURE   ==>  {{ temp }} oC</h3>
    10.     <h3> HUMIDITY (Rel.) ==>  {{ hum }} %</h3>
    11.     <hr>
    12.     <h3> Last Sensors Reading: {{ time }} ==> <a href="/"class="button">REFRESH</a></h3>
    13.     <hr>
    14.     <h3> MJRoBot Lab Live Streaming ==> <a href="/camera" class="button">LIVE</a></h3>
    15.     <hr>  
    16.     <p> @2018 Developed by MJRoBot.org</p>
    17. </body>
    18. </html>
    复制代码
    你可以在我的GitHub仓库中获得index. html

    camera.html
    基本上,这个页面与我们之前创建的页面相同,只是我们添加了一个按钮来返回到主页面。
    1. <html>
    2.   <head>
    3.     <title>MJRoBot Lab Live Streaming</title>
    4.     <link rel="stylesheet" href='../static/style.css'/>
    5.     <style>
    6.     body {
    7.         text-align: center;
    8.     }
    9.     </style>
    10.   </head>
    11.   <body>
    12.     <h1>MJRoBot Lab Live Streaming</h1>
    13.     <h3><img src="{{ url_for('video_feed') }}" width="80%"></h3>
    14.     <h3>{{ time }}</h3>
    15.     <hr>
    16.     <h3> Return to main page ==> <a href="/"class="button">RETURN</a></h3>   
    17.     <hr>
    18.     <p> @2018 Developed by MJRoBot.org</p>
    19.   </body>
    20. </html>
    21. You can get the file camera.html from my GitHub

    22. style.css

    23. body{
    24.     background: blue;
    25.     color: yellow;
    26.     padding:1%
    27. }

    28. .button {
    29.     font: bold 15px Arial;
    30.     text-decoration: none;
    31.     background-color: #EEEEEE;
    32.     color: #333333;
    33.     padding: 2px 6px 2px 6px;
    34.     border-top: 1px solid #CCCCCC;
    35.     border-right: 1px solid #333333;
    36.     border-bottom: 1px solid #333333;
    37.     border-left: 1px solid #CCCCCC;
    38. }
    复制代码
    你可以从我的GitHub仓库中获取camera.html

    style.css
    1. body{
    2.     background: blue;
    3.     color: yellow;
    4.     padding:1%
    5. }

    6. .button {
    7.     font: bold 15px Arial;
    8.     text-decoration: none;
    9.     background-color: #EEEEEE;
    10.     color: #333333;
    11.     padding: 2px 6px 2px 6px;
    12.     border-top: 1px solid #CCCCCC;
    13.     border-right: 1px solid #333333;
    14.     border-bottom: 1px solid #333333;
    15.     border-left: 1px solid #CCCCCC;
    16. }
    复制代码
    你可以从我的GitHub仓库中获取style.cs
    创建网络服务器环境
    这些文件必须以这样方式放在你的目录中:


    1. ├── camWebServer2
    2.                 ├── camera_pi.py
    3.                 └─── appCam2.py               
    4.                               ├── templates
    5.                               │            ├── index.html
    6.                               │            ├── camera.html
    7.                               └── static
    8.                                         └──── style.css
    复制代码
    现在,在终端上运行python脚本:
    1. sudo python3 appCam2.py
    复制代码
    可在以前的项目中添加视频流 (可选)
    8.jpg


    让我们在以前开发的项目中添加视频流**
    让我们使用我们以前的教程开发的内容:FROM DATA TO GRAPH. A WEB JOURNEY WITH FLASK AND SQLITE.
    记住,在该项目中,我们在数据库中记录了数据(温度和湿度),在网页上显示实际和历史数据:
    9.jpg


    我们这样做了,使用2个python脚本,一个用于在数据库上记录数据(logDHT.py),另一个用于通过Flask网络服务器(appDhtWebServer.py)在网页上显示数据:
    10.jpg


    创建网络服务器环境:
    下面是我的目录图。 Sensor_Database在我的树莓派中的/ Documents下:
    1. ├── Sensors_Database
    2. <span style="background-color: rgb(245, 245, 245); color: rgb(0, 0, 0); font-family: Consolas, &quot;Courier New&quot;, Courier, monospace; font-size: 14.4px; white-space: pre-wrap;">       </span>├── sensorsData.db
    3. <span style="background-color: rgb(245, 245, 245); color: rgb(0, 0, 0); font-family: Consolas, &quot;Courier New&quot;, Courier, monospace; font-size: 14.4px; white-space: pre-wrap;">       </span>├── logDHT.py
    4. <span style="background-color: rgb(245, 245, 245); color: rgb(0, 0, 0); font-family: Consolas, &quot;Courier New&quot;, Courier, monospace; font-size: 14.4px; white-space: pre-wrap;">       </span>└── dhtWebHistCam
    5. <span style="background-color: rgb(245, 245, 245); color: rgb(0, 0, 0); font-family: Consolas, &quot;Courier New&quot;, Courier, monospace; font-size: 14.4px; white-space: pre-wrap;">               </span>├── appDhtWebHistCam.py                 
    6. <span style="background-color: rgb(245, 245, 245); color: rgb(0, 0, 0); font-family: Consolas, &quot;Courier New&quot;, Courier, monospace; font-size: 14.4px; white-space: pre-wrap;">               </span>├── camera_pi.py
    7. <span style="background-color: rgb(245, 245, 245); color: rgb(0, 0, 0); font-family: Consolas, &quot;Courier New&quot;, Courier, monospace; font-size: 14.4px; white-space: pre-wrap;">               </span>└─── appCam2.py               
    8. <span style="background-color: rgb(245, 245, 245); color: rgb(0, 0, 0); font-family: Consolas, &quot;Courier New&quot;, Courier, monospace; font-size: 14.4px; white-space: pre-wrap;">                        </span>├── templates
    9. <span style="color: rgb(0, 0, 0); font-family: Consolas, &quot;Courier New&quot;, Courier, monospace; font-size: 14.4px; white-space: pre-wrap; background-color: rgb(245, 245, 245);">                        </span>│         ├── index.html
    10. <span style="color: rgb(0, 0, 0); font-family: Consolas, &quot;Courier New&quot;, Courier, monospace; font-size: 14.4px; white-space: pre-wrap; background-color: rgb(245, 245, 245);">                        </span>│         ├── camera.html
    复制代码
    这些文件可以在我的GitHub仓库上找到:dhtWebHistCam

    结果如下:


    结语
    一如既往,我希望这个项目能够帮助他人进入激动人心的电子世界!
    有关详细信息和最终代码,请访问我的GitHub仓库,Video-Streaming-with-Flask。



    3.jpg
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    关闭

    站长推荐上一条 /4 下一条

    手机版|爱板网

    GMT+8, 2018-10-16 12:18 , Processed in 0.121503 second(s), 15 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-5   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001056号

    Powered by Discuz!

    返回顶部