Code Monkey home page Code Monkey logo

gstreamer-python's Introduction

gstreamer-python

Purpose

  • abstraction over PyGOBJECT API for Gstreamer
  • work with Gstreamer metadata
  • common tools for Gstreamer pipeline management
  • easy gst-python installation

Install

Install OS packages

in-place

python3 -m venv venv

source venv/bin/activate
pip install --upgrade wheel pip setuptools
pip install --upgrade --requirement requirements.txt

./build-3rd-party.sh
./build-gst-python.sh

pip-package

pip install git+https://github.com/jackersson/gstreamer-python.git@{tag_name}#egg=gstreamer-python

### to skip ./build-gst-python.sh
pip install . -v --install-option "build_py" --install-option "--skip-gst-python"

### to set specific gstreamer version
export GST_VERSION=1.14.5

Test

PYTHONPATH=. pytest tests/ -s --verbose

Tools

Setup

  • By default Gstreamer tools use libgstreamer-1.0.so.0
export LIB_GSTREAMER_PATH=libgstreamer-1.0.so.0

Export LIB_GSTREAMER_PATH with custom path to libgstreamer.so

Setup Log Level
export GST_PYTHON_LOG_LEVEL=0, 1, 2, 3, 4, 5
from gstreamer import map_gst_buffer
with map_gst_buffer(pbuffer, Gst.MapFlags.READ | Gst.MapFlags.WRITE) as mapped:
            // do_something with mapped

Make Gst.Memory writable

from gstreamer import map_gst_memory
with map_gst_memory(memory, Gst.MapFlags.READ | Gst.MapFlags.WRITE) as mapped:
            // do_something with mapped

Get Gst.Buffer shape (width,height) from Gst.Caps

from gstreamer import get_buffer_size
ret, (width, height) = get_buffer_size(Gst.Caps)

Convert Gst.Buffer to np.ndarray

from gstreamer import gst_buffer_to_ndarray, gst_buffer_with_pad_to_ndarray

array = gst_buffer_to_ndarray(Gst.Buffer, width, height, channels)
# or
array = gst_buffer_with_pad_to_ndarray(Gst.Buffer, Gst.Pad, channels)

GstPipeline

  • With GstPipeline run any gst-launch pipeline in Python
from gstreamer import GstPipeline

command = "videotestsrc num-buffers=100 ! fakesink sync=false"
with GstPipeline(command) as pipeline:
    ...

GstVideoSource based on AppSink

  • With GstVideoSource run any gst-launch pipeline and receive buffers in Python
from gstreamer import GstVideoSource

width, height, num_buffers = 1920, 1080, 100
caps_filter = 'capsfilter caps=video/x-raw,format=RGB,width={},height={}'.format(width, height)
command = 'videotestsrc num-buffers={} ! {} ! appsink emit-signals=True sync=false'.format(
num_buffers, caps_filter)
with GstVideoSource(command) as pipeline:
    buffers = []
    while len(buffers) < num_buffers:
        buffer = pipeline.pop()
        if buffer:
            buffers.append(buffer)
    print('Got: {} buffers'.format(len(buffers)))

GstVideoSink based on AppSrc

  • With GstVideoSink push buffers in Python to any gst-launch pipeline
from gstreamer import GstVideoSink

width, height = 1920, 1080
command = "appsrc emit-signals=True is-live=True ! videoconvert ! fakesink sync=false"
with GstVideoSink(command, width=width, height=height) as pipeline:
    for _ in range(10):
        pipeline.push(buffer=np.random.randint(low=0, high=255, size=(height, width, 3), dtype=np.uint8))

Metadata

   x
   y
   width
   height
   confidence
   class_name
   track_id

Examples

Run Gstreamer pipeline in Python using Gst.ElementFactory

python examples/pipeline_with_factory.py

Run Gstreamer pipeline in Python using Gst.parse_launch

python examples/pipeline_with_parse_launch.py -p "videotestsrc num-buffers=100 pattern=1 ! autovideosink"

Capture frames (np.ndarray) from any Gstreamer pipeline

PYTHONPATH=. python examples/run_appsink.py -p "videotestsrc num-buffers=100 ! capsfilter caps=video/x-raw,format=RGB,width=640,height=480 ! appsink emit-signals=True"

Push images (np.ndarray) to any Gstreamer pipeline

