У меня есть пример конвейера gstreamer: gst-launch-1.0 v4l2src device=/dev/video2 ! image/jpeg,width=1280, height=800, framerate=30/1 ! v4l2jpegdec ! queue ! v4l2h264enc extra-controls = "controls, h264_profile=4, video_bitrate=620000" ! 'video/x-h264, profile=high, level=(string)4' ! h264parse ! matroskamux ! filesink location=output2.mkv
Что я запускаю его из командной строки. Вместо того, чтобы нажимать ctrl+c для завершения процесса, я хочу отправить ему событие EOS.
Это возможно? И если да, то кто-нибудь делал или какое решение?
Из --help
вывода gst-launch-1.0
:
-e, --eos-on-shutdown Force EOS on sources before shutting the pipeline down
Я отправлял «kill pid» вместо «kill -SIGINT pid», теперь это работает для меня, спасибо.
Вы можете сделать приложение, которое заботится о событиях EOS.
Вы можете попробовать этот пример, написанный на Python.
Депс.
sudo apt install python3-gst-1.0
Пример Python3:
import threading
import time
import gi
gi.require_version('Gst', '1.0')
gi.require_version('GLib', '2.0')
from gi.repository import Gst
from gi.repository import GLib
class Something(RuntimeError):
pass
class GStreamer():
def __init__(self):
Gst.init(None)
self.desc = "videotestsrc is-live=true ! appsink"
self.pipe_obj = None
self.sleep = 20
def create_pipeline(self):
try:
self.pipe_obj = Gst.parse_launch(self.desc)
except:
raise Something("Unable to create pipe object")
def play_pipeline(self):
ret = self.pipe_obj.set_state(Gst.State.PLAYING)
if ret == Gst.StateChangeReturn.FAILURE:
raise Something("Unable to play pipeline")
def signal_handler(self):
appsink = self.pipe_obj.get_by_name("appsink0")
appsink.connect("eos", self.signal_handler_callback, appsink)
def signal_handler_callback(self):
threading.Thread(target=self._counter_thread).start()
time.sleep(self.sleep)
def _counter_thread(self):
for i in range(1, self.sleep + 1):
time.sleep(1)
print (i)
gstreamer_instance = GStreamer()
gstreamer_instance.create_pipeline()
gstreamer_instance.play_pipeline()
print ("Started signal handler with timed out EOS to ", gstreamer_instance.sleep)
gstreamer_instance.signal_handler()
gstreamer_instance.signal_handler_callback()
Gst.init(None)
Где appsink
поддерживает события EOS Signal, вы можете проверить это с помощью gst-inspect-1.0 appsink
.
Вы можете обновить описание конвейера, чтобы оно соответствовало вашему, и выполнить некоторые манипуляции для записи в выходной файл, возможно, используя элемент AppSrc в новом экземпляре конвейера, чтобы он извлекал и сохранял буферы.
# Your first instance would be:
gst-launch-1.0 v4l2src device=/dev/video2 ! image/jpeg,width=1280, height=800, framerate=30/1 ! v4l2jpegdec ! queue ! v4l2h264enc extra-controls = "controls, h264_profile=4, video_bitrate=620000" ! 'video/x-h264, profile=high, level=(string)4' ! h264parse ! matroskamux ! appsink emit-signals=true
# Your receiver instance would be something similar to:
appsrc ! filesink location=output2.mkv
Надеюсь, вы получили представление о том, как управлять событиями в процессе конвейера GSt, используя сигналы элементов и этот пример.
РЕДАКТИРОВАТЬ
Подходит только для терминала.
Использование только консоли возможно путем отправки правильного сигнала в процесс.
Здесь у вас есть конвейерный процесс, например:
gst-launch-1.0 -e videotestsrc ! fakesink
Затем с другого терминала вы захотите отправить прерывание от стандартного сигнала клавиатуры, то есть: SIGINT
(эквивалент вашего текущего Ctrl + C) для вашего gst-launch-1.0
процесса.
kill -s SIGINT $(pidof gst-launch-1.0)
Это сделает работу. Попробуйте!
Но я не могу использовать python, только через командную консоль.
Взгляните на отредактированное решение, где вы можете узнать, как отправить EOS в конвейер GStreamer с помощью командной строки.
Да, вы правы, на моей стороне я убивал без сигнала прерывания, поэтому у меня это не сработало, спасибо.
Конечно, но одного аргумента в начале достаточно? Я думаю, что это вступает в силу, когда я говорю ему остановить процесс.