树莓派4b,使用picamer2进行rtsp推流时,摄像头推送固定10分钟左右就会断开
环境
picamera2 0.3.18
python 3.11.2
关键代码
import io
import threading
import time
from picamera2 import Picamera2
from picamera2.encoders import H264Encoder
# from picamera2.outputs import FfmpegOutput
from third.Out import FfmpegOutput
from device.models import Cam
from manager.device.index import Device, DeviceManager, Topic
from manager.protocol.index import ProtocolManager
from tool.base64_tool import bytes_to_base64
from tool.log.log_uru import Logger
from tool.time_tool import ymd_hms_time
class Camera(Device):
def get_protocol(self):
return "Mqtt"
def __init__(self, sn):
super().__init__(sn, {}, {}, {})
self.rtsp = None
self.topic = Topic.camera_post
self.lug = Logger().get_logger
self.picam2 = Picamera2()
# Picamera2.set_logging(Picamera2.DEBUG)
# rtsp推流的编码
self.encoder = None
resolution = (1280, 720)
self.picam2.configure(self.picam2.create_video_configuration(main={"size": resolution}))
self.picam2.start()
self.lug.info("Camera initialized")
# self.start_rtsp()
self.push_task()
def error_callback(self, e):
"""
picamera2异常断开的回调函数
"""
self.lug.error("Camera Error {}", e)
# 重连
# self.picam2.stop_encoder(self.encoder)
# self.start_rtsp()
# self.lug.warning("reconnecting...")
def start_rtsp(self):
# self.encoder = H264Encoder(bitrate=1000000)
self.encoder = H264Encoder(bitrate=1000000, repeat=True, iperiod=15, framerate=15)
self.rtsp = FfmpegOutput("-f rtsp rtsp://47.109.65.247/live/test")
self.rtsp.error_callback = self.error_callback
self.encoder.output = self.rtsp
self.picam2.start_encoder(self.encoder)
def __capture_pic(self):
"""
抓取图片
:return:
"""
time.sleep(1)
try:
while True:
data = io.BytesIO()
time.sleep(1)
self.picam2.capture_file(data, format='jpeg')
b = data.getvalue()
data.close()
base_64 = bytes_to_base64(b)
self.lug.debug("推送图片大小:{}", len(b))
ProtocolManager.send_msg("Mqtt", self.topic,
Cam(sn=self.sn, action="capture", val=base_64, time=ymd_hms_time()))
time.sleep(60 * 5)
except Exception as e:
self.lug.error("抓取图片异常:{}", e)
def push_task(self):
"""
开启定时任务推送数据
"""
threading.Thread(target=self.__capture_pic, daemon=True).start()
def stop(self):
"""
停止camera
:return:
"""
self.rtsp.stop()
self.picam2.stop_encoder()
self.picam2.stop()
启动方法是实例化当前类,然后主线程使用while true。
异常
2024-05-14 17:03:46.468 | ERROR | device.camera.index:error_callback:40 - Camera Error [Errno 32] Broken pipe