好几个月没写博客了,主要是没有时间,因为都去干其他事情了,不过也没有什么成果。今天就抽出来时间来凑一篇文章吧。随着 AI 越来越深入日常生活,我现在编程已经离不开 AI,今天这个代码也是的,几乎都是可以 AI 生成了。不过,我本身也了解这些技术,对于我要做的事情也有一个大致的思路。所以,更重要的还是提高我们自己的能力,这样 AI 才可以放大我们的优势,扩展知识面。
思路
它的思路很简单,程序不断的截屏然后发送给浏览器去显示,效果也还凑合吧。这里最重要的就是 multipart/x-mixed-replace; boundary=frame
这个首部的使用了,好几年前还在大学时,我买了一个树莓派+摄像头,使用一个开源的软件叫 motion,搭建了一个局域网的视频监控。这个 motion 的网页端就是使用该首部实现的,因为我当时很好奇就去了解了它。
代码
如果要运行代码需要安装对应的依赖:
pip install flask, mss, PIL
import time
from io import BytesIO
from flask import Flask, Response
import mss
from PIL import Image, ImageDraw, ImageFont
app = Flask(__name__)
@app.route('/monitor', methods=['GET'])
def monitor():
"""获取屏幕数据并返回"""
def gen_img():
with mss.mss() as sct:
# 获取屏幕的全部区域
screen = sct.monitors[1]
buffer = BytesIO()
fps = 0 # 帧率
frame_count = 0 # 计算帧率,这是服务端生成的速率,到了客户端还会更低
start = time.time()
while True:
# 抓取屏幕并返回
screenshot = sct.grab(screen)
# 将截图数据转换为 JPEG 格式的二进制数据
img = Image.frombytes("RGB", screenshot.size, screenshot.bgra, "raw", "BGRX")
if fps > 0:
img = add_fps(img, fps)
img.save(buffer, format="JPEG")
jpeg_data = buffer.getvalue()
yield (b'--frame\r\n' +
b'Content-Type: image/jpeg\r\n\r\n' + jpeg_data + b'\r\n')
# 重置buffer,方便复用
buffer.seek(0)
buffer.truncate(0)
frame_count += 1
elapsed = time.time() - start
if elapsed >= 1:
fps = frame_count // elapsed
frame_count = 0
start = time.time()
return Response(gen_img(), mimetype="multipart/x-mixed-replace; boundary=frame")
def add_fps(img, fps):
"""在图片上添加fps"""
draw = ImageDraw.Draw(img)
draw.text((100, 100), f"fps: {fps}", (255, 0, 0), ImageFont.truetype("arial.ttf", 100))
return img
if __name__ == '__main__':
print("monitoring...")
app.run("127.0.0.1", 9000)
演示
如果只是演示单纯的操作,可以达到十几fps,虽然非常低,但是实际体验也可以了。
如果是观看视频的话,那就不太行了,fps立马就降下去了。