使用 Gstreamer 和 Nvidia AGX Orin 进行 RTSP 视频输入和录制视频

问题描述 投票:0回答:1

我正在尝试通过 gstreamer python 绑定设置 gstreamer 管道。 管道应该使用摄像头将镜头记录到文件(并滚动它们),它还应该支持连接到设备的客户端通过 RTSP 实时查看它们。 当管道写入文件时,它仅在流冻结之前显示 1 到 2 秒。 我尝试过对脚本进行各种更改,但无法使其在几帧之外工作。 这是我的代码

import gi
import os
import signal
import sys

gi.require_version('Gst', '1.0')
gi.require_version('GstRtspServer', '1.0')
from gi.repository import Gst, GstRtspServer, GLib

Gst.init(None)

def signal_handler(sig, frame):
    print("Caught signal, cleaning up and stopping the main loop.")
    mainloop.quit()

def on_new_sample(appsink, appsrc):
    sample = appsink.emit("pull-sample")
    if sample:
        appsrc.emit("push-sample", sample)
    return Gst.FlowReturn.OK

BITRATE = 2000000

main_pipeline_str = f"""
v4l2src device=/dev/video7 do-timestamp=true ! video/x-raw, format=YUY2, width=1920, height=1080, framerate=30/1 ! nvvidconv ! video/x-raw(memory:NVMM) ! nvv4l2h264enc bitrate={BITRATE} preset-level=4 insert-sps-pps=true ! tee name=t
t. ! h264parse ! splitmuxsink location=/external/video_%05d.mkv max-size-time=100000000000 max-files=10
t. ! h264parse ! appsink name=appsink emit-signals=true sync=false
"""

main_pipeline = Gst.parse_launch(main_pipeline_str)
main_pipeline.set_state(Gst.State.PLAYING)
appsink = main_pipeline.get_by_name("appsink")

def error_cb(bus, msg):
    err, debug_info = msg.parse_error()
    print(f"Error: {err.message}")

bus = main_pipeline.get_bus()
bus.add_signal_watch()
bus.connect("message::error", error_cb)

class TestRtspMediaFactory(GstRtspServer.RTSPMediaFactory):
    def __init__(self, appsink):
        GstRtspServer.RTSPMediaFactory.__init__(self)
        self.appsink = appsink

    def do_create_element(self, url):
        print("New client has entered!")
        pipeline_str = "appsrc name=appsrc is-live=true do-timestamp=true ! h264parse ! rtph264pay config-interval=1 pt=96 name=pay0"
        pipeline = Gst.parse_launch(pipeline_str)
        appsrc = pipeline.get_by_name("appsrc")
        self.appsink.connect("new-sample", on_new_sample, appsrc)
        return pipeline

rtsp_server = GstRtspServer.RTSPServer()
rtsp_server.set_service("8557")
factory = TestRtspMediaFactory(appsink)
factory.set_shared(True)
mount_points = rtsp_server.get_mount_points()
mount_points.add_factory("/camera", factory)
rtsp_server.attach(None)

signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)

mainloop = GLib.MainLoop()
mainloop.run()

gstreamer nvidia rtsp nvidia-jetson python-gstreamer
1个回答
0
投票

这可能不是最佳解决方案,但以下代码有效(使用 ZED 相机在 AGX Orin 上测试):

import gi
gi.require_version('Gst','1.0')
gi.require_version('GstVideo','1.0')
gi.require_version('GstRtspServer','1.0')
from gi.repository import GLib, Gst, GstVideo, GstRtspServer

Gst.init(None)
mainloop = GLib.MainLoop()
pipeline = Gst.parse_launch ('v4l2src device=/dev/video0 do-timestamp=true ! video/x-raw, format=YUY2, width=1344, height=376, framerate=30/1 ! nvvidconv ! video/x-raw(memory:NVMM) ! nvv4l2h264enc preset-level=4 insert-sps-pps=1 idrinterval=30 insert-vui=1 ! tee name=t ! queue ! h264parse ! matroskamux ! multifilesink location=/external/video_%05d.mkv next-file=5 max-file-duration=10000000000 max-files=10     t. ! queue ! h264parse ! video/x-h264,stream-format=byte-stream ! queue ! shmsink socket-path=tmpSock')
server = GstRtspServer.RTSPServer()
mounts = server.get_mount_points()
factory = GstRtspServer.RTSPMediaFactory()
factory.set_launch('( shmsrc socket-path=tmpSock is-live=1 do-timestamp=1 ! video/x-h264,stream-format=byte-stream ! queue ! h264parse ! rtph264pay name=pay0 )')
mounts.add_factory("/test", factory)
server.attach(None)
print ("stream ready at rtsp://127.0.0.1:8554/test")
pipeline.set_state(Gst.State.PLAYING)
mainloop.run()

shmsink 和 shmsrc 的坏处是 shmsink 创建了一个命名套接字,但如果管道没有完全关闭,例如使用 Ctrl-C 停止服务器,则它不会被删除。 所以我建议使用以下命令来运行服务器,这将确保删除套接字:

bash -c 'sh -c "trap exit\ 0 INT; python3 ../rtspServerShm.py; "; rm tmpSock*'
© www.soinside.com 2019 - 2024. All rights reserved.