pythongstreamerzbargobject

reading decoded zbar element messages from gst pipeline bus


Using the example CLI (command-line-interface) pipeline from the documentation:

gst-launch-1.0 -m v4l2src ! videoconvert ! zbar ! videoconvert ! autovideosink

with the option -m which adds Output messages posted on the pipeline's bus my program works as I would expect: Present QR code to webcam, then program prints the decoded QR data. If I present a QR code to my webcam I get the following output in a terminal:

Got message #103 from element "zbar0" (element): barcode,
timestamp=(guint64)5069092054, stream-time=(guint64)5069092054,
running-time=(guint64)5069092054, type=(string)QR-Code,
symbol=(string)http://www.stackoverflow.com, quality=(int)1,
duration=(guint64)100000000;

If I take this pipeline and turn into Python code:

import sys
import gi
gi.require_version('Gst', '1.0')
from gi.repository import GObject, Gst, GLib

def bus_call(bus, message, loop):

    print("message:",message)
    print("message.src:",message.src)
    print("message.src.get_name():",message.src.get_name())

    t = message.type
    if t == Gst.MessageType.EOS:
        sys.stdout.write("End-of-stream\n")
        loop.quit()
    elif t == Gst.MessageType.WARNING:
        err, debug = message.parse_warning()
        sys.stderr.write("Warning: %s: %s\n" % (err, debug))
    elif t == Gst.MessageType.ERROR:
        err, debug = message.parse_error()
        sys.stderr.write("Error: %s: %s\n" % (err, debug))
        loop.quit()
    return True

def my_pipeline():

    Gst.init(None)

    # Create Pipeline
    pipeline = Gst.parse_launch("v4l2src device=/dev/video0 ! \
                                 videoconvert ! video/x-raw,width=640,height=480,framerate=30/1 ! \
                                 videoconvert ! zbar ! videoconvert ! autovideosink")

    # Create stream loop
    loop = GLib.MainLoop()

    # Setup pipeline bus
    bus = pipeline.get_bus()
    bus.add_signal_watch()
    bus.enable_sync_message_emission()
    bus.connect("message", bus_call, loop)

    print("Starting pipeline...\n")
    
    pipeline.set_state(Gst.State.PLAYING)
    try:
        loop.run()
    except:
        pass
    pipeline.set_state(Gst.State.NULL)

if __name__ == '__main__':
    my_pipeline()

then my output for an identified QR code becomes:

message:                  <Gst.Message object at 0x7fe13a4d1880 (GstMessage at 0x11a75a0)>
message.src:              <__gi__.GstZBar object at 0x7fe13a4ebdc0 (GstZBar at 0x11888d0)>
message.src.get_name():   zbar0

No matter what I try to print, it seems impossible to get the decoded message out. Preferably I'd like the full output structure as given from the CLI. After a lot of search, I learned that options like -m are only allowed in the CLI interface. I have tried printing the content of all available methods for the available class objects that seemed even remotely relevant to my goal. How can this very simple task be done?


Solution

  • After not finding anything, anywhere online, I decided to read the manual again to get a better understanding of the mechanisms behind. The answer was quite simple: message.get_structure().to_string()

    Also we can probe when this is triggered by seeing when t == Gst.MessageType.ELEMENT