将 OpenCV 输出发送到 VLC 流
Sending OpenCV output to VLC stream
这让我忙了一个下午的大部分时间,我还没能开始工作,但我觉得我真的很接近了。
我已经设置了 openCV,它从网络摄像头获取视频源。为了能够访问此视频源(使用 openCV 覆盖),我想将 openCV python 脚本的输出通过管道传输到 VLC 流。我设法启动了流并 运行 并且可以连接到它。 VLC 调整到正确的纵横比和分辨率,因此它获得了一些正确的数据,但我得到的图像只是 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}" &
脚本的输出是发送到标准输出的恒定视频源,如下所示
from imutils.video import WebcamVideoStream
vs = WebcamVideoStream(src=0)
while True:
frame = vs.read()
sys.stdout.write(frame.tostring())
以上示例是我正在使用的脚本的简化版本;也如所见,我正在使用 imutils 库; https://github.com/jrosebr1/imutils
如果有人能给我一个正确方向的提示,我将不胜感激。我的猜测是 stdout.write(frame.tostring()) 不是 vlc 所期望的,但我自己还没弄明白。
虽然我发送到 RTSP 流并且没有使用 imutils 库,但这对我有用:
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()
然后在命令行中:
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}"
请注意,您不需要将 opencv BGR 转换为 RGB。
以下对我有用 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()
还有命令行(我的摄像头有不同的分辨率,我只显示结果,但你没有问题)
python opencv.py | vlc --demux=rawvideo --rawvid-fps=25 --rawvid-width=640 --rawvid-height=480 --rawvid-chroma=RV24 - --sout "#display"
当然这需要从 BGR 转换为 RGB,因为前者在 OpenCV 中是默认的。
这让我忙了一个下午的大部分时间,我还没能开始工作,但我觉得我真的很接近了。
我已经设置了 openCV,它从网络摄像头获取视频源。为了能够访问此视频源(使用 openCV 覆盖),我想将 openCV python 脚本的输出通过管道传输到 VLC 流。我设法启动了流并 运行 并且可以连接到它。 VLC 调整到正确的纵横比和分辨率,因此它获得了一些正确的数据,但我得到的图像只是 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}" &
脚本的输出是发送到标准输出的恒定视频源,如下所示
from imutils.video import WebcamVideoStream
vs = WebcamVideoStream(src=0)
while True:
frame = vs.read()
sys.stdout.write(frame.tostring())
以上示例是我正在使用的脚本的简化版本;也如所见,我正在使用 imutils 库; https://github.com/jrosebr1/imutils
如果有人能给我一个正确方向的提示,我将不胜感激。我的猜测是 stdout.write(frame.tostring()) 不是 vlc 所期望的,但我自己还没弄明白。
虽然我发送到 RTSP 流并且没有使用 imutils 库,但这对我有用:
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()
然后在命令行中:
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}"
请注意,您不需要将 opencv BGR 转换为 RGB。
以下对我有用 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()
还有命令行(我的摄像头有不同的分辨率,我只显示结果,但你没有问题)
python opencv.py | vlc --demux=rawvideo --rawvid-fps=25 --rawvid-width=640 --rawvid-height=480 --rawvid-chroma=RV24 - --sout "#display"
当然这需要从 BGR 转换为 RGB,因为前者在 OpenCV 中是默认的。