22-1 web传输视频 Opencv+usb摄像头 树莓派+Flask实现视频流媒体WEB服务器


实用

https://blog.csdn.net/u012675539/article/details/53306335

 

第一篇 讲解原理

https://blog.miguelgrinberg.com/post/video-streaming-with-flask

第二篇 加入多线程可以直接用

https://github.com/xitu/gold-miner/blob/master/TODO1/flask-video-streaming-revisited.md

https://zhuanlan.zhihu.com/p/54292646

 

链接:https://pan.baidu.com/s/16iyO_XR_JhhHn184RVH6Hw
提取码:6dq6

 

http://shumeipai.nxez.com/2018/07/17/raspberry-pi-cam-pan-tilt-control-over-local-inter.html

 

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

 http://shumeipai.nxez.com/2018/07/03/video-streaming-web-server-with-flask.html

 

1最简单的模式

opencv

单线程

 

 

 

 

# main.py
from flask import Flask, render_template, Response
from camera import VideoCamera

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

def gen(camera):
    while True:
        frame = camera.get_frame()
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')

@app.route('/video_feed')
def video_feed():
    return Response(gen(VideoCamera()),
                    mimetype='multipart/x-mixed-replace; boundary=frame')

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)

  

 

# camera.py
import cv2

class VideoCamera(object):
    def __init__(self):
        # Using OpenCV to capture from device 0. If you have trouble capturing
        # from a webcam, comment the line below out and use a video file
        # instead.
        self.video = cv2.VideoCapture(0)
        # If you decide to use video.mp4, you must have this file in the folder
        # as the main.py.
        # self.video = cv2.VideoCapture('video.mp4')

    def __del__(self):
        self.video.release()

    def get_frame(self):
        success, image = self.video.read()
        # We are using Motion JPEG, but OpenCV defaults to capture raw images,
        # so we must encode it into JPEG in order to correctly display the
        # video stream.
        ret, jpeg = cv2.imencode('.jpg', image)
        # 对于 python2.7 或者低版本的 numpy 请使用 jpeg.tostring()
        return jpeg.tobytes()

  

 

 

<html>
  <head>
    <title>Video Streaming Demonstration</title>
  </head>
  <body>
    <h1>Video Streaming Demonstration</h1>
    <img src="{{ url_for('video_feed') }}">
  </body>
</html>

  

简单几步实现RTMP直播

 https://blog.csdn.net/steveyg/article/details/86488706?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

 

主服务器

 

#!/usr/bin/env python2
# -*- coding: utf-8 -*-

dianliang_v=100

import os
from configparser import  ConfigParser
import datetime
#存一个新数据
def writeconfig(time,dianliang):
 
    conf_path = "config.ini" #配置文件路径
    config = ConfigParser()
    config.read(conf_path, encoding="utf-8")
    
    #获取当前长度
    secs=config.sections()
    print(len(secs))
    
    config.add_section(str(len(secs)+1))
    config.set(str(len(secs)+1), '时间:', time)
    config.set(str(len(secs)+1), '电量:', dianliang)
    #保存修改
    with open(conf_path, "w") as fw:
        config.write(fw) 

import time
import RPi.GPIO as GPIO

GPIO.setwarnings(False) 
GPIO.setmode(GPIO.BCM)

pinA1=12  # 左电机1
pinA2=16  # 左电机 2
pinB1=20  # 右电机 1
pinB2=21  # 右电机 2

pin_alram=22  # 报警器

GPIO.setup(pinA1, GPIO.OUT) #设置脚为输出模式
GPIO.setup(pinA2, GPIO.OUT) #设置脚为输出模式
GPIO.setup(pinB1, GPIO.OUT) #设置脚为输出模式
GPIO.setup(pinB2, GPIO.OUT) #设置脚为输出模式
GPIO.setup(pin_alram, GPIO.OUT) #设置脚为输出模式

    
go_time_intever=0.2  # 运动步长(秒) 通过改时间来改每一步的运动距离 
def go_ahead():
    print ("go_ahead")
    GPIO.output(pinA1, GPIO.HIGH)  #  A往前转
    GPIO.output(pinA2, GPIO.LOW)  #灭
    GPIO.output(pinB1, GPIO.HIGH)  # B往前转
    GPIO.output(pinB2, GPIO.LOW)  #灭
    time.sleep( go_time_intever )   #延时 秒
    
def go_back():
    print ("go_ahead")
    GPIO.output(pinA1, GPIO.LOW)  #  A往前转
    GPIO.output(pinA2, GPIO.HIGH)  #灭
    GPIO.output(pinB1, GPIO.LOW)  # B往前转
    GPIO.output(pinB2, GPIO.HIGH)  #灭
    time.sleep( go_time_intever )   #延时 秒
    
def stop():
    print ("stop")
    GPIO.output(pinA1, GPIO.LOW)  #  A停止
    GPIO.output(pinA2, GPIO.LOW)  #灭
    GPIO.output(pinB1, GPIO.LOW)  # B停止
    GPIO.output(pinB2, GPIO.LOW)  #灭
    time.sleep( go_time_intever )   #延时 秒    
     
def tuen_left():
    print ("tuen_left")
    GPIO.output(pinA1, GPIO.LOW)  # A往后转
    GPIO.output(pinA2, GPIO.HIGH)  #灭
    GPIO.output(pinB1, GPIO.HIGH)  #B往前转
    GPIO.output(pinB2, GPIO.LOW)  #灭
    time.sleep( go_time_intever )   #延时 秒

     
