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!