KPNT
KPNT

Reputation: 453

Sending OpenCV output to VLC stream

This has been keeping me busy for a good part of the afternoon and I haven't been able to get it to work but I feel like I'm really close.

I've got openCV set up which takes the videofeed from a webcam. To be able to access this video feed (with openCV overlay) I want to pipe the output of the openCV python script to a VLC stream. I managed to get the stream up and running and can connect to it. VLC resizes to the correct aspect ratio and resolution so it gets some correct data but the image I get is just Jitter;

python opencv.py | cvlc --demux=rawvideo --rawvid-fps=30 --rawvid-width=320 --rawvid-height=240  --rawvid-chroma=RV24 - --sout "#transcode{vcodec=h264,vb=200,fps=30,width=320,height=240}:std{access=http{mime=video/x-flv},mux=ffmpeg{mux=flv},dst=:8081/stream.flv}" &

The output of the script is a constant video feed sent to stdout as follows

from imutils.video import WebcamVideoStream

vs = WebcamVideoStream(src=0)

while True: 
  frame = vs.read()
  sys.stdout.write(frame.tostring())

Above example is a dumbed down version of the script I'm using; Also as seen I'm making use of the imutils library; https://github.com/jrosebr1/imutils

If anyone could give me a nudge in the right direction I would appreciate it greatly. My guess is the stdout.write(frame.tostring()) is not what vlc expects but I haven't been able to figure it out myself.

Upvotes: 15

Views: 14136

Answers (2)

Atnas
Atnas

Reputation: 613

The following works for me under Python 3

import numpy as np
import sys
import cv2

cap = cv2.VideoCapture(0)

while(cap.isOpened()):
    ret, frame = cap.read()
    if ret==True:        
        sys.stdout.buffer.write(frame.tobytes())
    else:
        break

cap.release()

And the command line (my webcam has a different resolution, and I only display the result, but you did not have problems with that)

python opencv.py | vlc --demux=rawvideo --rawvid-fps=25 --rawvid-width=640 --rawvid-height=480 --rawvid-chroma=RV24 - --sout "#display" 

Of course this requires a conversion from BGR to RGB as the former is default in OpenCV.

Upvotes: 4

sbond
sbond

Reputation: 178

This worked for me, though I am sending to RTSP stream and not using imutils library:

import numpy as np
import sys
import cv2

input_rtsp = "rtsp://10.10.10.9:8080"
cap = cv2.VideoCapture(input_rtsp)

while(cap.isOpened()):
    ret, frame = cap.read()
    if ret==True:        
        sys.stdout.write(frame.tostring())
    else:
        break

cap.release()

Then in command line:

python opencv.py | cvlc --demux=rawvideo --rawvid-fps=25 --rawvid-width=1280 --rawvid-height=720  --rawvid-chroma=RV24 - --sout "#transcode{vcodec=h264,vb=200,fps=25,width=1280,height=720}:rtp{dst=10.10.10.10,port=8081,sdp=rtsp://10.10.10.10:8081/test.sdp}"

Note that you do not need to convert opencv BGR to RGB.

Upvotes: 2

Related Questions