Hello,
I want to read a frame with opencv and stream this frame with UDP(H264). I want to read the frame first because I will be processing the image later. My code;
import cv2
import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst, GLib
class UDPStreamer:
def __init__(self):
Gst.init(None)
self.pipeline = Gst.parse_launch((
"appsrc name=source is-live=true block=true format=GST_FORMAT_TIME "
"caps=video/x-raw,format=I420,width=1280,height=1024,framerate=50/1 ! "
"videoconvert ! x264enc tune=zerolatency bitrate=5000 speed-preset=ultrafast ! "
"rtph264pay ! udpsink host=192.168.1.48 port=5000"
))
self.source = self.pipeline.get_by_name("source")
self.frame_number = 0
def start(self):
self.pipeline.set_state(Gst.State.PLAYING)
print("UDP streaming to udp://192.168.1.48:5000")
def stop(self):
self.pipeline.set_state(Gst.State.NULL)
def main():
cap = cv2.VideoCapture(0, cv2.CAP_V4L2)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1024)
cap.set(cv2.CAP_PROP_FPS, 50)
cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*"YUYV"))
streamer = UDPStreamer()
streamer.start()
try:
while True:
ret, frame = cap.read()
if not ret:
print("Error: Unable to read frame from the camera.")
break
#Send frame to GStreamer appsrc
if streamer.source:
frame_i420 = cv2.cvtColor(frame, cv2.COLOR_BGR2YUV_I420)
data = frame_i420.tobytes()
buf = Gst.Buffer.new_allocate(None, len(data), None)
buf.fill(0, data)
buf.pts = Gst.util_uint64_scale(streamer.frame_number, Gst.SECOND, 50)
buf.duration = Gst.util_uint64_scale(1, Gst.SECOND, 50)
streamer.frame_number += 1
retval = streamer.source.emit("push-buffer", buf)
if retval != Gst.FlowReturn.OK:
print("Error: Unable to push buffer to the pipeline.")
cv2.imshow("Camera Feed", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
finally:
cap.release()
cv2.destroyAllWindows()
streamer.stop()
if __name__ == "__main__":
main()
I can’t watch frames with VLC Player on the host computer. My host computer’s IP Address: 192.168.1.48. I tried udp://192.168.1.48:5000 and udp://@:5000 but I can’t get any image. Then I created a .slp file and added the following lines to it;
v=0
c=IN IP4 192.168.1.48
m=video 5000 RTP/AVP 96
a=rtpmap:96 H264/90000
When I click “Open File” in VLC Player, select the “.slp” file, and press play, I can get images, but there is a lot of lag. Instead of “Open File” in VLC, I want to select “Open Network Stream” and enter the IP address to watch the images. What could I be doing wrong?
The features of my camera are as follows;
In addition to all this, the RTSP code below works without any problems, but I could not run UDP.
import cv2
import gi
gi.require_version('Gst', '1.0')
gi.require_version('GstRtspServer', '1.0')
from gi.repository import Gst, GstRtspServer, GLib
class RTSPServer:
def __init__(self):
Gst.init(None)
Gst.debug_set_default_threshold(3)
self.server = GstRtspServer.RTSPServer()
self.factory = GstRtspServer.RTSPMediaFactory()
self.factory.set_launch((
"appsrc name=source is-live=true block=true format=GST_FORMAT_TIME "
"caps=video/x-raw,format=I420,width=1280,height=1024,framerate=50/1 ! "
"videoconvert ! x264enc tune=zerolatency bitrate=5000 speed-preset=ultrafast ! "
"rtph264pay name=pay0 pt=96"
))
self.factory.set_shared(True)
self.server.get_mount_points().add_factory("/test", self.factory)
self.server.set_service("8554")
self.source = None
self.frame_number = 0
def start(self):
self.server.attach(None)
print("RTSP server running at rtsp://<your-ip>:8554/test")
def configure_pipeline(self, factory, media):
self.source = media.get_element().get_child_by_name("source")
def main():
cap = cv2.VideoCapture(0, cv2.CAP_V4L2)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1024)
cap.set(cv2.CAP_PROP_FPS, 50)
cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*"YUYV"))
server = RTSPServer()
server.factory.connect("media-configure", server.configure_pipeline)
server.start()
while True:
ret, frame = cap.read()
if not ret:
print("Error: Unable to read frame from the camera.")
break
#Send frames to GStreamer appsrc
if server.source:
frame_i420 = cv2.cvtColor(frame, cv2.COLOR_BGR2YUV_I420)
data = frame_i420.tobytes()
buf = Gst.Buffer.new_allocate(None, len(data), None)
buf.fill(0, data)
buf.pts = Gst.util_uint64_scale(server.frame_number, Gst.SECOND, 50)
buf.duration = Gst.util_uint64_scale(1, Gst.SECOND, 50)
server.frame_number += 1
server.source.emit("push-buffer", buf)
cv2.imshow("Camera Feed", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
main()
I can open the RTSP stream from VLC Player by typing the address “rtsp://my-ip:8554/test”. I want the same for UDP. Can you help me?