def turn_right():
    print ("turn_right")
    GPIO.output(pinA1, GPIO.HIGH)  #A往前转
    GPIO.output(pinA2, GPIO.LOW)  #灭
    GPIO.output(pinB1, GPIO.LOW)  #B往后转
    GPIO.output(pinB2, GPIO.HIGH)  #灭
    time.sleep( go_time_intever )   #延时 秒
    
#from flask import Flask, render_template, Response,request,redirect,url_for
from flask import Flask, render_template, Response,request,redirect,url_for
from camera import VideoCamera
import cv2

video=VideoCamera()
app = Flask(__name__)

@app.route('/')
def index():
    return render_template('dengku.html')

@app.route('/use')
def use():
    return render_template('index1.html')

@app.route('/login', methods = ["GET","POST"])
def login():
    name = request.args.get("username")
    password = request.args.get("userpwd")
    print('待验证账户:'+name+"   待验证密码:"+password)
    if name== 'admin' and password=='admin':
       
        #return redirect(url_for('use'))
        return '登录成功'
    else:
        return '登录失败'
 
@app.route('/move', methods = ["GET","POST"])
def move():
    fx = request.args.get("movefx")
    #print('运动方向:'+fx)
    if fx=='qian':
        print('前行')
        go_ahead()
        fx='前行'
    elif fx=='hou':
        print('后退')
        go_back()
        fx='后退'
    elif fx=='zuo':
        print('左转')
        tuen_left()
        fx='左转'
    elif fx=='you':
        print('右转')
        turn_right()
        fx='右转'
    elif fx=='stop':
        print('停止')
        stop()
        fx='停止'
    else:
        pass
    return fx

# 各种事情处理
@app.route('/do', methods = ["GET","POST"])
def do():
     ting = request.args.get("dowhat")
     #拍照
     if ting=="paizhao":
         img = video.get_img()
         cv2.namedWindow('image',0)
         cv2.imshow('image',img)
         cv2.waitKey(10)
         cv2.imwrite('save/image.jpg', img)        
         ting='拍照成功'
         print(ting)
     elif ting=="close_alram":
         ting='警报关闭'
         GPIO.output(pin_alram, GPIO.LOW)  #低电平
         print(ting)
         pass
     elif ting=="open_alram":
         ting='警报打开'
         GPIO.output(pin_alram, GPIO.HIGH)  #高电平
         print(ting)
         pass
     elif ting=="show_etc":
         ting='当前电量:'
         global dianliang_v
         dianliang_v=dianliang_v-1
         nowTime=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
         writeconfig(str(nowTime),str(dianliang_v))
         ting=ting+str(dianliang_v)+"--"+str(nowTime)
         print(ting)
         pass    
     return ting

 # 2添加 电量
 # 3添加 config保存

    
def gen(camera):
    while True:
        frame = camera.get_frame()
        yield (b'--frame\r\n'
                b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')

@app.route('/video_feed')
def video_feed():
    return Response(gen(video),
                    mimetype='multipart/x-mixed-replace; boundary=frame')

if __name__ == '__main__':
    app.run(host='0.0.0.0',port='8080')

  相机类

# camera.py
import cv2

class VideoCamera(object):
    def __init__(self):
        # Using OpenCV to capture from device 0. If you have trouble capturing
        # from a webcam, comment the line below out and use a video file
        # instead.
        self.video = cv2.VideoCapture(0)
        # If you decide to use video.mp4, you must have this file in the folder
        # as the main.py.
        # self.video = cv2.VideoCapture('video.mp4')

    def __del__(self):
        self.video.release()

    def get_img(self):
        success, image = self.video.read()
        return image
    
    def get_frame(self):
        success, image = self.video.read()
        # We are using Motion JPEG, but OpenCV defaults to capture raw images,
        # so we must encode it into JPEG in order to correctly display the
        # video stream.
        ret, jpeg = cv2.imencode('.jpg', image)
        # 对于 python2.7 或者低版本的 numpy 请使用 jpeg.tostring()
        return jpeg.tobytes()

  网页

    <html>
      <head>
      <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
      
        <title>视频流测试</title>
        
      </head>
      <body>
        <h1>视频流演示</h1>
         <script type="text/javascript">
           
              
              function GETmethod(msg) {
                     var xhttp = new XMLHttpRequest();
                      xhttp.onreadystatechange = function() {
                        if (this.readyState == 4 && this.status == 200) {
                         document.getElementById("demo").innerHTML = this.responseText;
                          alert("登录成功!")
                         if(this.responseText=="登录成功"){
                          window.location.href="use"}
                        }
                      };
                      xhttp.open("GET", msg, true);
                      xhttp.send();
                    }
              
              
                 //button 按钮,结合onclick事件,验证和提交表单
              function checkForm(){
                    //判断用户名是否为空
                    if(document.form1.username.value==""){
                            window.alert("用户名不能为空");
                    }else{
                        //方法一 使用form对象的submit()方法,实现参数提交。整体刷新网页,无法获取返回值做逻辑控制
                        //document.form1.submit();
                        //方法二 使用xjax提交,局部刷新网页 可以获取返回值
                        msg=  'login?'+'username='+document.form1.username.value +'&userpwd='+document.form1.userpwd.value
                        GETmethod(msg)
                    }
              }
              
              
        </script>
        
        <form name="form1" method="get" action="login">
          用户名:<input type="text" name="username" />
          密码:<input type="password" name="userpwd" />
          <input type="button" value="登录验证" onclick="checkForm()" />
        </form>
        
        <div id="demo">
          <h1>状态提示...</h2>
        </div>

     
        
       
        
     
      </body>
    </html>

  


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM