Мне нужно написать простое приложение, захватывающее кадры с веб-камеры и вставляющее их в конвейер appsr c gstreamer для потоковой передачи их по сети. В качестве отправной точки я использовал этот пример . У меня есть работающие конвейеры на стороне сервера и клиента:
gst-launch-1.0 -v v4l2src device="/dev/video0" ! videoconvert ! videoscale ! video/x-raw,width=640,height=480 ! avenc_mpeg4 ! rtpmp4vpay config-interval=3 ! udpsink host=127.0.0.1 port=5200
gst-launch-1.0 -v udpsrc port=5200 caps = "application/x-rtp\,\ media\=\(string\)video\,\ clock-rate\=\(int\)90000\,\ encoding-name\=\(string\)MP4V-ES\,\ profile-level-id\=\(string\)1\,\ config\=\(string\)000001b001000001b58913000001000000012000c48d8800cd3204709443000001b24c61766335362e312e30\,\ payload\=\(int\)96\,\ ssrc\=\(uint\)2873740600\,\ timestamp-offset\=\(uint\)391825150\,\ seqnum-offset\=\(uint\)2980" ! rtpmp4vdepay ! avdec_mpeg4 ! autovideosink
Поэтому я попытался встроить конвейер TX в свое приложение:
import time
import cv2
# Cam properties
fps = 1.
frame_width = 640
frame_height = 480
# Create capture
#cap = cv2.VideoCapture(0)
cap = cv2.VideoCapture("/dev/video0")
# Set camera properties
cap.set(cv2.CAP_PROP_FRAME_WIDTH, frame_width)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, frame_height)
cap.set(cv2.CAP_PROP_FPS, fps)
# Define the gstreamer sink
gst_str_rtp = "appsrc ! videoconvert ! videoscale ! video/x-raw,width=640,height=480 ! avenc_mpeg4 ! rtpmp4vpay config-interval=3 ! udpsink host=127.0.0.1 port=5200"
# Check if cap is open
if cap.isOpened() is not True:
print ("Cannot open camera. Exiting.")
quit()
# Create videowriter as a SHM sink
out = cv2.VideoWriter(gst_str_rtp, 0, fps, (frame_width, frame_height), True)
frame_counter = 0
# Loop it
while True:
# Get the frame
ret, frame = cap.read()
print("frame # = " + str(frame_counter))
frame_counter = frame_counter + 1
# Check
if ret is True:
# Flip frame
#frame = cv2.flip(frame, 1)
#cv2.imshow("Frame", frame)
# Our operations on the frame come here
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# Display the resulting frame
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# Write to SHM
out.write(frame)
else:
print ("Camera error.")
time.sleep(10)
cap.release()
Кадр отображается правильно, поэтому ОК с веб-камерой все в порядке.
Проблема в том, что кажется, что конвейер gstreamer вообще не запускается. Несмотря на то, что у меня GST_DEBUG = 9, я не вижу сообщений от streamer на стороне TX:
sysadmin@nuc6-0:~/devel/hfr-camera/python-opencv-gstreamer-examples$ python3 gst_device_to_rtp.py
frame # = 0
frame # = 1
...
На стороне клиента получатель ожидает кадры бесконечно:
$ gst-launch-1.0 -v udpsrc port=5200 caps = "application/x-rtp\,\ media\=\(string\)video\,\ clock-rate\=\(int\)90000\,\ encoding-name\=\(string\)MP4V-ES\,\ profile-level-id\=\(string\)1\,\ config\=\(string\)000001b001000001b58913000001000000012000c48d8800cd3204709443000001b24c61766335362e312e30\,\ payload\=\(int\)96\,\ ssrc\=\(uint\)2873740600\,\ timestamp-offset\=\(uint\)391825150\,\ seqnum-offset\=\(uint\)2980" ! rtpmp4vdepay ! avdec_mpeg4 ! autovideosink
Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Got context from element 'autovideosink0-actual-sink-vaapi': gst.vaapi.Display=context, gst.vaapi.Display=(GstVaapiDisplay)"\(GstVaapiDisplayGLX\)\ vaapidisplayglx1";
/GstPipeline:pipeline0/GstUDPSrc:udpsrc0.GstPad:src: caps = application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)MP4V-ES, profile-level-id=(string)1, config=(string)000001b001000001b58913000001000000012000c48d8800cd3204709443000001b24c61766335362e312e30, payload=(int)96, ssrc=(uint)2873740600, timestamp-offset=(uint)391825150, seqnum-offset=(uint)2980
/GstPipeline:pipeline0/GstRtpMP4VDepay:rtpmp4vdepay0.GstPad:src: caps = video/mpeg, mpegversion=(int)4, systemstream=(boolean)false, codec_data=(buffer)000001b001000001b58913000001000000012000c48d8800cd3204709443000001b24c61766335362e312e30
Setting pipeline to PLAYING ...
/GstPipeline:pipeline0/avdec_mpeg4:avdec_mpeg4-0.GstPad:sink: caps = video/mpeg, mpegversion=(int)4, systemstream=(boolean)false, codec_data=(buffer)000001b001000001b58913000001000000012000c48d8800cd3204709443000001b24c61766335362e312e30
New clock: GstSystemClock
/GstPipeline:pipeline0/GstRtpMP4VDepay:rtpmp4vdepay0.GstPad:sink: caps = application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)MP4V-ES, profile-level-id=(string)1, config=(string)000001b001000001b58913000001000000012000c48d8800cd3204709443000001b24c61766335362e312e30, payload=(int)96, ssrc=(uint)2873740600, timestamp-offset=(uint)391825150, seqnum-offset=(uint)2980
Я использую следующие версии:
$ gst-launch-1.0 --version
gst-launch-1.0 version 1.14.5
GStreamer 1.14.5
https://launchpad.net/distros/ubuntu/+source/gstreamer1.0
$ python3 -c "import cv2; print(cv2.__version__)"
4.2.0
Мой хост - это P C под управлением Ubuntu 18.04.
Любая помощь будет очень признательна.