目前RTSP拉流是网络摄像头获取图片数据常用的方法,但通过CPU软解码的方式不仅延时高且十分占用资源,本文提供了一种从网络摄像头RTSP硬解码的拉流的方法,并且提供python代码以便从网络摄像头获取图片进行后续算法处理。
Ffmpeg下载链接。建议下载稳定版本。
图1
这里会出现三个版本:
- essentials:必要的组件,东西可能不全。
- full:全面的,里面的库文件比较全。
- shared:有动态链接库。
通过版本号命名的为稳定版,日期命名的为最新版。仅是使用的话essentials即可,Qt等调库需要选择shared。
图2
图3
复制如图所示的bin文件地址,设置环境变量。
右击此电脑打开属性
图4
图5
图6
图7
按照图4~7将复制的bin文件环境变量路径添加进去。
运行命令
ffmpeg -version
显示以上信息则安装完成。
ffplay rtsp://XXXXXXX/stream
使用ffplay即可拉流成功,但是为软解码,拉流延时较高。
首先查看支持的硬件
ffmpeg -hwaccels
如果是nvidia的显卡并安装的对应驱动,也安装了cuda,则可以使用cuda跟h_264cuvid 解码器
查看可用的对应格式解码器
ffmpeg -codecs | findstr "h264"
红色框中为可用解码器。
利用硬件解码器的命令如下,以h264_cuvid为例:
ffmpeg -hwaccel cuda -vcodec h264_cuvid -i rtsp://admin:qwer1234@192.0.0.64/h264/ch1/main/av_stream output.mp4
-hwaccel 选择硬件模式
-vcodec 选择解码器
-i RTSP地址
output.mp4 保存成.mp4视频
note:硬解码器必须与硬件环境对应如:cuda 对应 h264_cuvid
测量延时方法
- 将网络摄像头对准手机计时器
- 把手机靠近播放视频的电脑屏幕
- 同时拍摄手机与电脑屏幕显示的计时器,可计算毫秒级延时 。
具体如下面的图片所示。
延时时间:7580 – 6130 = 1450ms
此时采用CPU软解,故延时较高。
延时时间:3390 – 2680 = 710ms
可见硬解码降低了RTSP延时。
查看任务管理器的GPU界面栏
双击红色区域放大GPU显示
当Video Decode出现波动时代表调用了硬件解码器。
首先安装ffmpeg-python、opencv-python、Numpy
- pip install ffmpeg-python
-
- pip install opencv-python
-
- pip install numpy
此时还需要环境中安装了Cuda。
Cuda安装网络资源很多,在此不做赘述。
Code
- import cv2
- import ffmpeg
- import numpy as np
-
- # RTSP 流地址
- rtsp_url = "rtsp://admin:qwer1234@192.0.0.64/h264/ch1/main/av_stream"
-
- # 创建 FFmpeg 进程
- probe = ffmpeg.probe(rtsp_url)
- video_info = next(stream for stream in probe['streams'] if stream['codec_type'] == 'video')
- width = video_info['width']
- height = video_info['height']
-
-
- ffmpeg_cmd = (
- ffmpeg
- .input(rtsp_url, hwaccel='cuda', vcodec='h264_cuvid')
- .output('pipe:', format='rawvideo',pix_fmt='bgr24')
- .run_async(pipe_stdout=True)
- )
-
- # 读取并显示视频帧
- while True:
- in_bytes = ffmpeg_cmd.stdout.read(width * height * 3)
- if not in_bytes:
- break
- frame = (
- np
- .frombuffer(in_bytes, np.uint8)
- .reshape([height, width, 3])
- )
- cv2.imshow('RTSP Stream (GPU)', frame)
- if cv2.waitKey(1) & 0xFF == ord('q'):
- break
-
- ffmpeg_cmd.wait()
- cv2.destroyAllWindows()
上述Code即可通过python调用ffmpeg并且能够与opencv交互,能为后续开发图像算法做一个前端。