I am trying to launch a GStreamer command in Python using the Gst.parse_launch() function from GObject Introspection. I have two video sources, one is a mp4 file and one is my webcam.
In terminal, my commands are
gst-launch-1.0 -e filesrc location=Resources/Data/video1.mp4 ! decodebin ! videoconvert ! tee name=t t. ! queue ! autovideosink name=appsink t. ! queue ! x264enc tune=zerolatency ! mp4mux ! filesink location=output.mp4
and
gst-launch-1.0 -e v4l2src device=/dev/video0 ! decodebin ! videoconvert ! tee name=t t. ! queue ! autovideosink name=appsink t. ! queue ! x264enc tune=zerolatency ! mp4mux ! filesink location=output.mp4
both behave as expected. Launch, display the video and on pressing ctrl-c save the recording of the video to a mp4 file.
However, when I try to do this in python, using the Gst.parse_launch() function the -e flag generates a syntax error.
My code
import streamlit as st
import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst, GObject
#INPUT = "v4l2src device=/dev/video0" # source from webcam
INPUT = "filesrc location=Data/video1.mp4" # source from file
Gst.init(None)
pipeline_string = f"-e {INPUT} ! decodebin ! videoconvert ! tee name=t t. ! queue ! autovideosink name=appsink t. ! queue ! x264enc tune=zerolatency ! mp4mux ! filesink location=output.mp4"
pipeline = Gst.parse_launch(pipeline_string)
pipeline.set_state(Gst.State.PLAYING)
If I remove the -e flag, the code runs
pipeline_string = f"{INPUT} ! decodebin ! videoconvert ! tee name=t t. ! queue ! autovideosink name=appsink t. ! queue ! x264enc tune=zerolatency ! mp4mux ! filesink location=output.mp4"
I use the following to terminate the run
pipeline.send_event(Gst.Event.new_eos())
pipeline.set_state(Gst.State.NULL)
However, the saved mp4 is broken. When I tried to open it in ubuntu the message "An error occurred This file contains no playable streams." is displayed.
I have tried increasing the max-size-buffers, max-size-bytes and max-size-time which allowed me to record from webcam to a mp4. However, when I use a mp4 file as source the saved mp4 is still broken.
Can some one point me to the correct way to run the GStreamer command in python so that I can display, record and save a video from a source to mp4?
Thank you
The
-eoption is specific togst-launch-1.0and is not valid pipeline syntax. Underneath it does exactly what you implemented:The problem with you code is that you need to wait for the EOS to actually be processed. Unlike other events, the EOS travels inline with buffers so it actually takes some time to process. Install a bus callback and wait for the EOS to be posted. The EOS is posted when all elements have processed it.
Checkout this example: https://github.com/GStreamer/gstreamer/blob/abdd1967ad55bdc939aea619f3b6a12eb4fb00d7/subprojects/gst-python/examples/helloworld.py#L47