Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sending OpenCV output to VLC stream

Tags:

python

opencv

vlc

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.

like image 346
Nicky Romeijn Avatar asked Apr 12 '16 16:04

Nicky Romeijn


2 Answers

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.

like image 183
Atnas Avatar answered Nov 16 '22 07:11

Atnas


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.

like image 30
sbond Avatar answered Nov 16 '22 07:11

sbond