Python Gstreamer 与 PyGObject 的绑定 只有核心模块,没有插件

Yll*_*123 5 python glib gstreamer pygobject

我在 OSX 12.0.1 Monterey 上安装了 gstreamer。我刚刚在运行 python 3.9 的虚拟环境中安装了 python 绑定:

pip3 install pycairo PyGObject

我可以毫无问题gi地导入。gi.repository.Gst然而,似乎几乎所有 gstreamer 插件都丢失了。这是我的测试脚本:

import gi
gi.require_versions({'Gst': '1.0'})

from gi.repository import Gst, GLib

Gst.init(None)
Gst.debug_set_active(True)
Gst.debug_set_default_threshold(5)

if not Gst.init_check()[0]:
    print("gstreamer initialization failed")


class Main:
    def __init__(self):
        self.pipeline = Gst.parse_launch('playbin uri=https://gstreamer.freedesktop.org/data/media/small/sintel.mkv')
        self.pipeline.set_state(Gst.State.PLAYING)
        self.main_loop = GLib.MainLoop.new(None, False)
        GLib.MainLoop.run(self.main_loop)
        self.bus = self.pipeline.get_bus()
        self.msg = self.bus.timed_pop_filtered(
            Gst.CLOCK_TIME_NONE,
            Gst.MessageType.ERROR | Gst.MessageType.EOS
        )

        if self.msg is not None:
            self.msg.unref()
        self.bus.unref()
        self.pipeline.set_state(Gst.State.NULL)
        self.pipeline.unref()


Main()
Run Code Online (Sandbox Code Playgroud)

它失败了:

0:00:00.006178000 92472 0x7fbd7d049210 INFO            GST_PIPELINE gstparse.c:345:gst_parse_launch_full: parsing pipeline description 'playbin uri=https://gstreamer.freedesktop.org/data/media/small/sintel.mkv'
0:00:00.006205000 92472 0x7fbd7d049210 DEBUG           GST_PIPELINE parse.l:135:priv_gst_parse_yylex: flex: IDENTIFIER: playbin
0:00:00.006217000 92472 0x7fbd7d049210 WARN     GST_ELEMENT_FACTORY gstelementfactory.c:701:gst_element_factory_make_with_properties: no such element factory "playbin"!
0:00:00.006229000 92472 0x7fbd7d049210 ERROR           GST_PIPELINE gst/parse/grammar.y:851:priv_gst_parse_yyparse: no element "playbin"
0:00:00.006237000 92472 0x7fbd7d049210 DEBUG           GST_PIPELINE parse.l:181:priv_gst_parse_yylex: flex: SPACE: [ ]
0:00:00.006243000 92472 0x7fbd7d049210 DEBUG           GST_PIPELINE parse.l:93:priv_gst_parse_yylex: flex: ASSIGNMENT: uri=https://gstreamer.freedesktop.org/data/media/small/sintel.mkv
0:00:00.006261000 92472 0x7fbd7d049210 DEBUG           GST_PIPELINE gst/parse/grammar.y:1228:priv_gst_parse_launch: got 0 elements and 0 links
Traceback (most recent call last):
  File "/python_experiments/playbin-example-audio.py", line 32, in <module>
    Main()
  File "/python_experiments/playbin-example-audio.py", line 16, in __init__
    self.pipeline = Gst.parse_launch('playbin uri=https://gstreamer.freedesktop.org/data/media/small/sintel.mkv')
Run Code Online (Sandbox Code Playgroud)

这是输出gst-inspect-1.0 | grep playbin

(gst-plugin-scanner:92783): GLib-GObject-WARNING **: 15:29:32.244: type name '-a-png-encoder-pred' contains invalid characters

(gst-plugin-scanner:92783): GLib-GObject-CRITICAL **: 15:29:32.245: g_type_set_qdata: assertion 'node != NULL' failed

(gst-plugin-scanner:92783): GLib-GObject-CRITICAL **: 15:29:32.245: g_type_set_qdata: assertion 'node != NULL' failed

(gst-plugin-scanner:92783): GLib-GObject-WARNING **: 15:29:32.293: type name '-a-png-encoder-pred' contains invalid characters

(gst-plugin-scanner:92783): GLib-GObject-CRITICAL **: 15:29:32.293: g_type_set_qdata: assertion 'node != NULL' failed

(gst-plugin-scanner:92783): GLib-GObject-CRITICAL **: 15:29:32.293: g_type_set_qdata: assertion 'node != NULL' failed
playback:  playbin: Player Bin 2
playback:  playbin3: Player Bin 3
Run Code Online (Sandbox Code Playgroud)

抛出的 GLib 错误与此有关吗?gst-launch-1.0 playbin uri=https://gstreamer.freedesktop.org/data/media/small/sintel.mkv视频播放没有问题,它似乎只是 python 绑定的问题。在尝试完全清除并重新安装 gstreamer 之前,我应该采取任何进一步的调试步骤吗?

编辑:我使用以下命令重新安装了 gstreamer: brew reinstall gstreamer gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugins-ugly gst-libav然后我使用 pip 从我的 venv 和系统安装中卸载 cairo 和 PyGObject。然后我使用brew install pygobject3并尝试再次运行该脚本,这次是从我的 python 系统安装中运行的。还是失败了

编辑:由于我的赏金即将到期,请重新审视这一点。我确实可以访问 gstreamer 核心。我可以用filesrcElementFactory.make没有什么用处。

编辑:REPL 使用Gst.ElementFactory.make()

>>> import gi
>>> gi.require_versions({'Gst': '1.0'})
>>> from gi.repository import Gst, GLib
>>> Gst.init(None)
[]
>>> Gst.debug_set_active(True)
>>> Gst.debug_set_default_threshold(5)
>>> Gst.ElementFactory.make('playbin', 'playbin')
0:00:12.767487000 49323 0x7fc9a2321c10 WARN     GST_ELEMENT_FACTORY gstelementfactory.c:754:gst_element_factory_make_valist: no such element factory "playbin"!
>>>
Run Code Online (Sandbox Code Playgroud)

Joh*_*ade 2

我发现 python 使用的注册表路径与 gst 命令行工具使用的注册表路径不同。您可以按如下方式进行检查。

运行gst-inspect-1.0 playbin并检查“文件名”行中的路径 - 这是/usr/local/lib/gstreamer-1.0/在我使用的 Mac 上。但这与 Python 的路径不匹配。运行此代码片段,它将打印所有插件及其加载路径。

import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst
Gst.init(None)

reg = Gst.Registry.get()
for x in reg.get_plugin_list():
    print (x.get_name(), x.get_filename())
Run Code Online (Sandbox Code Playgroud)

如果此处存在差异,您必须强制注册表在 gst-inspect 报告的同一位置进行查找。您可以在导入后执行此操作:

Gst.Registry.get().scan_path("/usr/local/lib/gstreamer-1.0/")
Run Code Online (Sandbox Code Playgroud)

我认为您还可以设置 GST_PLUGIN_PATH 环境变量 - 但我没有对此进行测试。