使用Flask+OpenCV实现浏览器/微信小程序的视频流传输

使用Flask+OpenCV实现浏览器和微信小程序的视频流传输

目录

前言
一、 Flask+浏览器实现
二、 Flask+微信小程序实现
三、Flask+uni-app小程序实现
后记

前言

近期在做的东西涉及到实时视频的处理,碰到一些问题,因此将之记录下来,便于日后翻看,同时也希望能给遇到同样问题的小伙伴提供帮助。

一、Flask+浏览器实现

实现代码如下:

分为 app.py 和index.html。

1. Flask代码示例

# -----------------------------
# app.py
# -----------------------------
from flask import Flask, render_template, Response
import cv2

class VideoCamera(object):
    def __init__(self):
        # 通过opencv获取实时视频流
        self.video = cv2.VideoCapture(0) 
    
    def __del__(self):
        self.video.release()
    
    def get_frame(self):
        success, image = self.video.read()
        # 因为opencv读取的图片并非jpeg格式,因此要用motion JPEG模式需要先将图片转码成jpg格式图片
        ret, jpeg = cv2.imencode('.jpg', image)
        return jpeg.tobytes()

app = Flask(__name__)

@app.route('/')  # 主页
def index():
    # jinja2模板,具体格式保存在index.html文件中
    return render_template('index.html')

def gen(camera):
    while True:
        frame = camera.get_frame()
        # 使用generator函数输出视频流, 每次请求输出的content类型是image/jpeg
        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, port=5000)

2. 浏览器HTML代码示例

<!-- ———————————————————————— -->
<!-- index.html -->
<!-- ———————————————————————— -->
<html>
  <head>
    <title>Video Streaming Demonstration</title>
  </head>
  <body>
    <!-- 使用Jinja2模板,指向路由video_feed -->
    <img src="{
     
     { url_for('video_feed') }}">
  </body>
</html>

此处需要注意的是,cv2这个库的版本有很多,如果出现一些bug一直解决不了,建议降低版本试试。

pip install opencv-python== 3.4.8.29

二、 Flask+微信小程序实现

微信小程序支持展示以下几种格式的视频流:

  1. FLV格式:FLV(Flash Video)是一种Adobe Flash技术中使用的视频流格式,通常使用在Web播放器和一些视频网站上。微信小程序中可以通过live-player组件来展示FLV格式的视频流。
  2. HLS格式:HLS(HTTP Live Streaming)是一种苹果公司开发的视频流协议,通过分割视频流为短片段,利用HTTP协议传输,实现了较好的稳定性和兼容性。微信小程序中可以通过live-player组件来展示HLS格式的视频流。
  3. RTMP格式:RTMP(Real Time Messaging Protocol)是Adobe公司开发的一种视频流协议,广泛应用于直播领域。微信小程序中可以通过live-player组件来展示RTMP格式的视频流。

需要注意的是,展示视频流需要满足微信小程序的一些要求,例如视频流地址需要使用https协议、服务器需要支持CORS跨域等。如果使用的是自己的服务器来提供视频流,需要确保服务器满足这些要求。

在微信小程序中展示实时视频流,可以使用小程序自带的live-player组件。live-player组件支持播放RTMP、HLS、FLV等格式的实时视频流。需要将实时视频流的地址传递给live-player组件的src属性,并设置一些其他的属性,例如modeautoplaymuted等,来控制视频的播放行为。

1. 微信小程序前端代码示例

前端中调用视频流服务:在微信小程序的前端中,可以使用live-player组件来播放视频流。在live-player组件的src属性中,设置Flask应用程序的视频流服务地址即可。

<live-player src="https://your_flask_server.com/video_feed" mode="live"></live-player>

2. 后端Flask代码示例:

import cv2
from flask import Flask, Response
from flask_cors import CORS

app = Flask(__name__)
# 进行跨域处理
CORS(app)

# 用于不断地读取摄像头或视频文件中的帧,并将其转换成JPG格式的图片
def generate_frames():
    camera = cv2.VideoCapture(0)  # 打开摄像头
    while True:
        success, frame = camera.read()
        if not success:
            break
        ret, buffer = cv2.imencode('.jpg', frame)
        frame = buffer.tobytes()
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')

@app.route('/video_feed')
def video_feed():
    # 这是一种特殊的HTTP响应格式,用于在响应数据中分隔多个数据块。
    # Flask应用程序会将这些数据块发送给客户端,客户端可以将它们转换成视频流进行播放。
    return Response(generate_frames(),
                    mimetype='multipart/x-mixed-replace; boundary=frame')

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

三、Flask+uni-app小程序实现

上面第二部分提到的,是针对Flask和微信小程序的视频流展示方式,如果要在uni-app小程序中展示实时视频流,需要使用uni-app提供的组件来实现。

在uni-app中,可以使用live-pusherlive-player组件来实现视频流的推送和播放。

1. uni-app代码示例

live-pusher组件用于推送实时视频流到服务器(前端视频流—>服务器),需要在小程序中使用微信开发者工具提供的摄像头API获取摄像头的视频流,并将其传递给live-pusher组件。下面是一个简单的示例代码:

<live-pusher url="rtmp://your_server.com/live/stream" mode="RTC"></live-pusher>

在上面的代码中,url属性设置了视频流推送的地址,mode属性设置了推送模式,这里使用的是RTC模式。可以根据自己的实际情况设置这些属性。

live-player组件用于播放服务器端推送过来的视频流(服务器视频流—>前端),在小程序中将服务器端的视频流地址传递给live-player组件即可。下面是一个简单的示例代码:

<live-player src="http://your_server.com/live/stream" mode="live"></live-player>

在上面的代码中,src属性设置了视频流的地址,mode属性设置了播放模式,这里使用的是live模式。可以根据自己的实际情况设置这些属性。

需要注意的是,在实际应用中,可能需要对视频流进行编码、解码、压缩等处理,以便在网络上高效地传输。

2. Flask代码示例

import cv2
from flask import Flask, Response
from flask_cors import CORS

app = Flask(__name__)
# 进行跨域处理
CORS(app)

# 用于不断地读取摄像头或视频文件中的帧,并将其转换成JPG格式的图片
def generate_frames():
    camera = cv2.VideoCapture(0)  # 打开摄像头
    while True:
        success, frame = camera.read()
        if not success:
            break
        ret, buffer = cv2.imencode('.jpg', frame)
        frame = buffer.tobytes()
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')

@app.route('/video_feed')
def video_feed():
    # 这是一种特殊的HTTP响应格式,用于在响应数据中分隔多个数据块。
    # Flask应用程序会将这些数据块发送给客户端,客户端可以将它们转换成视频流进行播放。
    return Response(generate_frames(),
                    mimetype='multipart/x-mixed-replace; boundary=frame')

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

是的没错,看完你会发现其实第三和第二的Flask代码示例是一样的,为什么呢?

因为后端的代码并不关心前端使用的是什么框架,它只需要根据标准的HTTP协议接收和响应请求即可。因此,无论使用什么前端框架来展示视频流,后端的Flask代码都是不需要修改的。


后记

本人也是第一次接触,如有错误之处,请各位指教,我们共同探讨进步。

猜你喜欢

转载自blog.csdn.net/weixin_46064809/article/details/129772515