PYTHONPATH=. python examples/run_appsrc.py -p "appsrc emit-signals=True is-live=True caps=video/x-raw,format=RGB,width=640,height=480 ! queue ! videoconvert ! autovideosink"  -n 1000

gstreamer-python's People

Contributors

edumotya avatar jackersson avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gstreamer-python's Issues

Metadata class_name field overwritten

Using the gst_objects_info_meta library and Python bindings, it seems that the class_name field is getting overwritten/corrupted. For instance, I've got detector and annotator elements, where the former is generating the bounding boxes, and the latter is drawing them on the frame. Printing things out while the pipeline runs, I get something like b'\x01' as the class label. I assume this has something to do with memory not being allocated correctly for that field but am not sure how to fix it.

dynamically adding a pipline

Hi,

I'm trying to understand how to dynamically add a pipeline to existing one. I see in

src = Gst.ElementFactory.make("videotestsrc", "my_video_test_src")
the usage of factory.

https://github.com/GStreamer/gst-python/blob/2b5b0d951ed997462c5e1d0ec9f70cabe023058a/examples/dynamic_src.py#L63

is an example of a dynamic factory. Is there an easy way to apply GstPipeline to a dynamic allocated instance?

Kind regards,

Martijn

Build fails, legacy-install-failure

I may be using too recent of dependencies. Using Python 3.8 on Ubuntu 20.

Attempted the following command: pip install . -v --install-option "build_py" --install-option "--skip-gst-python"

