преобразовать конвейер gstreamer в код python

Я пытаюсь преобразовать конвейер gstreamer в код python, используя библиотеку gi.

Это конвейер, который успешно работает в терминале:

gst-launch-1.0 rtspsrc location="rtsp://admin:[email protected]:554/H264?ch=1&subtype=0&proto=Onvif" latency=300 ! rtph264depay ! h264parse ! nvv4l2decoder drop-frame-interval=1 ! nvvideoconvert ! video/x-raw,width=1920,height=1080,formate=I420 ! queue !  nveglglessink window-x=0 window-y=0 window-width=1080 window-height=720

но при запуске того же конвейера с использованием кода Python нет окна вывода, отображающего поток rtsp, а также нет ошибки на терминале. Терминал просто зависает, пока я не нажму ctrl+c.

Это код, который я использую для запуска команды gstreamer:

import gi

gi.require_version("Gst", "1.0")

from gi.repository import Gst, GObject


def main(device):
    GObject.threads_init()
    Gst.init(None)

    pipeline = Gst.Pipeline()

    source = Gst.ElementFactory.make("rtspsrc", "video-source")
    source.set_property("location", device)
    source.set_property("latency", 300)
    pipeline.add(source)

    depay = Gst.ElementFactory.make("rtph264depay", "depay")
    pipeline.add(depay)
    source.link(depay)

    parse = Gst.ElementFactory.make("h264parse", "parse")
    pipeline.add(parse)
    depay.link(parse)

    decoder = Gst.ElementFactory.make("nvv4l2decoder", "decoder")
    decoder.set_property("drop-frame-interval", 2)
    pipeline.add(decoder)
    parse.link(decoder)

    convert = Gst.ElementFactory.make("nvvideoconvert", "convert")
    pipeline.add(convert)
    decoder.link(convert)

    caps = Gst.Caps.from_string("video/x-raw,width=1920,height=1080,formate=I420")
    filter = Gst.ElementFactory.make("capsfilter", "filter")
    filter.set_property("caps", caps)
    pipeline.add(filter)
    convert.link(filter)

    queue = Gst.ElementFactory.make("queue", "queue")
    pipeline.add(queue)
    filter.link(queue)

    sink = Gst.ElementFactory.make("nveglglessink", "video-sink")
    sink.set_property("window-x", 0)
    sink.set_property("window-y", 0)
    sink.set_property("window-width", 1280)
    sink.set_property("window-height", 720)

    pipeline.add(sink)

    queue.link(sink)

    loop = GObject.MainLoop()

    pipeline.set_state(Gst.State.PLAYING)

    try:
        loop.run()
    except:
        pass

    pipeline.set_state(Gst.State.NULL)

if __name__ == "__main__":
    main("rtsp://admin:[email protected]:554/H264?ch=1&subtype=0&proto=Onvif")

Кто-нибудь знает, в чем ошибка? Благодарю вас!


person dipesh    schedule 14.02.2020    source источник
comment
Я добавил определение вызова шины в приведенном выше коде, чтобы зафиксировать ошибку. Ошибка, которую я получаю, это Ошибка: gst-stream-error-quark: Внутренняя ошибка потока данных. (1): gstbasesrc.c(3055): gst_base_src_loop (): /GstPipeline:pipeline0/GstRTSPSrc:video-source/GstUDPSrc:udpsrc2: потоковая передача остановлена, причина не связана (-1)   -  person dipesh    schedule 15.02.2020


Ответы (1)


Причина, по которой это не работает, заключается в том, что исходная панель rtspsrc представляет собой так называемый "Иногда прокладки". Ссылка здесь объясняет это довольно хорошо, но в основном вы не можете заранее знать, сколько пэдов станет доступным на rtspsrc, поскольку это зависит от SDP, предоставляемого сервером RTSP.

Таким образом, вы должны слушать сигнал "pad-added" rtspsrc, где вы можете связать остальную часть вашего конвейера с исходной площадкой, которая только что появилась в обратном вызове.

Итак, резюмируем:

def main(device):
    GObject.threads_init()
    Gst.init(None)

    pipeline = Gst.Pipeline()
    source = Gst.ElementFactory.make("rtspsrc", "video-source")
    source.set_property("location", device)
    source.set_property("latency", 300)
    source.connect("pad-added", on_rtspsrc_pad_added)
    pipeline.add(source)

    # We will add/link the rest of the pipeline later
    loop = GObject.MainLoop()

    pipeline.set_state(Gst.State.PLAYING)

    try:
        loop.run()
    except:
        pass

    pipeline.set_state(Gst.State.NULL)

def on_rtspsrc_pad_added(rtspsrc, pad, *user_data):
    # Create the rest of your pipeline here and link it 
    depay = Gst.ElementFactory.make("rtph264depay", "depay")
    pipeline.add(depay)
    rtspsrc.link(depay)

    # and so on ....
person nielsdg    schedule 03.06.2020