Search code examples
pythonmacosgstreamerpython-gstreamer

Homebrew Gstreamer, Python and video


I am trying to go through the Gstreamer tutorial, but I got stuck on the first two already (1st, 2nd). Here is the copy of the 2nd lesson's code, for reference:

#!/usr/bin/env python3
import sys
import gi
import logging

gi.require_version("GLib", "2.0")
gi.require_version("GObject", "2.0")
gi.require_version("Gst", "1.0")

from gi.repository import Gst, GLib, GObject


logging.basicConfig(level=logging.DEBUG, format="[%(name)s] [%(levelname)8s] - %(message)s")
logger = logging.getLogger(__name__)

# Initialize GStreamer
Gst.init(sys.argv[1:])

# Create the elements
source = Gst.ElementFactory.make("videotestsrc", "source")
sink = Gst.ElementFactory.make("autovideosink", "sink")

# Create the empty pipeline
pipeline = Gst.Pipeline.new("test-pipeline")

if not pipeline or not source or not sink:
    logger.error("Not all elements could be created.")
    sys.exit(1)


# Build the pipeline
pipeline.add(source, sink)
if not source.link(sink):
    logger.error("Elements could not be linked.")
    sys.exit(1)

# Modify the source's properties
source.props.pattern = 0
# Can alternatively be done using `source.set_property("pattern",0)`
# or using `Gst.util_set_object_arg(source, "pattern", 0)`

# Start playing
ret = pipeline.set_state(Gst.State.PLAYING)
if ret == Gst.StateChangeReturn.FAILURE:
    logger.error("Unable to set the pipeline to the playing state.")
    sys.exit(1)

# Wait for EOS or error
bus = pipeline.get_bus()
msg = bus.timed_pop_filtered(Gst.CLOCK_TIME_NONE, Gst.MessageType.ERROR | Gst.MessageType.EOS)

# Parse message
if msg:
    if msg.type == Gst.MessageType.ERROR:
        err, debug_info = msg.parse_error()
        logger.error(f"Error received from element {msg.src.get_name()}: {err.message}")
        logger.error(f"Debugging information: {debug_info if debug_info else 'none'}")
    elif msg.type == Gst.MessageType.EOS:
        logger.info("End-Of-Stream reached.")
    else:
        # This should not happen as we only asked for ERRORs and EOS
        logger.error("Unexpected message received.")

pipeline.set_state(Gst.State.NULL)

If I run this code, the Python's rocket icon starts jumping on the Dock, but no video is shown. If I launch it with GST_DEBUG=5 python3 02.py, I can see the things happening and time ticking, just no video output.

When I run the 1st lesson's code, which creates a playbin, there is no Python rocket on the Dock; I hear the audio playing, but again, no video.

If I change the 2nd lesson's code (copied above) and make the videotestsrc and autovideosink into audiotestsrc and autoaudiosink (and comment out the pattern parameter), again, it works — I can hear the beep.

The Gstreamer command line tools work correctly, showing a video window for the equivalent pipelines:

gst-launch-1.0 playbin uri=https://gstreamer.freedesktop.org/data/media/sintel_trailer-480p.webm
gst-launch-1.0 videotestsrc pattern=0 ! autovideosink

Any ideas why the Python version does not work correctly?


I have installed Gstreamer using brew install gstreamer (version: stable 1.22.2 (bottled), HEAD), with Python 3.11.3, on Mac OS Ventura 13.2.1 (22D68).


Solution

  • I believe there is nothing wrong with your python code. It is likely an issue with the element that is being selected by the autovideosink.

    I've seen this happen with the vaapisink, where due to a bad GPU driver or just any incompatibility it can't display the window. You can determine which sink is selected by the autovideosink from running the pipeline with the verbose (-v) option.

    If it is the vaapisink you can either uninstall the gstreamer vaapi elements (apt remove gstreamer1.0-vaapi) or trying to fix your installation. If it is another sink element you will need to debug that particular element installation or uninstall it. Once fixed or uninstalled autovideosink will use the fixed version or select another sink option that will likely work for you.

    If you're just interested in the output and not necessarily making autiovideosink work you can replace the autovideosink with another explicit video sink that you're sure works with your system, I recommend you try xvimagesink or ximagesink. That should display the videotestsrc properly.