Creating Gstreamer sink for widget in GTK4 application

I’m not super experienced with Python or GTK, but am hoping to create a video color balance application in GTK. I tried to follow a few of the methods discussed on this site for integrating video with a Python GTK4 application, but nothing has quite worked so far. I started out working with Flatpak, but to reduce complexity, I’m currently developing a normal, non-sandboxed program on Fedora 37.

Using the Gtk.Video widget displays a black screen and some controls, but I haven’t gotten it to play any videos yet. I don’t need playback controls, so I figured I would try setting up a Gstreamer pipeline with a ‘sink’ that supports the GTK framework.

from gi.repository import Adw, Gtk, Gst, GstVideo
from pprint import pprint

class VideotuneWindow(Adw.ApplicationWindow):

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        self.box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        self.set_content(self.box)

        #gtksink = Gst.ElementFactory.make("gtk4paintablesink")
        #gtksink = Gst.ElementFactory.make("clappersink")
        #gtksink = Gst.ElementFactory.make("glsinkbin")
        gtksink = Gst.ElementFactory.make("gtkglsink")
        help(gtksink)
        self.video = gtksink.widget
        self.video.set_vexpand(True)

        self.box.append(self.video)

gtk4paintablesink should be supported in Gstreamer 1.20, which was released about a year ago, but Fedora 37 and Flatpak return None from the make function for this type of sink, which implies that Gstreamer doesn’t know about that element. clappersink is distributed with the Clapper GTK4 program, but despite help(gtksink) saying that there is a widget property available that’s also used in the Clapper source code itself, trying to access that property results in an attribute error. The next two behave similarly.

Clapper itself works great for me, so perhaps I am missing something here. Does anyone know how to set up a Gstreamer sink widget in GTK4?

gtk4paintablesink is not included in the Flatpak SDK yet, see Ship gst-plugins-rs together with the other GStreamer components (#1502) · Issues · freedesktop-sdk / freedesktop-sdk · GitLab.

You would have to build it as part of your Flatpak application.

gtkglsink is for GTK3 and not going to work in a GTK4 application.

Thanks for your help. I look forward to wider distribution of the Gstreamer plugin for GTK4, but in the meantime, it might make sense for me to stick to GTK 3 for the sake of compatibility with older systems outside of Flatpak.

However I still get the AttributeError: 'GstGtkGLSink' object has no attribute 'widget' error when trying to use gtkglsink. Am I doing this wrong, or is there some kind of bug? (The code is very similar to what I already wrote above). pprint(dir(gtksink)) does list many other attributes, so it’s working at least to that extent.

I created a bug report for pygobject.

“widget” is a property of the GstGtkGLSink class, which can be accessed under props:

self.video = gtksink.props.widget

In case anyone finds it useful, I managed to get a demo working with Clapper’s clappersink. Here’s part of the code:

from gi.repository import Gtk, Adw, Gst

class VideotuneWindow(Adw.ApplicationWindow):

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        source = Gst.ElementFactory.make("gltestsrc", "source")
        source.set_property("pattern", 0)

        gtksink = Gst.ElementFactory.make("clappersink", "sink")
        gtksink.set_state(Gst.State.READY)

        pipeline = Gst.Pipeline()
        pipeline.add(source)
        pipeline.add(gtksink)

        caps = Gst.Caps.new_any()
        caps.set_value("width", 640)
        caps.set_value("height", 480)
        source.link_filtered(gtksink, caps)
        #source.link(gtsink) # if the above isn't correct, and you don't want to set Gst.Caps

        self.picture = Gtk.Picture()
        self.picture.set_paintable(gtksink.props.widget.get_paintable())

        self.box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        self.box.append(self.picture)

        self.set_default_size(640, 480)
        self.set_content(self.box)


        bus = gtksink.get_bus()
        pipeline.set_state(Gst.State.PLAYING)

The configured window shows the test screen, but there is also another standalone window that shows up. I suspect that could be due to how clappersink was designed. One of the next things I’ll try is to compile gtk4paintablesink for Flatpak.

You are using it incorrectly. Since clappersink gives you a ready to use widget, just place that in your widget hierarchy instead of accessing internal paintable.

Another window pops up because it was designed to also work with gst-launch-1.0 for testing purposes when user does not place widget anywhere in his app.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.