Flask介绍:

Flask是一个使用python编写的轻量化web应用框架,它的作用主要用于开发Web应用程序。Web框架(Flask)致力于如何生成HTML代码,而Web服务器(nginx)用于处理和响应HTTP请求。
Socket则提供了一种网络通信的底层接口,允许开发人员直接访问网络协议栈,它提供了对网络套接字的编程接口,允许应用程序直接发送和接收数据包。

HTTP图传:

关于实时视频传输,业界已经有非常多成熟方案,分别应用在不同需求场景。
例如RTMP 、RTSP、hls 、FFMPEG 、nginx-rtmp服务器
同时还会涉及到时音视频的底层传输协议问题(TCP,UDP,QUIC)
基本上原理就是有一个中转服务器(比如Nginx),FFMPEGD推流,html拉流。那Django干啥?控制页面拉流。或者说python干啥?拉流。还有一些是用opencv做推流的,

通过 stream 形式,将图片通过 http 协议输出到客户端。只要客户端支持 multipart/x-mixed-replace 头,就可以从响应中读取视频帧,chrome、Firefox 在这一点上有比较好的支持,只要使用 标签就可以实现视频流效果:

下面是源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

import os
import re
import threading as th
import time

from iot import iRGB,cam
from maix import image,app

from flask import Flask, Response, redirect, url_for
from werkzeug.serving import make_server

flask_app = Flask(__name__) # Flask app

pause_event = th.Event()
show_fps = False
quality = 70

class Server(object):

def __init__(self) -> None:
self.image_event = th.Event()
self.running = False
self.fpc = FPSCounter()
flask_app.route("/")(self.http_index)
flask_app.route("/stream")(self.http_stream)
flask_app.route("/snapshot")(self.http_snapshot)

def http_index(self):
return redirect(url_for("http_stream"))

def stream_worker(self):
while self.running:
while pause_event.is_set():
time.sleep(1)
self.img = cam.read()
if show_fps:
self.img.draw_string(
10, 10, f"{self.fpc.get():.3f}", color=iRGB(255, 0, 0), scale=2
)
self.jpg = self.img.to_jpeg(quality)
if self.jpg is None:
print("Encoding error!")
app.set_exit_flag(True)
self.image_event.set()

def get_stream(self):
while self.running:
self.image_event.wait()
self.image_event.clear()
if self.jpg is None:
continue
self.fpc.update()
yield (
b"Content-Type: data/jpeg\r\n\r\n"
+ self.jpg.to_bytes(False)
+ b"\r\n\r\n--frame\r\n"
)

def get_snapshot(self):
self.image_event.wait()
self.image_event.clear()
self.png = self.img.to_format(image.Format.FMT_PNG)
return self.png.to_bytes()

def http_stream(self):
return Response(
self.get_stream(), mimetype="multipart/x-mixed-replace; boundary=frame"
)

def http_snapshot(self):
return Response(self.get_snapshot(), mimetype="image/png")

def start_server(self, host, port, block=False):
"""
Start the server non-blocking
"""
assert not self.running, "Server already running"
self.running = True
self.stream_thread = th.Thread(target=self.stream_worker, daemon=True)
self.stream_thread.start()
self.server = make_server(host, port, flask_app, threaded=True, processes=1)
self.server.log_startup()
if block:
self.server.serve_forever()
else:
self.server_thread = th.Thread(
target=self.server.serve_forever, daemon=True
)
self.server_thread.start()

def stop_server(self):
"""
Stop the server
"""
assert self.running, "Server not running"
self.running = False
self.server.shutdown()
self.server_thread.join()
self.stream_thread.join()


def get_ip_list():
lst = []
try:
content = os.popen("ifconfig").read()
for line in content.splitlines():
if line.strip().startswith("inet"):
res = re.search(r"addr:(\d+\.\d+\.\d+\.\d+)", line)
if res:
lst.append(res.group(1))
except Exception:
pass
return lst if lst else ["0.0.0.0"]

参考文章

使用 multipart/x-mixed-replace 实现 http 实时视频流
(python)【学习记录】http传输图片
简易HTTP串流服务器2.0

低延迟视频传输 UDP JPEG图像压缩 opencv
关于摄像头推流拉流的一些内容
OpenCV Nginx 实现局域网视频推流/拉流

TCP实时图像传输

计算机网络体系结构
HTTP 和 TCP 我知道,但是套接字是什么鬼?
HTTP协议格式详解之报头(HTTP header)、请求正文(body)
HTTP Multipart 概述:一步步理解复杂数据传输