将图像帧写入 gstreamer rtp 管道
Write image frames into gstreamer rtp pipeline
我正在尝试使用 gstreamer 管道在我的计算机上查看 vlc 中的 rtp 流。我主要研究了这个 。我的最终结果是这样的
#!/usr/bin/env python
import gi
import numpy as np
gi.require_version('Gst', '1.0')
from gi.repository import Gst, GObject
import time
class RtpPipeline(object):
def __init__(self):
self.number_frames = 0
self.fps = 30
self.duration = 1 / self.fps * Gst.SECOND # duration of a frame in nanoseconds
self.launch_string = 'appsrc name=source ' \
'!videoconvert !x264enc speed-preset=ultrafast tune=zerolatency byte-stream=true ' \
'! mpegtsmux ! rtpmp2tpay ! udpsink host=127.0.0.1 port=5000'
pipeline = Gst.parse_launch(self.launch_string)
appsrc = pipeline.get_child_by_name('source')
while True:
try:
img = np.zeros([320, 320, 3], dtype=np.uint8)
img.fill(255) # white image
data = img.tostring()
buf = Gst.Buffer.new_allocate(None, len(data), None)
buf.fill(0, data)
buf.duration = self.duration
timestamp = self.number_frames * self.duration
buf.pts = buf.dts = int(timestamp)
buf.offset = timestamp
self.number_frames += 1
retval = appsrc.emit('push-buffer', buf)
if retval != Gst.FlowReturn.OK:
print(retval)
time.sleep(0.2)
except Exception as e:
break
Gst.init(None)
factory = RtpPipeline()
loop = GObject.MainLoop()
loop.run()
这不会引发错误,但不会在我的 vlc 客户端中显示任何内容。任何提示都会很棒(OpenCV VideoWriter 不是一个选项)。
图像帧需要解码(基于您从中读取图像文件的格式),然后转换为 RAW 格式(RGB/BGR/YUV 等),然后传递到 gstreamer 管道。
如果你用特定颜色填充图像缓冲区,而不是从任何图像文件中读取,你应该知道图像缓冲区的格式。
Gstreamer 管道还应该知道传递给它的是什么 RAW 格式以及什么分辨率和 fps 详细信息。
Python 脚本应该以 fps 中设置的相同帧速率推送图像文件。检查你的睡眠时间。
更改这些参数后检查,如果问题仍然存在 - 也添加 gstreamer 日志。
我认为最重要的遗漏是:
pipeline.set_state(Gst.State.PLAYING)
我还添加了来自 的评论。这是最终结果,虽然有点问题,但这是一个好的开始。
class RtpPipeline(object):
def __init__(self):
self.number_frames = 0
self.fps = 30
self.cap = cv2.VideoCapture(0)
self.duration = 1 / self.fps * Gst.SECOND # duration of a frame in nanoseconds
self.launch_string = 'appsrc name=source is-live=true format=GST_FORMAT_TIME ' \
' caps=video/x-raw,format=BGR,width=640,height=480,framerate=30/1 ' \
'! videoconvert ! video/x-raw,format=I420 ' \
'! x264enc speed-preset=ultrafast tune=zerolatency byte-stream=true ' \
'! mpegtsmux ! rtpmp2tpay ! udpsink host=127.0.0.1 port=5000 sync=false'
pipeline = Gst.parse_launch(self.launch_string)
appsrc = pipeline.get_child_by_name('source')
pipeline.set_state(Gst.State.PLAYING)
while True:
try:
ret, frame = self.cap.read()
start = time.time()
data = frame.tostring()
buf = Gst.Buffer.new_allocate(None, len(data), None)
buf.fill(0, data)
buf.duration = self.duration
timestamp = self.number_frames * self.duration
buf.pts = buf.dts = int(timestamp)
buf.offset = timestamp
self.number_frames += 1
retval = appsrc.emit('push-buffer', buf)
if retval != Gst.FlowReturn.OK:
print(retval)
except Exception as e:
break
我正在尝试使用 gstreamer 管道在我的计算机上查看 vlc 中的 rtp 流。我主要研究了这个
#!/usr/bin/env python
import gi
import numpy as np
gi.require_version('Gst', '1.0')
from gi.repository import Gst, GObject
import time
class RtpPipeline(object):
def __init__(self):
self.number_frames = 0
self.fps = 30
self.duration = 1 / self.fps * Gst.SECOND # duration of a frame in nanoseconds
self.launch_string = 'appsrc name=source ' \
'!videoconvert !x264enc speed-preset=ultrafast tune=zerolatency byte-stream=true ' \
'! mpegtsmux ! rtpmp2tpay ! udpsink host=127.0.0.1 port=5000'
pipeline = Gst.parse_launch(self.launch_string)
appsrc = pipeline.get_child_by_name('source')
while True:
try:
img = np.zeros([320, 320, 3], dtype=np.uint8)
img.fill(255) # white image
data = img.tostring()
buf = Gst.Buffer.new_allocate(None, len(data), None)
buf.fill(0, data)
buf.duration = self.duration
timestamp = self.number_frames * self.duration
buf.pts = buf.dts = int(timestamp)
buf.offset = timestamp
self.number_frames += 1
retval = appsrc.emit('push-buffer', buf)
if retval != Gst.FlowReturn.OK:
print(retval)
time.sleep(0.2)
except Exception as e:
break
Gst.init(None)
factory = RtpPipeline()
loop = GObject.MainLoop()
loop.run()
这不会引发错误,但不会在我的 vlc 客户端中显示任何内容。任何提示都会很棒(OpenCV VideoWriter 不是一个选项)。
图像帧需要解码(基于您从中读取图像文件的格式),然后转换为 RAW 格式(RGB/BGR/YUV 等),然后传递到 gstreamer 管道。
如果你用特定颜色填充图像缓冲区,而不是从任何图像文件中读取,你应该知道图像缓冲区的格式。
Gstreamer 管道还应该知道传递给它的是什么 RAW 格式以及什么分辨率和 fps 详细信息。
Python 脚本应该以 fps 中设置的相同帧速率推送图像文件。检查你的睡眠时间。
更改这些参数后检查,如果问题仍然存在 - 也添加 gstreamer 日志。
我认为最重要的遗漏是:
pipeline.set_state(Gst.State.PLAYING)
我还添加了来自
class RtpPipeline(object):
def __init__(self):
self.number_frames = 0
self.fps = 30
self.cap = cv2.VideoCapture(0)
self.duration = 1 / self.fps * Gst.SECOND # duration of a frame in nanoseconds
self.launch_string = 'appsrc name=source is-live=true format=GST_FORMAT_TIME ' \
' caps=video/x-raw,format=BGR,width=640,height=480,framerate=30/1 ' \
'! videoconvert ! video/x-raw,format=I420 ' \
'! x264enc speed-preset=ultrafast tune=zerolatency byte-stream=true ' \
'! mpegtsmux ! rtpmp2tpay ! udpsink host=127.0.0.1 port=5000 sync=false'
pipeline = Gst.parse_launch(self.launch_string)
appsrc = pipeline.get_child_by_name('source')
pipeline.set_state(Gst.State.PLAYING)
while True:
try:
ret, frame = self.cap.read()
start = time.time()
data = frame.tostring()
buf = Gst.Buffer.new_allocate(None, len(data), None)
buf.fill(0, data)
buf.duration = self.duration
timestamp = self.number_frames * self.duration
buf.pts = buf.dts = int(timestamp)
buf.offset = timestamp
self.number_frames += 1
retval = appsrc.emit('push-buffer', buf)
if retval != Gst.FlowReturn.OK:
print(retval)
except Exception as e:
break