Resulted in the following:

  × Running setup.py install for toml did not run successfully.
  │ exit code: 1
  ╰─> See above for output.
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
  full command: /usr/bin/python3 -u -c '
  exec(compile('"'"''"'"''"'"'
  # This is <pip-setuptools-caller> -- a caller that pip uses to run setup.py
  #
  # - It imports setuptools before invoking setup.py, to enable projects that directly
  #   import from `distutils.core` to work with newer packaging standards.
  # - It provides a clear error message when setuptools is not installed.
  # - It sets `sys.argv[0]` to the underlying `setup.py`, when invoking `setup.py` so
  #   setuptools doesn'"'"'t think the script is `-c`. This avoids the following warning:
  #     manifest_maker: standard file '"'"'-c'"'"' not found".
  # - It generates a shim setup.py, for handling setup.cfg-only projects.
  import os, sys, tokenize
  
  try:
      import setuptools
  except ImportError as error:
      print(
          "ERROR: Can not execute `setup.py` since setuptools is not available in "
          "the build environment.",
          file=sys.stderr,
      )
      sys.exit(1)
  
  __file__ = %r
  sys.argv[0] = __file__
  
  if os.path.exists(__file__):
      filename = __file__
      with tokenize.open(__file__) as f:
          setup_py_code = f.read()
  else:
      filename = "<auto-generated setuptools caller>"
      setup_py_code = "from setuptools import setup; setup()"
  
  exec(compile(setup_py_code, filename, "exec"))
  '"'"''"'"''"'"' % ('"'"'/tmp/pip-install-oy1_0t_m/toml_ea05c2edf01f452b96ccba24abf9cd53/setup.py'"'"',), "<pip-setuptools-caller>", "exec"))' install --record /tmp/pip-record-xphty8gv/install-record.txt --single-version-externally-managed --user --prefix= --compile --install-headers /home/colin/.local/include/python3.8/toml build_py --skip-gst-python
  cwd: /tmp/pip-install-oy1_0t_m/toml_ea05c2edf01f452b96ccba24abf9cd53/
  Running setup.py install for toml ... error
error: legacy-install-failure

× Encountered error while trying to install package.
╰─> toml

note: This is an issue with the package mentioned above, not pip.
hint: See above for output from the failure.

Recommended way to handle KeyboardInterrupt (ctrl-c) properly in apps

Hi

(sorry this may not be an issue but a question)

I have made a test Python app that use the GstContext. As GstContext runs inside a thread and I could not find a way to "terminate" it properly. The main thread could not catch the KeyboardInterrupt (even I have tried the signal).

Is there a way to handle KeyboardInterrupt at the main thread (app) and shutdown pipeline gracefully?

Thanks.

Yu

except Exception:

Readme question

Readme includes sections “install OS packages”, “in-place”, “pip-package” under the section Install. Are all 3 of those steps needed to use the pip package?

libgst_objects_info_meta.so: cannot open shared object file: No such file or directory

After executed the installation part, I tried to import from pygst_utils.gst_objects_info_meta import gst_meta_write and got an error:

>>> from pygst_utils.gst_objects_info_meta import gst_meta_write
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.6/dist-packages/pygst_utils/gst_objects_info_meta.py", line 27, in <module>
    libc = CDLL(os.path.join(cwd, "3rd_party/gstreamer/build/libgst_objects_info_meta.so"))
  File "/usr/lib/python3.6/ctypes/__init__.py", line 348, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: /usr/local/lib/python3.6/dist-packages/pygst_utils/3rd_party/gstreamer/build/libgst_objects_info_meta.so: cannot open shared object file: No such file or directory

Any ideas on how to solve it?

run_rtsp example throw: TypeError: 'Iterator' object is not iterable

Throw an Error TypeError: 'Iterator' object is not iterable in example run_rtsp.py.

return [e for e in element.iterate_elements() if isinstance(e, cls)]

Log:

Traceback (most recent call last):
  File "rtsp-server.py", line 212, in do_configure
    appsrcs = get_child_by_cls(rtsp_media.get_element(), GstApp.AppSrc)
  File "rtsp-server.py", line 162, in get_child_by_cls
    return [e for e in element.iterate_elements() if isinstance(e, cls)]
TypeError: 'Iterator' object is not iterable

Installing in Dockerfile breaks Deepstream installation

I am installing this package using pip within a Dockerfile build:
RUN pip3 install git+https://github.com/jackersson/gstreamer-python.git#egg=gstreamer-python
The base image I am using is the Deepstream image nvcr.io/nvidia/deepstream:6.0.1-devel. If I do this, when I run the container, Deepstream plugins can't be found anymore (e.g. get-inspect-1.0 nvinfer can't find nvinfer). However, if I install this very library (in the same way) within the container (vs during the docker build) I have no issues and everything works fine: Deepstream plugins can be found.
Any hint on what could be causing this issue?

Install option --skip-gst-python fails

I just tried to install gstreamer-python while skipping gst-python and installation failed.

Error logs:

gstreamer-python-install-error.txt

Steps to reproduce:

git clone git+https://github.com/jackersson/gstreamer-python.git
cd gstreamer-python
pip3 --user install . -v --install-option "build_py" --install-option "--skip-gst-python"

I would be grateful for any pointers to fix this!

Internal streaming error during appsrc example

Hey,

thanks for this great work. I want to use it in an app to push frames to a pipeline after some computer vision magic. However, when running the appsrc example, I encounter the following error:

bob@nano5:~/gstreamer-python$ PYTHONPATH=. python examples/run_appsrc.py -p "appsrc emit-signals=True is-live=True caps=video/x-raw,format=RGB,width=640,height=480 ! queue ! videoconvert ! autovideosink"  -n 1000

INFO   | pygst.GstPipeline    | 13.08 12:22:31.595 | MainThread | GstPipeline 
 gst-launch-1.0 appsrc emit-signals=True is-live=True caps=video/x-raw,format=RGB,width=640,height=480 ! queue ! videoconvert ! autovideosink

INFO   | pygst.GstPipeline    | 13.08 12:22:31.672 | MainThread | Starting GstPipeline

DEBUG  | pygst.GstPipeline    | 13.08 12:22:31.674 | MainThread | GstPipeline Setting pipeline state to PLAYING ... 

DEBUG  | pygst.GstPipeline    | 13.08 12:22:31.675 | MainThread | GstPipeline Pipeline state set to PLAYING 

ERROR  | pygst.GstPipeline    | 13.08 12:22:31.695 | Thread-1 | Gstreamer.GstPipeline: Error gst-stream-error-quark: 
Internal data stream error. (1): gstbasesrc.c(3055): gst_base_src_loop (): /GstPipeline:pipeline0/GstAppSrc:appsrc0:
streaming stopped, reason not-negotiated (-4). 

DEBUG  | pygst.GstPipeline    | 13.08 12:22:31.696 | Thread-1 | GstPipeline Stopping pipeline ...

DEBUG  | pygst.GstPipeline    | 13.08 12:22:31.697 | Thread-1 | GstPipeline Reseting pipeline state ....

DEBUG  | pygst.GstPipeline    | 13.08 12:22:31.698 | Thread-1 | GstPipeline Gst.Pipeline successfully destroyed

INFO   | pygst.GstPipeline    | 13.08 12:22:38.935 | MainThread | GstPipeline Shutdown requested ...

INFO   | pygst.GstPipeline    | 13.08 12:22:38.935 | MainThread | GstPipeline successfully destroyed

DEBUG  | pygst.GstContext     | 13.08 12:22:38.935 | MainThread | GstContext Quitting main loop ...

DEBUG  | pygst.GstContext     | 13.08 12:22:38.937 | MainThread | GstContext Joining main loop thread...

platform: Jetson nano with jetpack 4.5.1
python: 3.6.9
gstreamer: 1.14.5

Any idea what might be the reason?
Cheers

Project license

Hi

This is a very good Python module/utility classes on top of the low-level module "py-gst".
It seems that this repo does not have any license defined.

PYGOBJECT version mismatch

Was following the README.md file and got this error when running the "build-gst-python.sh" script:

checking for GST... yes
checking for PYGOBJECT... configure: error: Package requirements (pygobject-3.0 >= 3.8) were not met:

No package 'pygobject-3.0' found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Alternatively, you may set the environment variables PYGOBJECT_CFLAGS
and PYGOBJECT_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.

make: *** No targets specified and no makefile found. Stop.
make: Nothing to be done for 'install'.

Any tips on how to fix this?

OSError: dlopen(libgstreamer-1.0.so.0, 6): image not found

gst_hack.py was throwing this error, when running on a mac:

---------------------------------------------------------------------------
OSError                                   Traceback (most recent call last)
~/Documents/mythic-projects/OKR_2019Q2/gstreamer_tutorials/test_gst_pipeline.py in <module>
      6 import os
      7 import logging
----> 8 from pygst_utils import utils
      9 logging.basicConfig(level=logging.DEBUG)
     10

~/Documents/mythic-projects/OKR_2019Q2/venv/lib/python3.6/site-packages/pygst_utils/__init__.py in <module>
      4 from gi.repository import Gst, GstBase, GObject, GLib
      5
----> 6 from .gst_hacks import map_gst_buffer, get_buffer_size
      7 from .gst_hacks import map_gst_memory
      8

~/Documents/mythic-projects/OKR_2019Q2/venv/lib/python3.6/site-packages/pygst_utils/gst_hacks.py in <module>
     25 _GST_MAP_INFO_POINTER = POINTER(_GstMapInfo)
     26
---> 27 _libgst = CDLL("libgstreamer-1.0.so.0")
     28 _libgst.gst_buffer_map.argtypes = [c_void_p, _GST_MAP_INFO_POINTER, c_int]
     29 _libgst.gst_buffer_map.restype = c_int

/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ctypes/__init__.py in __init__(self, name, mode, handle, use_errno, use_last_error)
    346
    347         if handle is None:
--> 348             self._handle = _dlopen(self._name, mode)
    349         else:
    350             self._handle = handle

OSError: dlopen(libgstreamer-1.0.so.0, 6): image not found

I was able to get around it by setting https://github.com/jackersson/pygst-utils/blob/master/pygst_utils/gst_hacks.py#L27 to the .dylib path

for my machine, it was this:

libgst = CDLL("/usr/local/lib/libgstreamer-1.0.dylib")

[Question] Change the buffer size

As per README, you can modify the buffer as

with map_gst_buffer(buffer, Gst.MapFlags.READ | Gst.MapFlags.WRITE) as mapped:

My question is: what if I want to increase the buffer size by appending some bytes from Python?
Is it possible? If so, how to convert Python bytearray to C byte array, using Ctypes?

Thanks.

Best Regards,

Yu

Writable array requested but buffer is not writeable

I am trying to draw some shapes on the video stream using PyCairo:

with map_gst_buffer(buffer, Gst.MapFlags.READ | Gst.MapFlags.WRITE) as mapped:
     # code to draw shapes

However I get an error:

Writable array requested but buffer is not writeable

This error is raised in the map_gst_buffer function in gst_hacks.py

    if flags & Gst.MapFlags.WRITE and _libgst.gst_mini_object_is_writable(ptr) == 0:
        raise ValueError(
            "Writable array requested but buffer is not writeable")

What am I missing here?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.