'Python Gstreamer bindings with PyGObject Only has Core modules, no Plugins
I have gstreamer installed on OSX 12.0.1 Monterey. I just installed the python bindings inside of a virtual environment running python 3.9 with:
pip3 install pycairo PyGObject
I can import gi and gi.repository.Gst without an issue. However it seems that almost all gstreamer plugins are missing. This is my test script:
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()
It fails with:
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')
Here is the output of 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
Do the GLib errors thrown have something to do with this? gst-launch-1.0 playbin uri=https://gstreamer.freedesktop.org/data/media/small/sintel.mkv has no problem with video playback it just appears to be the python bindings. Are there any further debugging steps I should take before attempting to purge and reinstall gstreamer entirely?
Edit: I reinstalled gstreamer using the command:
brew reinstall gstreamer gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugins-ugly gst-libav I then used pip to uninstall cairo and PyGObject from my venv and my system install. I then used brew install pygobject3 and tried to run the script again, this time from my python system install. Still failed
Edit: Revisiting this as my bounty expires soon. I do have access to the gstreamer core. I can make filesrc with ElementFactory.make but nothing useful.
Edit: REPL using 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"!
>>>
Solution 1:[1]
Playbin need to be create with Gst.ElementFactory.make
and Gst.parse_launch take a pipeline description as parameter.
Take example on this:
def __init__(self, tsm_description="audiotsm-phase-vocoder"):
super().__init__()
self._speed = 1.0
self._speed_set = False
# Create the playbin, that will handle the decoding of the audio files
self.playbin = Gst.ElementFactory.make('playbin', 'playbin')
self.add(self.playbin)
# Create the audiotsm bin, that will handle the TSM
audiotsmbin = Gst.Bin('audiotsm')
# Create the elements of the audiotsm bin, add them, and link them
self.tsm = Gst.parse_launch(tsm_description)
converter = Gst.ElementFactory.make('audioconvert', 'converter')
sink = Gst.ElementFactory.make('autoaudiosink', 'sink')
audiotsmbin.add(self.tsm)
audiotsmbin.add(converter)
audiotsmbin.add(sink)
self.tsm.link(converter)
converter.link(sink)
# Add the sink pad of the TSM plugin to the audiotsm bin.
self.tsm_sink_pad = Gst.GhostPad.new(
'sink', self.tsm.get_static_pad('sink'))
audiotsmbin.add_pad(self.tsm_sink_pad)
# And link it to the playbin
self.playbin.set_property("audio-sink", audiotsmbin)
Solution 2:[2]
One solution is to iterate over all rows and compare the values with the previous row. Then we can set both rows to either Tier A or B. The following code is doing exactly this and produces your expected output. The solution of course requires that the dataframe is sorted by the Time column.
# Variables for values from the last row
prev_time = -1
prev_variable1 = -1
prev_variable2 = -1
# Iterate over all rows
for i, row in df.iterrows():
# Extract needed values from row
time = row[0]
variable1 = row[1]
variable2 = row[2]
# Check if current and last row are in Tier A
if time == prev_time and variable1 == prev_variable1:
df.at[i-1, 'Tier'] = 'A'
df.at[i, 'Tier'] = 'A'
# Check if current and last row are in Tier B
elif time == prev_time and variable2 == prev_variable2:
df.at[i-1, 'Tier'] = 'B'
df.at[i, 'Tier'] = 'B'
# Set current row values to the previous values of next row
prev_time = time
prev_variable1 = variable1
prev_variable2 = variable2
print(df)
Output:
Time Variable 1 Variable 2 Tier
0 1 a URI A
1 1 a CVV A
2 2 b URI B
3 2 c URI B
4 3 e BCN A
5 3 e MKL A
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | fchancel |
| Solution 2 | JANO |
