Конвейер в исходном вопросе предназначен для отображения видео и воспроизведения аудио, поэтому он использует элементы autovideosink
и autoaudiosink
соответственно. Если вы хотите, чтобы ваши видеокадры передавались в ваше приложение, а не на экран, вам нужно использовать другой элемент приемника, а именно appsink
вместо autovideosink
.
self.appsink = Gst.ElementFactory.make('appsink')
self.pipeline.add(self.appsink)
Элемент appsink
имеет сигнал под названием «new-sample», который вы можете подключить к нему, который срабатывает при появлении нового кадра.
handler_id = self.app_sink.connect("new-sample", self.__on_new_sample)
Затем необходимо преобразовать формат буфера GStreamer в массив Numpy.
def __on_new_sample(self, app_sink):
sample = app_sink.pull_sample()
caps = sample.get_caps()
# Extract the width and height info from the sample's caps
height = caps.get_structure(0).get_value("height")
width = caps.get_structure(0).get_value("width")
# Get the actual data
buffer = sample.get_buffer()
# Get read access to the buffer data
success, map_info = buffer.map(Gst.MapFlags.READ)
if not success:
raise RuntimeError("Could not map buffer data!")
numpy_frame = np.ndarray(
shape=(height, width, 3),
dtype=np.uint8,
buffer=map_info.data)
# Clean up the buffer mapping
buffer.unmap(map_info)
Обратите внимание, что этот код делает определенные предположения о данных кадра, а именно о том, что это трехцветный формат, такой как RGB, и что данные цвета будут беззнаковыми 8-разрядными.