python中的gstreamer管道未正确保存.mp4视频

2024-04-27 00:16:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个Python脚本,通过gstreamer记录从四个摄像头到mp4的流。我定义了一个信号,以便在按下Ctrl-C时捕获终止,并且工作正常。在gstreamer管道本身中,我在源numbuffers = 600添加了一个属性,因为我希望捕获在600帧之后停止,如果在此之前我没有按Ctrl-C

我的问题是,如果我通过键盘中断所有四个mp4视频都正确保存,但如果我让它在600帧后自行完成,第二到第四个视频就可以了,而第一个视频将“没有可播放的流”,即使与其他视频大小相同

我不明白为什么只有第一个视频没有正确保存或关闭,有什么提示吗? 这是我的代码:

import gi
import signal
import threading
import logging
from time import time, sleep
gi.require_version('Gst', '1.0')
from gi.repository import Gst, GObject

logging.basicConfig(level=logging.INFO)

def on_message(bus: Gst.Bus, message: Gst.Message, loop: GObject.MainLoop):
    mtype = message.type
    """
        Gstreamer Message Types and how to parse
    """
    if mtype == Gst.MessageType.EOS:
        logging.info("End-of-stream\n")
        loop.quit()

    elif mtype == Gst.MessageType.ERROR:
        err, debug = message.parse_error()
        logging.info("Warning: %s: %s\n" % (err, debug))
        loop.quit()

    elif mtype == Gst.MessageType.WARNING:
        err, debug = message.parse_warning()
        logging.info("Error: %s: %s\n" % (err, debug))

    return True


def signal_handler(signal, frame):
    for i in range(0,n_cams):
        pipelines[i].send_event(Gst.Event.new_eos())

signal.signal(signal.SIGINT, signal_handler)

# Initialize
GObject.threads_init()
Gst.init(None)

n_cams = 4
buses = []
pipelines = []

for i in range(0,n_cams):
    logging.info("Starting camera " + str(i))

    command = ("nvarguscamerasrc sensor-id={} num-buffers=600 ! "
            "video/x-raw(memory:NVMM), width=(int)1920, height=(int)1080, format=(string)NV12, framerate=(fraction)30/1 ! "
            "queue max-size-buffers=4 leaky=2 ! "
            "nvv4l2h265enc control-rate=1 bitrate=8000000 ! video/x-h265, stream-format=(string)byte-stream ! "
            "h265parse ! qtmux ! filesink location=test_{}.mp4").format(i)

    logging.info("Parse launch " + command)
    pipelines.append(Gst.parse_launch(command))


loop = GObject.MainLoop()

for i in range(0,n_cams):
    buses.append(pipelines[i].get_bus())
    buses[i].add_signal_watch()
    buses[i].connect("message", on_message, loop)

logging.info("Starting pipelines")

for i in range(0,n_cams):
    pipelines[i].set_state(Gst.State.PLAYING)

loop.run()

# stop
for i in range(0,n_cams):
    pipelines[i].send_event(Gst.Event.new_eos())
    pipelines[i].set_state(Gst.State.NULL)


Tags: inimportinfoloopmessagefor视频signal
1条回答
网友
1楼 · 发布于 2024-04-27 00:16:21

首先,我认为你在ctrl-c的情况下是幸运的。在ctrl情况下,当您发送EOS时,您应该等待EOS到达总线,然后再将管道状态设置为NULL

与您实际描述的问题类似。您有4条管道,但只有一个主回路。在第一条管道到达EOS后退出循环。相反,您应该等到所有管道都到达EOS

另外,我认为# stop之后的send_事件实际上没有任何作用

相关问题 更多 >