Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Python: Play UDP video streaming while sending keep alive messages

have a program which connects with a camera via socket. This camera starts to livestream video when I send a message throught this socket, and continues while I send keep alive messages. The video is transmitted via UDP as mpeg-ts packets. I'm trying to play the video with OpenCV but I'm having

[udp @ 0x10d07e0] bind failed: Address  already in use

error in execution. Here is my code (ip4 and LIVEPORT are constants):

dataLive = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
td = threading.Timer(0, send_keepalive_msg, [dataLive, KA_DATA_MSG, (ip4,LIVEPORT)])
td.start()

videoLive = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
tl = threading.Timer(0, send_keepalive_msg, [videoLive, KA_VIDEO_MSG, (ip4, LIVEPORT)])
tl.start()

videourl = "udp://@{0}:{1}/".format(ip4, LIVEPORT)
cap = cv2.VideoCapture(videourl)

while cap.isOpened():
    ret, frame = cap.read()
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    cv2.imshow("frame", gray)
    if cv2.waitKey(30) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

This code is a evolution from previous one using Gstreamer, which works well:

PIPELINE_DEF = "udpsrc do-timestamp=true name=src closefd=false !" \
               "mpegtsdemux !" \
               "queue !" \
               "ffdec_h264 max-threads=0 !" \
               "ffmpegcolorspace !" \
               "xvimagesink name=video"

dataLive = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
td = threading.Timer(0, send_keepalive_msg, [dataLive, KA_DATA_MSG, (ip4,LIVEPORT)])
td.start()

videoLive = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
tl = threading.Timer(0, send_keepalive_msg, [videoLive, KA_VIDEO_MSG, (ip4, LIVEPORT)])
tl.start()

# Create gstreamer pipeline to stream video
pipeline = gst.parse_launch(PIPELINE_DEF)

# Source element: video socket. Sockfd file for UDP reception. socket.fileno() returns socket descriptor
src = pipeline.get_by_name("src")
src.set_property("sockfd", videoLive.fileno())

pipeline.set_state(gst.STATE_PLAYING)

while True:
    state_change_return, state, pending_state = pipeline.get_state(0)
    if gst.STATE_CHANGE_FAILURE == state_change_return:
        break

send_keep_alive function is not important, but here is the code:

def send_keepalive_msg(socket, msg, peer):
    while True:
        socket.sendto(msg, peer)
        time.sleep(timeout)

How can I bind correctly the opencv CaptureVideo with the socket? Thanks in advance!