Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Gstreamer总线日志消息在哪里?_Python_Gstreamer_Rtsp_Gstreamer 1.0_Python Gstreamer - Fatal编程技术网

Python Gstreamer总线日志消息在哪里?

Python Gstreamer总线日志消息在哪里?,python,gstreamer,rtsp,gstreamer-1.0,python-gstreamer,Python,Gstreamer,Rtsp,Gstreamer 1.0,Python Gstreamer,我正在尝试使用python中的Gstreamer将.mp4流式传输到RTSP服务器 import sys import gi gi.require_version('Gst', '1.0') gi.require_version('GstRtspServer', '1.0') gi.require_version('GstRtsp', '1.0') from gi.repository import Gst, GstRtspServer, GObject, GLib, GstRtsp loo

我正在尝试使用python中的Gstreamer.mp4流式传输到RTSP服务器

import sys
import gi

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

loop = GLib.MainLoop()
Gst.init(None)
file_path = "test.mp4"
class TestRtspMediaFactory(GstRtspServer.RTSPMediaFactory):
    def __init__(self):
        GstRtspServer.RTSPMediaFactory.__init__(self)

    def do_create_element(self, url):
        src_demux = f"filesrc location={file_path} ! qtdemux name=demux"
        h264_transcode = "demux.video_0"
        pipeline = "{0} {1} ! queue ! rtph264pay name=pay0 config-interval=1 pt=96".format(src_demux, h264_transcode)
        print ("Element created: " + pipeline)

        self._pipeline = Gst.parse_launch(pipeline)
        def bus_handler(bus, message):
            print(message)
        self.bus = self._pipeline.get_bus()
        self.bus.connect('message', bus_handler)
        self.bus.add_signal_watch_full(1)
        return self._pipeline

class GstreamerRtspServer():
    def __init__(self):
        self.rtspServer = GstRtspServer.RTSPServer()
        factory = TestRtspMediaFactory()
        factory.set_shared(True)
        mountPoints = self.rtspServer.get_mount_points()
        self.address = '127.0.0.1' #my RPi's local IP
        self.port = '8553'
        self.rtspServer.set_address(self.address)
        self.rtspServer.set_service(self.port)
        urlstr = "/user=&password=.sdp"
        url = GstRtsp.RTSPUrl.parse(urlstr)
        mountPoints.add_factory(urlstr, factory)

        self.rtspServer.attach(None)

if __name__ == '__main__':
    s = GstreamerRtspServer()
    loop.run()

然而,我试图了解如何使用Gstreamer总线记录诸如eos或错误和警告之类的消息,但我没有看到任何错误和警告,即使在我发送eos事件并且流媒体有效停止时也是如此

s.rtspServer._pipeline._end_stream_event.set()
s.rtspServer._pipeline.send_event(Gst.Event.new_eos())

我用得对吗?如果没有,我可以修复什么来正确记录总线消息?

以下解决方案基于已接受但不完全的答案

我找到了一种不需要“手动”创建管道元素的方法,但它(在本场景中)保持了方便的
Gst.parse_launch(pipelineCmd)
方法,并扩展了Gst.Bin以启用消息调试

下面是完整的示例源代码(查看注释行以了解一些解释):

请注意,实际上inherists/extends(和Gst.Element)可以(无论听起来多么奇怪)将管道添加到bin

这个小“把戏”为我们这些“懒惰”的程序员节省了时间,使他们能够继续使用命令行语法的解析来创建管道元素

在一些更复杂的场景中,命令行语法的解析不适用,解决方案如下:

  • 创建ExtendedBin
  • 使用方法“手动”创建元素(并设置必要的属性)
  • 将创建的元素添加到
    ExtendedBean
  • 链接元素
  • 创建新管道并向其添加bin
  • 在需要的地方使用管道

    • 以下解决方案基于公认但不完全的答案

      我找到了一种不需要“手动”创建管道元素的方法,但它(在本场景中)保持了方便的
      Gst.parse_launch(pipelineCmd)
      方法,并扩展了Gst.Bin以启用消息调试

      下面是完整的示例源代码(查看注释行以了解一些解释):

      请注意,实际上inherists/extends(和Gst.Element)可以(无论听起来多么奇怪)将管道添加到bin

      这个小“把戏”为我们这些“懒惰”的程序员节省了时间,使他们能够继续使用命令行语法的解析来创建管道元素

      在一些更复杂的场景中,命令行语法的解析不适用,解决方案如下:

      • 创建ExtendedBin
      • 使用方法“手动”创建元素(并设置必要的属性)
      • 将创建的元素添加到
        ExtendedBean
      • 链接元素
      • 创建新管道并向其添加bin
      • 在需要的地方使用管道
      #!/usr/bin/env python
      
      import sys
      import gi
      
      gi.require_version('Gst', '1.0')
      gi.require_version('GstRtspServer', '1.0')
      from gi.repository import Gst, GstRtspServer, GObject, GLib
      
      Gst.init(None)
      loop = GLib.MainLoop()
      
      # extended Gst.Bin that overrides do_handle_message and adds debugging
      class ExtendedBin(Gst.Bin):
          def do_handle_message(self,message):
              if message.type == Gst.MessageType.ERROR:
                  error, debug = message.parse_error()
                  print("ERROR:", message.src.get_name(), ":", error.message)
                  if debug:
                      print ("Debug info: " + debug)
              elif message.type == Gst.MessageType.EOS:
                  print ("End of stream")
              elif message.type == Gst.MessageType.STATE_CHANGED:
                  oldState, newState, pendingState = message.parse_state_changed()
                  print ("State changed -> old:{}, new:{}, pending:{}".format(oldState,newState,pendingState))
              else :
                  print("Some other message type: " + str(message.type))
      
              #call base handler to enable message propagation
              Gst.Bin.do_handle_message(self,message)
      
      class TestRtspMediaFactory(GstRtspServer.RTSPMediaFactory):
      
          def __init__(self):
              GstRtspServer.RTSPMediaFactory.__init__(self)
      
          def do_create_element(self, url):
              #set mp4 file path to filesrc's location property
              src_demux = "filesrc location=/path/to/dir/test.mp4 ! qtdemux name=demux"
              h264_transcode = "demux.video_0"
              #uncomment following line if video transcoding is necessary
              #h264_transcode = "demux.video_0 ! decodebin ! queue ! x264enc"
              pipelineCmd = "{0} {1} ! queue ! rtph264pay name=pay0 config-interval=1 pt=96".format(src_demux, h264_transcode)
      
              self.pipeline = Gst.parse_launch(pipelineCmd)
              print ("Pipeline created: " + pipelineCmd)
      
              # creates extended Gst.Bin with message debugging enabled
              extendedBin = ExtendedBin("extendedBin")
      
              # Gst.pipeline inherits Gst.Bin and Gst.Element so following is possible
              extendedBin.add(self.pipeline)
      
              # creates new Pipeline and adds extended Bin to it
              self.extendedPipeline = Gst.Pipeline.new("extendedPipeline")
              self.extendedPipeline.add(extendedBin)
      
              return self.extendedPipeline
      
      class GstreamerRtspServer(GstRtspServer.RTSPServer):
          def __init__(self):
              self.rtspServer = GstRtspServer.RTSPServer()
              self.factory = TestRtspMediaFactory()
              self.factory.set_shared(True)
              mountPoints = self.rtspServer.get_mount_points()
              mountPoints.add_factory("/stream", self.factory)
              self.rtspServer.attach(None)
              print ("RTSP server is ready")
      
      if __name__ == '__main__':
          s = GstreamerRtspServer()
          loop.run()