Save np.ndarray frame from opencv with using Gstreamer as video recorder on jetson nano

Hello, guys.

So i have problem with python3 api of gstreamer. I can’t write correctly video in format .mov (i add frames np.ndarray in gstreamer) with using gstreamer. So in constructor i send filename like hostname-date.mov .But all videos has zero bytes size. I think problem may be in method: def release(self) -> None: or in def __init_pipeline(self).

class CustomVideoWriter:
    """ Class that modifies a video stream    
    """

    def __init__(self, filename: str, fps = 22) -> None:
        """
        __init__ 
            Constructor class CustomVideoWriter
        Parameters
        ----------
        filename : str
            Name of the currently being written file

        fps : int
            FPS of the video stream
        """
        # 
        self.desired_fps = fps

        if FLAG_USED_GSTREAMER:
            self.filename = filename
            self.pipeline = None
            self.width = None
            self.height = None
            self.appsrc = None
  

    def __init_pipeline(self):

        self.pipeline = Gst.Pipeline()

        # Create elements
        self.appsrc = Gst.ElementFactory.make("appsrc", "source")
        videoconvert1 = Gst.ElementFactory.make("videoconvert", "videoconvert1")
        videoconvert2 = Gst.ElementFactory.make("videoconvert", "videoconvert2")
        x264enc = Gst.ElementFactory.make("x264enc", "x264enc")
        avimux = Gst.ElementFactory.make("avimux", "avimux")
        filesink = Gst.ElementFactory.make("filesink", "filesink")

        if not self.appsrc or not videoconvert1 or not videoconvert2 or not x264enc or not avimux or not filesink:
            print("Not all elements could be created")
            return

        # Set properties
        self.appsrc.set_property("is-live", True)
        self.appsrc.set_property("format", Gst.Format.TIME)

        filesink.set_property("location", self.filename)

        # Add elements to the pipeline
        self.pipeline.add(self.appsrc)
        self.pipeline.add(videoconvert1)
        self.pipeline.add(videoconvert2)
        self.pipeline.add(x264enc)
        self.pipeline.add(avimux)
        self.pipeline.add(filesink)

        # Link elements
        self.appsrc.link(videoconvert1)
        videoconvert1.link(videoconvert2)
        videoconvert2.link(x264enc)
        x264enc.link(avimux)
        avimux.link(filesink)

        # Set pipeline state to PLAYING
        ret = self.pipeline.set_state(Gst.State.PLAYING)
        if ret == Gst.StateChangeReturn.FAILURE:
            print("Unable to set the pipeline to the PLAYING state")

    def write(self, frame: np.ndarray) -> None:
        """
        write 

        The function of initializing the pipe gstreamer and writing the frame to a file

        Parameters
        ----------
        frame : np.ndarray
            Frame for record
        """
        if FLAG_USED_GSTREAMER:
            if self.pipeline is None:
                self.width, self.height = frame.shape[:2]
                self.__init_pipeline()
            data = frame.tobytes()
            buf = Gst.Buffer.new_allocate(None, len(data), None)
            # Push buffer into appsrc
            ret = self.appsrc.emit("push-buffer", buf)
            if ret != Gst.FlowReturn.OK:
                print("Failed to push buffer to appsrc")
            else:
                print("Done writing frame to file")

    def release(self) -> None:
        """
        release 

        The function of freeing memory from the video stream for recording
        """
        if FLAG_USED_GSTREAMER:
            if self.pipeline:
                self.appsrc.emit("end-of-stream")
                bus = self.pipeline.get_bus()
                self.pipeline.set_state(Gst.State.NULL)
                self.pipeline = None

If you have any idea how to solved/ rewrite please write here :D Thank you for you help!

Hi
Please try matroskamux plugin. It does not require Eos for this file container. Please use it and see if the video file has bytes and can be played.

And here is a C sample for reference:
GStreamer freeze when using qtmux and NVIDIA-accelerated h264/h265 encoding - #7 by DaneLLL

Not sure but it looks like in your code, you send EoS but do not poll it. You may add the function call same as gst_bus_poll() in python and try.

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