2 回答

TA贡献1818条经验 获得超3个赞
所以,你可以覆盖do_handle_message在Gst.Bin下面的方法:
import gi
gi.require_version("Gst", "1.0")
from gi.repository import Gst, GLib
Gst.init(None)
class SubclassBin(Gst.Bin):
def do_handle_message(self, message):
if message.type == Gst.MessageType.ERROR:
error, message = message.parse_error()
# TODO: Do something with the error
# Call the base Gst.Bin do_handle_message
super().do_handle_message(self, message)
subclass_bin = SubclassBin("mybin")
也就是说,我不确定如何GstRtspServer.RTSPMediaFactory使用SubclassBin而不是Gst.Bin因为据我所知,将任何 Bin 连接到的唯一方法RTSPMediaFactory是通过set_launch需要管道字符串而不是预构建 bin 的方法。如果有一种方法可以将预构建的 bin 添加到RTSPMediaFactory,这将是一个完整的答案......但不幸的是,这是我所能得到的。

TA贡献1884条经验 获得超4个赞
我建议使用 bkanuka 的解决方案 (Subclassing Gst.Bin) 而不是下面的解决方案,它有很多缺点。
对 GStreamer 和 RTSP 服务器库进行了一些更多的实验后,错误处理情况很复杂。
正常方式
查看 GStreamer 管道上的错误的规范方法是向管道的总线添加观察者并侦听错误消息。
def watcher(bus, message, *user_data);
if message.type == Gst.MessageType.ERROR:
error, message = message.parse_error()
# TODO: Do something with the error
my_pipeline.get_bus().add_watch(
GLib.PRIORITY_DEFAULT,
watcher,
None)
但是,您不能使用提供给 GstRtspServer 的管道执行此操作。这是因为 GstRtspServer 期望能够在管道的总线上安装自己的观察器,并且一次只能将一个观察器连接到总线。这尤其令人遗憾,因为这会阻止我们侦听管道上的任何事件,而不仅仅是错误。
我的解决方法
我们可以将管道分成两部分:一部分负责连接到源和解码帧的容易出错的过程,另一部分负责对结果帧进行编码并将它们加载到 GstRtspServer。然后我们可以使用视频间插件在两者之间进行通信。
例如,假设您尝试从 VP8 格式的文件进行流式传输。我们负责读取和解码帧的第一个管道如下所示:
filesrc location="{filepath}" ! decodebin ! intervideosink channel="file-channel"
...我们负责编码和加载帧的第二条管道将如下所示:
intervideosrc channel="file-channel" ! videoconvert ! vp8enc deadline=1 ! rtpvp8pay name=pay0 pt=96
这里的关键是只有第二个管道必须由 GstRtspServer 管理,因为它是提供有效负载数据的管道。第一个由我们管理,我们可以将我们自己的观察者附加到它上面,它可以智能地响应错误并做我们需要的任何其他事情。这当然不是一个完美的解决方案,因为我们无法响应与编码和负载相关的错误,但我们已经获得了接收与读取文件和解码文件相关的错误的能力。我们现在还能够执行其他与消息相关的任务,例如拦截流结束消息以循环播放视频文件。
添加回答
举报