使用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代码示例

Video Streaming Demonstration

python 实时音视频 使用Flask+OpenCV实现浏览器/微信小程序的视频流传输  第1张

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

pip install opencv-python== 3.4.8.29

二、 Flask+微信小程序实现

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

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

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

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

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

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

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-pusher和live-player组件来实现视频流的推送和播放。

1. uni-app代码示例

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

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

live-player组件用于播放服务器端推送过来的视频流(服务器视频流—>前端),在小程序中将服务器端的视频流地址传递给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代码都是不需要修改的。

后记

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

推荐链接

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。