当前位置:   article > 正文

subprocess.Popen BrokenPipeError: [Errno 32] Broken pipe

brokenpipeerror: [errno 32] broken pipe

BrokenPipeError: [Errno 32] Broken pipe

问题描述

在向管道中写入数据的时候,稳定输入一段时间后,若长时间不再输入,则会报错:BrokenPipeError: [Errno 32] Broken pipe。且该子进程会进入sleep状态(即pipe.poll() == 1

解决方式

每次向管道中输入数据的时候,判断子进程的状态,非正常状态的话,重启子进程。

原代码

# 定义管道及ffmpeg命令,输出rtmp流的时候使用
command = ['ffmpeg',
           '-y',
           '-v', '24',  # 日志显示等级
           '-f', 'rawvideo',
           '-vcodec', 'rawvideo',
           '-pix_fmt', 'bgr24',
           '-s', str(self.width) + 'x' + str(self.height),
           '-i', '-',
           '-c:v', 'h264_nvenc',
           '-pix_fmt', 'yuv420p',
           '-f', 'rtsp',
           '-rtsp_transport', 'tcp',
           rtsp_url]
# 使用指定的GPU索引
my_env = os.environ.copy()
my_env["CUDA_VISIBLE_DEVICES"] = self.gpu_index
# 定义ffmpeg的子进程并启动
pipe = sp.Popen(command, stdin=sp.PIPE, env=my_env)
num = 0
while self._isLive:
    num += 1
    frame = self.realtime_queue.get()
    if num == 100:
        print("start sleep 50")
        time.sleep(50)
        print("end sleep 50")
    if num >= 100:
        print("超时后的,第%d次写入" % (num-99))
        time.sleep(5)
    pipe.stdin.write(frame.tostring())  # 存入管道用于直播
pipe.stdin.close()  # 关闭输入管道
pipe.communicate()  # 等待子进程关闭
  • 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

修改后代码

# 定义管道及ffmpeg命令,输出rtmp流的时候使用
command = ['ffmpeg',
           '-y',
           '-v', '24',  # 日志显示等级
           '-f', 'rawvideo',
           '-vcodec', 'rawvideo',
           '-pix_fmt', 'bgr24',
           '-s', str(self.width) + 'x' + str(self.height),
           '-i', '-',
           '-c:v', 'h264_nvenc',
           '-pix_fmt', 'yuv420p',
           '-f', 'rtsp',
           '-rtsp_transport', 'tcp',
           rtsp_url]
# 使用指定的GPU索引
my_env = os.environ.copy()
my_env["CUDA_VISIBLE_DEVICES"] = self.gpu_index
# 定义ffmpeg的子进程并启动
pipe = sp.Popen(command, stdin=sp.PIPE, env=my_env)
num = 0
while self._isLive:
    num += 1
    # poll()返回该子进程的状态,0正常结束,1sleep,2子进程不存在,-15 kill,None正在运行
    if pipe.poll() is not None:
    	time.sleep(3)
        print(pipe.poll())
        print("the popen of ffmpeg not run, restart this:%s" % self.name)
        pipe = sp.Popen(command, stdin=sp.PIPE, env=my_env)
       
    frame = self.realtime_queue.get()
    if num == 100:
        print("start sleep 50")
        time.sleep(50)
        print("end sleep 50")
    if num >= 100:
        print("超时后的,第%d次写入" % (num-99))
        time.sleep(5)
    try:
        pipe.stdin.write(frame.tostring())  # 存入管道用于直播
    except BrokenPipeError:
        print("Pushing the camera of %s appear ERROR:%s" % (self.name, rtsp_url))
        print(traceback.format_exc())
pipe.stdin.close()  # 关闭输入管道
pipe.communicate()  # 等待子进程关闭
  • 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
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/850899
推荐阅读
相关标签
  

闽ICP备14008679号