简易共享屏幕工具改进版

昨天心血来潮写了一篇关于简易共享屏幕工具的文章,发现也有一些阅读量,并且我对于它的效果不是很满意 ,实际呈现的帧率还是太低了。所以我今天换了更高效的方式来实现。
50 行代码简易屏幕共享工具

改进

降低分辨率
昨天那个测试的帧率低,最大的原因是我的电脑的分辨率有点高了,它是2.5K屏幕,所以我今天换成了 1920*1080 的屏幕来测试,效果就好很多了,基本都在 50 帧左右。

更换截屏库
更换了一个速度更快的截屏库,这个截屏库的速度很快,比昨天那个快多了,但是反应到实际的帧率上就低了,所以还是后续其他的操作太过于耗时,但是暂时也没有想到啥优化的好方法。

降低图片的质量
JPEG 格式的图片是可以选择压缩质量的,适当的调低质量可以提高处理的速度。

缺点
这个程序占用资源还是挺大的,运行程序之后,我的笔记本电脑风扇就开始运行了,不过这个可能也是因为帧率提高的原因吧。
在这里插入图片描述

在这里插入图片描述

代码

from flask import Flask, Response
from io import BytesIO
from PIL import Image, ImageDraw, ImageFont
import time
import dxcam

app = Flask(__name__)
# 整个应用只创建一个即可
camera = dxcam.create(device_idx=0, output_idx=1)  # output_idx 0 是第一块屏幕,1 是第二块屏幕
camera.start(target_fps=60, video_mode=True)

@app.route('/monitor', methods=['GET'])
def monitor():
    """获取屏幕数据并返回"""
    def gen_img():
        # 获取屏幕的全部区域
        fps = 0  # 帧率
        frame_count = 0 # 计算帧率,这是服务端生成的速率,到了客户端还会更低
        start_time = time.perf_counter()
        buffer = BytesIO()
        while True:
            reset_buffer(buffer)  # 每次重置buffer,方便复用
            t1 = time.perf_counter()
            yield get_frame(buffer, fps)
            print("get frame fps: ", 1.0 / (time.perf_counter() - t1))
            frame_count += 1
            elapsed_time = time.perf_counter() - start_time
            if elapsed_time >= 1:
                fps = frame_count // elapsed_time
                frame_count = 0
                start_time = time.perf_counter()
                print("real frame fps: ", fps)
    return Response(gen_img(), mimetype="multipart/x-mixed-replace; boundary=frame")

def get_frame(buffer, fps):
    """
    获取一帧,然后处理成jpeg并返回二进制数据
    """
    image_array = camera.get_latest_frame()
    img = Image.fromarray(image_array)
    if fps > 0:
        img = add_fps(img, fps)
    img.save(buffer, format="JPEG", quality=20)
    return (b'--frame\r\n' +
            b'Content-Type: image/jpeg\r\n\r\n' + buffer.getvalue() + b'\r\n')


def reset_buffer(buffer):
    # 重置buffer,方便复用
    buffer.truncate(0)
    buffer.seek(0)


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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值