我有一个示例 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 事件。
这可能吗?如果是这样,有人做过吗?或者解决方案是什么?
你可以做一个处理 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)
就可以了。试一试!
来自
--help
的gst-launch-1.0
输出:
-e, --eos-on-shutdown Force EOS on sources before shutting the pipeline down
-e 在单个管道上为我工作,但如果我将视频分成两个流,则当我以
Ctrl-C
终止时,它不会生成 EOS 或创建输出文件
我将 watchdog timeout=1000
添加到管道并断开视频输入,然后看门狗终止流并生成 EOS,但我希望能够以另一种方式进行。
顺便说一句,我正在使用 Windows。
C:\gstreamer\1.0\x86_64\bin\gst-launch-1.0.exe rtspsrc location=rtsp://192.168.189.3:8554/bandwidth_h264 latency=0 ! decodebin ! watchdog timeout=1000 ! tee name=split split.! queue leaky=1 ! autovideosink sync=false split.! queue leaky=1 ! videoconvert ! x264enc ! mp4mux ! filesink location=c:/demo/test.mp4 -e