How to write Gstreamer plugin with Python?
10 min. read |
Next guide shows steps to write Gstreamer Plugin in Python for any Computer Vision, Image Processing task and use it in standard Gstreamer pipeline from command line. Additionally this post explains how to get/set own properties from implemented Gstreamer plugin.
Requirements
- Ubuntu 18
- Python 3.6
- Gstreamer with Python Bindings. Look at “How to install Gstreamer Python Bindings on Ubuntu 18”
- gstreamer-python
- opencv-python
Code
Learn how to?
- create basic gstreamer plugins
- “hello_world” plugin (gstplugin_py)
- blur filter plugin (gaussian_blur)
- set/get user defined properties for plugin
Use gstreamer plugins
- sources: videotestsrc, filesrc
- transforms: videoconvert, decodebin, capsfilter, videobox
- mixer: videomixer
- sinks: autovideosink, gtksink, fakesink
Preface
Inspired by guide “How to write Gstreamer elements in Python”, where the author shows how to write Audio Source and Filter Elements, I wanted to create simple example on how to write Gstreamer plugins for Computer Vision/Image Processing purpose. Despite mentioned disadvantages of Python implementation of Gstreamer elements it is still faster than any other Python approach in image processing (like OpenCV), and more flexible as you can easily reuse this element in other Gstreamer pipelines without changing any code.
Guide
Extend GstBase.BaseTransform
GstBase.BaseTransform is base class for filter element that does data processing. The main parts or filter element are:
- sink: receiving incoming buffers (sinkpad)
- src: send outcoming buffers (srcpad)
- transform
- inplace transform (transform_ip)
- out buffer transform (transform)
Description
Plugin’s description is stored in gstmetadata field as tuple with the following fields:
__gstmetadata__ = (name, # str transform, # str description, # str author) # str
This description is displayed when user calls gst-inspect-1.0. For example:
Pads
General scheme of any filter element looks like the following:
Sink and Src are implementations of Gst.Pad. In Pads and Capabilities there is well defined meaning and functions of pads.
To initialize specific pad, – define Gst.PadTemplate first. Gst.PadTemplate describes pad’s name, direction (sink, src), presense (always, sometimes, request), caps. Have a look at the following code to define sink’s Gst.PadTemplate that accepts buffers in Red Green Blue colorspaces format and it’s variations.
# RGB colorspace variations FORMATS = "{RGBx,BGRx,xRGB,xBGR,RGBA,BGRA,ARGB,ABGR,RGB,BGR}"
Gst.PadTemplate.new("sink", Gst.PadDirection.SINK, Gst.PadPresence.ALWAYS, # Set to target format Gst.Caps.from_string(f"video/x-raw,format={FORMATS}"))
The, let do the same for src pad
Gst.PadTemplate.new("src", Gst.PadDirection.SRC, Gst.PadPresence.ALWAYS, # Set to target format, Gst.Caps.from_string(f"video/x-raw,format={FORMATS}"))
In order to make pad templates visible for plugin, – just define gsttemplates field
__gsttemplates__ = (src_pad_template, sink_pad_template)
Otherwise you’ll get next CRITICAL error:
If everything OK, you should be able to get next information after running gst-inspect-1.0:
Transform
As buffer flows from sink to src we need to override do_transform_ip (for buffer processing in-place) or do_transform (for out-buffer processing and in-buffer remains unchanged) in order to do custom buffer processing and push it to src’s pad.
def do_transform_ip(self, buffer: Gst.Buffer) -> Gst.FlowReturn: # BUFFER processing return Gst.FlowReturn.OK
In our case the main purpose of plugin is to blur image. So we need to convert Gst.Buffer to numpy array, make it writable (recap: How to make Gst.Buffer writable) and apply Gaussian Blur (using OpenCV) to it. Look how this could be implemented within do_transform_ip:
def do_transform_ip(self, buffer: Gst.Buffer) -> Gst.FlowReturn: try: # get sink's caps sink_caps = self.sinkpad.get_current_caps() # convert Gst.Buffer to np.ndarray image = gst_buffer_with_caps_to_ndarray(buffer, sink_caps) # apply gaussian blur to image image[:] = gaussian_blur(image, self.kernel_size, sigma=(self.sigma_x, self.sigma_y)) except Exception as e: logging.error(e) return Gst.FlowReturn.OK
Properties
Most of gstreamer plugins have properties that are being initialized by user when specifying commands in terminal. As every Gst.Element is derived from GObject we can easily use it’s __gproperties__ metadata to define own properties. It’s well described in official documentation.
So to create own property, – fill the __gproperties__ dictionary (property-name: tuple) with your own properties and it’s description. Common template is the following:
__gproperties__ = {"property-name": (type, # GObject.TYPE_* short description, # str full desctiption, # str min_value, # any max_value, # any default_value, # any flags) # GObject.ParamFlags
Then properties for gaussian_blur plugin (sigmaX, sigmaY, kernel) could be defined by the following lines of code:
__gproperties__ = { "kernel": (GObject.TYPE_INT64, "Kernel Size", "Gaussian Kernel Size", 1, GLib.MAXINT, DEFAULT_KERNEL_SIZE, GObject.ParamFlags.READWRITE ), "sigmaX": (GObject.TYPE_FLOAT, "Standart deviation in X", "Gaussian kernel standard deviation in X direction", 1.0, GLib.MAXFLOAT, DEFAULT_SIGMA_X, GObject.ParamFlags.READWRITE ), "sigmaY": (GObject.TYPE_FLOAT, "Standart deviation in Y", "Gaussian kernel standard deviation in Y direction", 1.0, GLib.MAXFLOAT, DEFAULT_SIGMA_Y, GObject.ParamFlags.READWRITE ), }
To use own properties just override do_get_property method and include implementation for custom properties handle.
def do_get_property(self, prop: GObject.GParamSpec): if prop.name == 'kernel': return self.kernel_size elif prop.name == 'sigmaX': return self.sigma_x elif prop.name == 'sigmaY': return self.sigma_y else: raise AttributeError('unknown property %s' % prop.name)
And override do_set_property as well:
def do_set_property(self, prop: GObject.GParamSpec, value): if prop.name == 'kernel': self.kernel_size = value elif prop.name == 'sigmaX': self.sigma_x = value elif prop.name == 'sigmaY': self.sigma_y = value else: raise AttributeError('unknown property %s' % prop.name)
With gst-inspect-1.0 defined properties above looks like the following:
Registration
In order to use gstreamer plugin from command line, just put next two lines in the end of the file:
GObject.type_register(class_type) __gstelementfactory__ = (name, # str rank, # Gst.Rank class_type) # class type
For example, for gaussian_blur plugin previous code is going to be similar to the following:
GObject.type_register(GstGaussianBlur) # register type __gstelementfactory__ = ("gaussian_blur", Gst.Rank.NONE, GstGaussianBlur)
Run examples
Get repository
First clone the repository and setup environment:
git clone https://github.com/jackersson/gst-python-plugins.git cd gst-python-plugins python3 -m venv venv source venv/bin/activate pip install -U wheel pip setuptools pip install -r requirements.txt
Before running examples, export the following GST_PLUGIN_PATH, so gstreamer can locate newly created plugins:
export GST_PLUGIN_PATH=$GST_PLUGIN_PATH:$PWD/venv/lib/gstreamer-1.0/:$PWD/gst/
Note: Explanation for GST_PLUGIN_PATH export
- $GST_PLUGIN_PATH: previous path with plugin’s libs
- $PWD/venv/lib/gstreamer-1.0/: path were gst-python was installed (–prefix value) and contains libgstpython*.so
- $PWD/gst/: path with python/ directory which contains plugins implementation (*.py)
Launch simple command, to check how gstplugin_py works.
GST_DEBUG=python:6 gst-launch-1.0 videotestsrc ! gstplugin_py int-prop=100 float-prop=0.2 bool-prop=True str-prop="set" ! fakesink
Notice that the properties “int-prop“, “float-prop“, “bool-prop“, “str-prop“, “pyobject-prop” successfully set to values specified by command line.
Next, let check gaussian_blur plugin:
gst-launch-1.0 videotestsrc ! gaussian_blur kernel=9 sigmaX=5.0 sigmaY=5.0 ! videoconvert ! autovideosink
Note: To see the difference I used basic video mixing pipeline to put two streams (with/without blur) in one window (Look at gstreamer cheat sheet, to learn more about classic pipelines)
gst-launch-1.0 videomixer name=mixer ! videoconvert ! \ autovideosink videotestsrc ! \ video/x-raw,format=RGBA,width=1280,height=720 ! \ gaussian_blur kernel=9 sigmaX = 5.0 sigmaY=5.0 ! \ videobox left=-1280 ! mixer. videotestsrc ! \ video/x-raw,format=RGBA,width=1280,height=720 ! \ videobox left=0 ! mixer.
Or let us do the same with a video:
gst-launch-1.0 videomixer name=mixer ! videoconvert \ ! autovideosink \ filesrc location=video.mp4 ! decodebin ! \ tee name=t ! queue ! videoconvert ! \ gaussian_blur kernel=9 sigmaX=5.0 sigmaY=5.0 ! \ videobox left=-1280 ! mixer. t. ! queue ! \ videobox left=0 ! mixer.
The other option could be to do the same but directly from youtube video using “How to watch Youtube videos with Gstreamer”.
Troubleshooting
1. Remove gstreamer’s cache to reload plugins and display error messages when there is a problem.
rm -rf ~/.cache/gstreamer-1.0/
2. Check GST_PLUGIN_PATH export as described above if you are receiving:
No such element or plugin 'myplugin'
Conclusion
With gstreamer python bindings you can easily implement plugins for image processing (gaussian_blur). We learned basic steps to implement filter plugin from GstBase.BaseTransform:
- description
- pads
- transform
- properties
- registration
Hope everything works as expected 😉 In case of troubles with running code leave comments or open an issue in Github.
I really like your writing style, good information, thanks for putting up : D.
gst-launch-1.0 videotestsrc ! gaussian_blur kernel=9 sigmaX=5.0 sigmaY=5.0 ! videoconvert ! autovideosink
WARNING: erroneous pipeline: no element “gaussian_blur”
i got this error how i can solve this please help
Hi Saurabh,
Make sure you have exported GST_PLUGIN_PATH:
export GST_PLUGIN_PATH=$GST_PLUGIN_PATH:$PWD/venv/lib/gstreamer-1.0/:$PWD/gst/
and
rm -rf ~/.cache/gstreamer-1.0
Hope this works 🙂
Best regards
did follow your recommendations export GST_PLUGIN_PATH as well as rm -rf ~/.cache/gstreamer-1.0 but the same error message still show up:
WARNING: erroneous pipeline: no element “gstplugin_py”
Hi Paul,
Check this answer. This may help you 🙂
Also check if in GST_PLUGIN_PATH folder there are libgstpython*.{la,so}
indeed, I cannot find libgstpython*.so and check your answer link and follow the steps and still cannot get libgstpython*.so installed. Not sure what’s missing. Any specific pip installation will get libgstpython*.so installed? I did run:
pip install -r requirements.txt
successfully (well, I don’t see any error message at least)
Thank you very much for your help in advance.
update: finally I got libgstpython*.so installed (gst-python)
The missing part (http://lifestyletransfer.com/how-to-install-gstreamer-python-bindings/) is:
sudo apt install -y python-gi-dev
after installed python-gi-dev, then I am able to ./configure successfully (otherwise, it will complain:
No package ‘pygobject-3.0’ found
) I hope these information will help whoever encounter the same problem I have. Enjoy!
gst-launch-1.0 videotestsrc ! videoconvert ! gstplugin_py ! videoconvert ! fakesink
WARNING: erroneous pipeline: no element “gstplugin_py”
The same error as saurabh.
Hi Miguel,
Answered previously 😉
Make sure you have exported GST_PLUGIN_PATH:
export GST_PLUGIN_PATH=$GST_PLUGIN_PATH:$PWD/venv/lib/gstreamer-1.0/:$PWD/gst/
and
rm -rf ~/.cache/gstreamer-1.0
Hope this works 🙂
Best regards
does not work
[flaskuser@localhost pygst]$ gst-launch-1.0 videotestsrc ! gaussian_blur kernel=9 sigmaX=5.0 sigmaY=5.0 ! videoconvert ! autovideosink
(gst-launch-1.0:8218): GStreamer-CRITICAL **: 12:31:10.725: gst_query_set_caps_result: assertion ‘gst_query_is_writable (query)’ failed
(gst-launch-1.0:8218): GStreamer-CRITICAL **: 12:31:10.725: gst_mini_object_ref: assertion ‘mini_object != NULL’ failed
(gst-launch-1.0:8218): GStreamer-CRITICAL **: 12:31:10.726: gst_caps_can_intersect: assertion ‘GST_IS_CAPS (caps2)’ failed
(gst-launch-1.0:8218): GStreamer-CRITICAL **: 12:31:10.726: gst_mini_object_unref: assertion ‘mini_object != NULL’ failed
(gst-launch-1.0:8218): GStreamer-CRITICAL **: 12:31:10.726: gst_query_set_caps_result: assertion ‘gst_query_is_writable (query)’ failed
(gst-launch-1.0:8218): GStreamer-CRITICAL **: 12:31:10.726: gst_mini_object_ref: assertion ‘mini_object != NULL’ failed
(gst-launch-1.0:8218): GStreamer-CRITICAL **: 12:31:10.726: gst_pad_template_new: assertion ‘caps != NULL’ failed
(gst-launch-1.0:8218): GStreamer-CRITICAL **: 12:31:10.726: gst_mini_object_unref: assertion ‘mini_object != NULL’ failed
(gst-launch-1.0:8218): GStreamer-CRITICAL **: 12:31:10.726: gst_element_request_compatible_pad: assertion ‘GST_IS_PAD_TEMPLATE (templ)’ failed
(gst-launch-1.0:8218): GStreamer-CRITICAL **: 12:31:10.726: gst_object_unref: assertion ‘object != NULL’ failed
(gst-launch-1.0:8218): GStreamer-CRITICAL **: 12:31:10.727: gst_query_set_caps_result: assertion ‘gst_query_is_writable (query)’ failed
(gst-launch-1.0:8218): GStreamer-CRITICAL **: 12:31:10.727: gst_mini_object_ref: assertion ‘mini_object != NULL’ failed
(gst-launch-1.0:8218): GStreamer-CRITICAL **: 12:31:10.727: gst_caps_can_intersect: assertion ‘GST_IS_CAPS (caps1)’ failed
(gst-launch-1.0:8218): GStreamer-CRITICAL **: 12:31:10.727: gst_mini_object_unref: assertion ‘mini_object != NULL’ failed
(gst-launch-1.0:8218): GStreamer-CRITICAL **: 12:31:10.728: gst_query_set_caps_result: assertion ‘gst_query_is_writable (query)’ failed
(gst-launch-1.0:8218): GStreamer-CRITICAL **: 12:31:10.728: gst_mini_object_ref: assertion ‘mini_object != NULL’ failed
WARNING: erroneous pipeline: could not link filter+gstgaussianblur0 to videoconvert0
Hi EJL,
Thank you for noticing it. Had the same problem. Fixed it with GstBase.BaseTransform usage. And it is better practice to extend BaseTransform than Gst.Element. Updated the post and a code. Try it now 😉
Best regards
In Commits on May 18, 2019 “added median_filter” plugins work if you make fixes similar to {pygst_utils -> gstreamer}.
But in Commits on Mar 12, 2020 “moved to GstBase.BaseTransform” plugins crash with an error:
# GST_DEBUG=2 gst-launch-1.0 videotestsrc ! gstplugin_py int-prop=100 float-prop=0.2 bool-prop=True str-prop=”set” ! fakesink
sys:1: Warning: g_object_class_find_property: assertion ‘G_IS_OBJECT_CLASS (class)’ failed
0:00:01.162700289 27632 0x5589972b00 ERROR GST_PIPELINE grammar.y:414:gst_parse_element_set: no property “float-prop” in element “���U”
0:00:01.162827262 27632 0x5589972b00 ERROR GST_PIPELINE grammar.y:414:gst_parse_element_set: no property “bool-prop” in element “���U”
0:00:01.162894006 27632 0x5589972b00 ERROR GST_PIPELINE grammar.y:414:gst_parse_element_set: no property “str-prop” in element “���U”
sys:1: Warning: g_object_ref: assertion ‘G_IS_OBJECT (object)’ failed
(gst-launch-1.0:27632): GStreamer-CRITICAL **: 12:57:38.613: gst_bin_add: assertion ‘GST_IS_ELEMENT (element)’ failed
**
ERROR:./grammar.y:646:gst_parse_perform_link: assertion failed: (GST_IS_ELEMENT (sink))
Aborted
Why did I get these errors after updating to the last commit ?
Thank you very much for your website.
Hi Nikita,
***
Thank you for sharing with current problem. Had similar problem, that’s why at first in this post I used Gst.Element instead of GstBase.BaseTransform. But, when I tested installation guides from official sources on my PC and different docker configurations I stopped with GstBase.BaseTransform. And I can’t reproduce same mistakes you got.
Can you specify version of your Gstreamer, Ubuntu? I’ll try to reproduce it.
***
Also I separated repository gst-python-plugins into 2 branches, so you can use any that works for you:
1. 1.0-element (based on Gst.Element
2. 2.0-base-transform (based on GstBase.BaseTransform)
***
Best regards,
Thanks for the answer.
I checked the branch “1.0-element (based on Gst.Element)”, it works.
I use JetsonTX2, information about my Gstreamer, Ubuntu:
Operating System: Ubuntu 18.04.2 LTS
Kernel: Linux 4.9.140-tegra
Architecture: arm64
gst-launch-1.0 version 1.14.5
GStreamer 1.14.5
https://launchpad.net/distros/ubuntu/+source/gstreamer1.0
Great 😉
Thank you for information. Got it, I’ll check it on Jetson Platform too and keep you updated on why there was a problem.
Best regards,
Taras
Hi Nikita,
Seems on Jetson Nano <1.0-element> branch not working as well. With GstBase.BaseTransform everything works like a charm 😉
***
Checked with Jetson Nano:
Description: Ubuntu 18.04.3 LTS
Kernel: 4.9.140-tegra
Gstreamer: 1.14.5
***
I do not know why it is so. On branch I have no errors. With GstBase.BaseTransform even gst-inspect-1.0 crashes (segfault):
# gst-inspect-1.0 gstplugin_py
Factory Details:
Rank none (0)
Long-name Name
Klass Transform
Description Description
Author Author
Plugin Details:
Name python
Description loader for plugins written in python
Filename /root/Projects/gst-python/plugin/.libs/libgstpython.cpython-36m-aarch64-linux-gnu.so
Version 1.14.5
License LGPL
Source module gst-python
Binary package GStreamer GObject Introspection overrides for Python
Origin URL http://gstreamer.freedesktop.org
GObject
+—-GInitiallyUnowned
+—-GstObject
+—-GstElement
+—-GstBaseTransform
+—-gstplugin_py+GstPluginPy
Pad Templates:
SRC template: ‘src’
Availability: Always
Capabilities:
ANY
SINK template: ‘sink’
Availability: Always
Capabilities:
ANY
Element has no clocking capabilities.
Element has no URI handling capabilities.
Pads:
SINK: ‘sink’
Pad Template: ‘sink’
SRC: ‘src’
Pad Template: ‘src’
Element Properties:
name : The name of the object
flags: readable, writable
String. Default: “gstplugin_py+gstpluginpy0”
parent : The parent of the object
flags: readable, writable
Object of type “GstObject”
qos : Handle Quality-of-Service events
flags: readable, writable
Boolean. Default: false
bool-prop : A property that contains bool
flags: readable, writable
Boolean. Default: false
float-prop : A property that contains float
sys:1: Warning: g_object_get_property: assertion ‘G_IS_OBJECT (object)’ failed
flags: readable, writable
Float. Range: 0 – 1 Default: 0
int-prop : A property that contains an integer
flags: readable, writable
Integer64. Range: 1 – 2147483647 Default: 0
pyobject-prop : A property that contains an pyobject
flags: readable, writable
Boxed pointer of type “PyObject”
str-prop : A property that contains str
flags: readable, writable
String. Default: null
Segmentation fault
Thank you again for such great tutorial.
Just curious about do_transform and do_transform_in. Which function should be good if the job is like videocrop to output a cropped stream where source and sink caps like width and height are different?
Regards
Hi Yu You,
Thanks for question)
For plugins where input_size != output_size use do_transform.
Checkout this videocrop implementation. This should help 😉
Best regards,
Taras Lishchenko
Hi Taras,
Thank you so much for such a learning materials!
Regarding:
“Despite mentioned disadvantages of Python implementation of Gstreamer elements it is still faster than any other Python approach in image processing (like OpenCV),”
Do you mean that gstreamer is faster than OpenCV compiled with ffpmeg?
Hi Wiktor,
According to my experience, when we are talking about general video processing based on LibAV then FFMPEG performance is going to be almost same to Gstreamer.
But with Gstreamer there are a lot more advantages when using hardware-accelerated video processing (DeepStream, Nvidia, VAAPI, …). So when developing video applications you are flexible to any platform. As far as I know ffmpeg doesn’t have such hardware-accelerated support (especially, like DeepStream SDK provides with NVIDIA capabilities).
Also with OpenCV there is always a memory copy when buffer is converted from ffmpeg or gstreamer specific format (exception for GPU-allocated CV Mat). And with Gstreamer Plugin – there is no buffer copy, as created numpy array just points to Gst.Buffer allocated memory.
Despite the fact that Gstreamer is difficult to use and learn, it gives a huge flexibility, comparable performance and various platforms support.
But for simple, well-defined application I suggest OpenCV 🙂
Hope this helps 🙂
Hi Taras, I really like this tutorial. I try to “pip install -r requirements.txt” and got stuck at the last install item with following error message: Could you tell me what should I do to fix this? thanks a lot.
Collecting gstreamer-python@ git+https://github.com/jackersson/gstreamer-python.git#egg=gstreamer-python
Cloning https://github.com/jackersson/gstreamer-python.git to /tmp/pip-install-jyu7vlz9/gstreamer-python
Running command git clone -q https://github.com/jackersson/gstreamer-python.git /tmp/pip-install-jyu7vlz9/gstreamer-python
Collecting numpy>=1.14.3
Downloading numpy-1.19.0-cp36-cp36m-manylinux2010_x86_64.whl (14.6 MB)
|████████████████████████████████| 14.6 MB 10.1 MB/s
Collecting pycairo>=1.18.2
Using cached pycairo-1.19.1.tar.gz (205 kB)
Collecting PyGObject
Using cached PyGObject-3.36.1.tar.gz (716 kB)
Installing build dependencies … error
ERROR: Command errored out with exit status 1:
command: /home/paul/gst-python-plugins/venv/bin/python3 /home/paul/gst-python-plugins/venv/lib/python3.6/site-packages/pip install –ignore-installed –no-user –prefix /tmp/pip-build-env-dqze49a5/overlay –no-warn-script-location –no-binary :none: –only-binary :none: -i https://pypi.org/simple — setuptools wheel pycairo
cwd: None
Complete output (56 lines):
Collecting setuptools
Using cached setuptools-49.2.0-py3-none-any.whl (789 kB)
Collecting wheel
Using cached wheel-0.34.2-py2.py3-none-any.whl (26 kB)
Collecting pycairo
Using cached pycairo-1.19.1.tar.gz (205 kB)
Building wheels for collected packages: pycairo
Building wheel for pycairo (setup.py): started
Building wheel for pycairo (setup.py): finished with status ‘error’
ERROR: Command errored out with exit status 1:
command: /home/paul/gst-python-plugins/venv/bin/python3 -u -c ‘import sys, setuptools, tokenize; sys.argv[0] = ‘”‘”‘/tmp/pip-install-2dl40pca/pycairo/setup.py'”‘”‘; __file__='”‘”‘/tmp/pip-install-2dl40pca/pycairo/setup.py'”‘”‘;f=getattr(tokenize, ‘”‘”‘open'”‘”‘, open)(__file__);code=f.read().replace(‘”‘”‘\r\n'”‘”‘, ‘”‘”‘\n'”‘”‘);f.close();exec(compile(code, __file__, ‘”‘”‘exec'”‘”‘))’ bdist_wheel -d /tmp/pip-wheel-3e7dw5vy
cwd: /tmp/pip-install-2dl40pca/pycairo/
Complete output (15 lines):
running bdist_wheel
running build
running build_py
creating build
creating build/lib.linux-x86_64-3.6
creating build/lib.linux-x86_64-3.6/cairo
copying cairo/__init__.py -> build/lib.linux-x86_64-3.6/cairo
copying cairo/__init__.pyi -> build/lib.linux-x86_64-3.6/cairo
copying cairo/py.typed -> build/lib.linux-x86_64-3.6/cairo
running build_ext
Package cairo was not found in the pkg-config search path.
Perhaps you should add the directory containing `cairo.pc’
to the PKG_CONFIG_PATH environment variable
No package ‘cairo’ found
Command ‘[‘pkg-config’, ‘–print-errors’, ‘–exists’, ‘cairo >= 1.13.1′]’ returned non-zero exit status 1.
—————————————-
ERROR: Failed building wheel for pycairo
Running setup.py clean for pycairo
Failed to build pycairo
Installing collected packages: setuptools, wheel, pycairo
Running setup.py install for pycairo: started
Running setup.py install for pycairo: finished with status ‘error’
ERROR: Command errored out with exit status 1:
command: /home/paul/gst-python-plugins/venv/bin/python3 -u -c ‘import sys, setuptools, tokenize; sys.argv[0] = ‘”‘”‘/tmp/pip-install-2dl40pca/pycairo/setup.py'”‘”‘; __file__='”‘”‘/tmp/pip-install-2dl40pca/pycairo/setup.py'”‘”‘;f=getattr(tokenize, ‘”‘”‘open'”‘”‘, open)(__file__);code=f.read().replace(‘”‘”‘\r\n'”‘”‘, ‘”‘”‘\n'”‘”‘);f.close();exec(compile(code, __file__, ‘”‘”‘exec'”‘”‘))’ install –record /tmp/pip-record-4fl6oy2d/install-record.txt –single-version-externally-managed –prefix /tmp/pip-build-env-dqze49a5/overlay –compile –install-headers /home/paul/gst-python-plugins/venv/include/site/python3.6/pycairo
cwd: /tmp/pip-install-2dl40pca/pycairo/
Complete output (15 lines):
running install
running build
running build_py
creating build
creating build/lib.linux-x86_64-3.6
creating build/lib.linux-x86_64-3.6/cairo
copying cairo/__init__.py -> build/lib.linux-x86_64-3.6/cairo
copying cairo/__init__.pyi -> build/lib.linux-x86_64-3.6/cairo
copying cairo/py.typed -> build/lib.linux-x86_64-3.6/cairo
running build_ext
Package cairo was not found in the pkg-config search path.
Perhaps you should add the directory containing `cairo.pc’
to the PKG_CONFIG_PATH environment variable
No package ‘cairo’ found
Command ‘[‘pkg-config’, ‘–print-errors’, ‘–exists’, ‘cairo >= 1.13.1′]’ returned non-zero exit status 1.
—————————————-
ERROR: Command errored out with exit status 1: /home/paul/gst-python-plugins/venv/bin/python3 -u -c ‘import sys, setuptools, tokenize; sys.argv[0] = ‘”‘”‘/tmp/pip-install-2dl40pca/pycairo/setup.py'”‘”‘; __file__='”‘”‘/tmp/pip-install-2dl40pca/pycairo/setup.py'”‘”‘;f=getattr(tokenize, ‘”‘”‘open'”‘”‘, open)(__file__);code=f.read().replace(‘”‘”‘\r\n'”‘”‘, ‘”‘”‘\n'”‘”‘);f.close();exec(compile(code, __file__, ‘”‘”‘exec'”‘”‘))’ install –record /tmp/pip-record-4fl6oy2d/install-record.txt –single-version-externally-managed –prefix /tmp/pip-build-env-dqze49a5/overlay –compile –install-headers /home/paul/gst-python-plugins/venv/include/site/python3.6/pycairo Check the logs for full command output.
—————————————-
ERROR: Command errored out with exit status 1: /home/paul/gst-python-plugins/venv/bin/python3 /home/paul/gst-python-plugins/venv/lib/python3.6/site-packages/pip install –ignore-installed –no-user –prefix /tmp/pip-build-env-dqze49a5/overlay –no-warn-script-location –no-binary :none: –only-binary :none: -i https://pypi.org/simple — setuptools wheel pycairo Check the logs for full command output.
Hi Paul,
Let’s try the next steps.
Check if everything installed from here. In your case install the following:
sudo apt install libcairo2-dev python3-gi python-gi-dev
Make sure that PyGObject and PyCairo can be installed with pip :
source venv/bin/activate
pip install -U wheel pip setuptools
pip install -U PyGObject
pip install -U pycairo
And after that try to install gstreamer-python again.
Let me know if this helps 😉
Best regards,
Taras
Hi Taras, thanks for sharing this awesome tutorial. I’ve already read this, but still confused while implementing this to my scenario. I want to add some database operations inside gstreamer. Let say, after doing object detection, i’ll insert raw data to database. What is the best way to doing that? Am i required to do database operation with custom gstreamer plugin? or just grab meta data from probe and do some operations in there?
Thanks
# root @ 09c1f2b17b52 in ~/gst-python-plugins [9:35:32] C:127
$ echo $GST_PLUGIN_PATH
/usr/lib/gstreamer-1.0/:/root/gst-python-plugins/gst/
# root @ 09c1f2b17b52 in ~/gst-python-plugins [9:35:47]
$ ll /usr/lib/gstreamer-1.0/
total 76K
-rwxr-xr-x 1 root root 71K Aug 20 06:33 libgstpython.cpython-36m-x86_64-linux-gnu.so
-rwxr-xr-x 1 root root 1.2K Aug 20 06:33 libgstpython.la
# root @ 09c1f2b17b52 in ~/gst-python-plugins [9:36:00] C:1
$ rm -rf ~/.cache/gstreamer-1.0
# root @ 09c1f2b17b52 in ~/gst-python-plugins [9:36:01]
$ ll /root/gst-python-plugins/gst/python/
total 28K
-rw-r–r– 1 root root 5.1K Aug 20 03:36 gstblur_py.py
-rw-r–r– 1 root root 4.9K Aug 21 08:32 gstplugin_py.py
-rw-r–r– 1 root root 8.6K Aug 20 03:22 gstvideocrop.py
# root @ 09c1f2b17b52 in ~/gst-python-plugins [9:36:18]
$ gst-inspect-1.0 gstplugin_py
** (gst-plugin-scanner:4581): CRITICAL **: 09:36:24.557: gi.repository.Gst is no dict
No such element or plugin ‘gstplugin_py’
Hi,
This problem is connected with gstreamer-python installation. Try to use -v flag when installing package with pip. It will show you an error message. Checkout similar output without error: log_file
Best regards,
Taras
gst-inspect-1.0 python
Traceback (most recent call last):
File “/home/osa/MLTools/gst-python-plugins/gst/python/gstblur_py.py”, line 17, in
from gstreamer import Gst, GObject, GLib, GstBase
ModuleNotFoundError: No module named ‘gstreamer’
Traceback (most recent call last):
File “/home/osa/MLTools/gst-python-plugins/gst/python/gstvideocrop.py”, line 27, in
from gstreamer.utils import gst_buffer_with_caps_to_ndarray # noqa:F401,F402
ModuleNotFoundError: No module named ‘gstreamer’
Plugin Details:
Name python
Description loader for plugins written in python
Filename /home/osa/.virtualenvs/gst/lib/gstreamer-1.0/libgstpython.cpython-36m-x86_64-linux-gnu.so
Version 1.14.5
License LGPL
Source module gst-python
Binary package GStreamer GObject Introspection overrides for Python
Origin URL http://gstreamer.freedesktop.org
gstplugin_py: Name
1 features:
+– 1 elements
ERROR | root | 22.12 07:33:35.726 | Dummy-1 | cannot reshape array of size 307200 into shape (240,320,3)
getting this error when running gst-launch-1.0 videotestsrc ! gaussian_blur kernel=9 sigmaX=5.0 sigmaY=5.0 ! videoconvert ! autovideosink