前段时间买了台小主机,替换树莓派做云盘/下载器,也安装了jellyfin和aria2等其他自建服务,性能比树莓派强很多。于是树莓派又吃灰了,这次用它做个监控摄像头。 外观外观 演示 制作 制作过程我没有记录下来,需要的物品如下: 树莓派 x1 树莓派专用摄像头 x1 MG995舵机(180度) x2 雪糕棍若干 热熔胶枪+热熔胶棒 5v电源+杜邦线若干 用外接电源给两个舵机供电,需要注意的是外接电源和树莓派必须共地,否则PWM不会起作用。两个舵机的信号线接树莓派gpio的第16和18个针。 代码 详细代码在Github仓库。前端用的react,后端是fastapi起服务,RPI.GPIO控制PWN,picamera控制摄像头。用websocket保持连接。 支持多个终端同时观看: # 输出 output: StreamingOutput @app.get("/stream/{pwd}") async def stream(pwd, background_tasks: fastapi.background.BackgroundTasks): # 校验密码 check = check_pwd(pwd) if check: return check # 做一个generator,用于自主控制关闭 def streamer(): while True: with output.condition: # picamera输出,参考的官方示例,此处省略 output.condition.wait() frame = output.frame yield (b'--FRAME\r\n' + b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n') g = streamer() # http断开时,关闭generator,防止卡死 background_tasks.add_task(lambda g: g.close(), g) return StreamingResponse(g, media_type="multipart/x-mixed-replace;boundary=FRAME") python的async和yield还是比较令人费解的,我研究了很久fastapi如何支持多个http stream连接,一开始只能一个连接,而且服务端会被block。查了一些资料,StreamingResponse既可以异步,也可以多线程,把def streamer()前面的async去掉就行了。 background_tasks.add_task(lambda g: g.close(), g)在连接断开时关闭generator。相比于flask把所有连接都当子线程处理(个人猜测),async的方式明显更好,用户可以自己控制异步还是多线程。 树莓派最近涨价地厉害,苦了爱折腾的人。虽然这个监控摄像头没啥用,而且花了好几天时间,但自己动手,完成后的小小成就感还是挺让人满足的
树莓派监控摄像头制作
前段时间买了台小主机,替换树莓派做云盘/下载器,也安装了jellyfin和aria2等其他自建服务,性能比树莓派强很多。于是树莓派又吃灰了,这次用它做个监控摄像头。
外观
外观
制作
制作过程我没有记录下来,需要的物品如下:
用外接电源给两个舵机供电,需要注意的是外接电源和树莓派必须共地,否则PWM不会起作用。两个舵机的信号线接树莓派gpio的第16和18个针。
代码
详细代码在Github仓库。前端用的
react
,后端是fastapi
起服务,RPI.GPIO
控制PWN,picamera
控制摄像头。用websocket保持连接。 支持多个终端同时观看:# 输出 output: StreamingOutput @app.get("/stream/{pwd}") async def stream(pwd, background_tasks: fastapi.background.BackgroundTasks): # 校验密码 check = check_pwd(pwd) if check: return check # 做一个generator,用于自主控制关闭 def streamer(): while True: with output.condition: # picamera输出,参考的官方示例,此处省略 output.condition.wait() frame = output.frame yield (b'--FRAME\r\n' + b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n') g = streamer() # http断开时,关闭generator,防止卡死 background_tasks.add_task(lambda g: g.close(), g) return StreamingResponse(g, media_type="multipart/x-mixed-replace;boundary=FRAME")
python的
async
和yield
还是比较令人费解的,我研究了很久fastapi如何支持多个http stream连接,一开始只能一个连接,而且服务端会被block。查了一些资料,StreamingResponse
既可以异步,也可以多线程,把def streamer()
前面的async
去掉就行了。background_tasks.add_task(lambda g: g.close(), g)
在连接断开时关闭generator。相比于flask
把所有连接都当子线程处理(个人猜测),async的方式明显更好,用户可以自己控制异步还是多线程。树莓派最近涨价地厉害,苦了爱折腾的人。虽然这个监控摄像头没啥用,而且花了好几天时间,但自己动手,完成后的小小成就感还是挺让人满足的