发现并采集 ONVIF 网络摄像头视频流,核心流程是:确认设备网络地址和 ONVIF 服务端口,调用设备与媒体服务获取 Profile Token,再通过 GetStreamUri 取得 RTSP 地址,最后使用 FFprobe、VLC 或 FFmpeg 验证并录制。以下步骤适用于已获得管理权限或明确授权的局域网摄像头、编码器和部分 NVR;不要扫描或采集无权访问的设备。

一、ONVIF 视频流发现与采集的基本原理
1. ONVIF 负责什么
ONVIF 是网络视频设备的互操作规范。客户端通常通过 SOAP Web Service 查询设备信息、网络配置、媒体编码参数和视频流地址。它本身通常不承载视频内容,实际音视频大多通过 RTSP/RTP 传输。
2. 一次完整调用包含哪些环节
- 通过 DHCP 租约、厂商工具或 WS-Discovery 找到摄像头。
- 连接设备服务地址,例如
http://192.168.1.20:80/onvif/device_service。 - 调用
GetCapabilities获取媒体服务地址。 - 调用
GetProfiles枚举主码流、子码流及对应的 Profile Token。 - 调用
GetStreamUri获取指定配置的 RTSP URI。 - 用 RTSP 客户端拉流,并按截图、连续录像或分段归档等方式采集。
二、采集前准备
1. 网络与权限
- 让采集机与摄像头处于可路由网络中,并确认交换机、VLAN 和防火墙策略允许访问。
- 准备具有实时预览权限的摄像头账号。部分设备需要在管理页面单独启用 ONVIF,并创建 ONVIF 用户。
- 确认设备时间、时区和 NTP 设置。时间偏差过大可能导致 WS-Security 鉴权失败。
- 记录摄像头 IP、ONVIF 端口、RTSP 端口及账号权限,不要默认所有设备都使用 80 和 554。
2. 推荐工具
- ONVIF Device Manager:适合在 Windows 中发现设备、查看 Profiles 和测试实时视频。
- VLC:适合快速判断 RTSP 地址能否播放。
- FFmpeg 与 FFprobe:适合检测编码参数、截图、录像和自动化采集。
- Python 3 与
onvif-zeep:适合批量获取设备信息和 RTSP URI。
三、步骤一:发现摄像头 IP 和 ONVIF 服务
方法 A:查询 DHCP 租约
登录路由器、DHCP 服务器或网络控制器,根据摄像头标签上的 MAC 地址查找当前 IP。这种方式对跨 VLAN 环境更可靠,因为 WS-Discovery 的组播报文通常不会经过路由器。

方法 B:使用 ONVIF Device Manager
- 在与摄像头相同的二层网络中启动工具。
- 等待设备列表刷新,按 IP、厂商或型号识别目标设备。
- 输入 ONVIF 用户名和密码。
- 检查 Identification、Network Settings、Profiles 和 Live Video 页面。
- 记录设备服务地址、媒体服务地址、Profile 名称及视频编码格式。
方法 C:使用 WS-Discovery
ONVIF 发现通常使用 UDP 3702 和组播地址 239.255.255.250。发现失败不等于 ONVIF 不可用:无线客户端隔离、容器网络、VPN、VLAN、组播过滤和主机防火墙都可能阻断探测报文。此时应直接使用已知 IP 连接设备服务。
四、步骤二:验证 ONVIF 接口与设备能力
在管理页面启用 ONVIF 后,先验证设备服务是否可达。可以用浏览器或 HTTP 工具访问设备服务 URL;返回 400、401、405 或 SOAP 错误,通常仍说明端口和 HTTP 服务可达。连接超时或拒绝连接则需要继续检查端口、防火墙和设备配置。
随后依次检查以下接口:
GetDeviceInformation:确认制造商、型号、固件版本和序列号。GetSystemDateAndTime:检查设备时间,定位鉴权时间戳问题。GetCapabilities:获取 Media、Events、PTZ 等服务地址。GetProfiles:获取媒体配置及 Profile Token。GetVideoEncoderConfigurations:核对分辨率、帧率、码率以及 H.264、H.265 或 JPEG 编码。
不要自行拼接媒体服务路径。不同固件可能使用不同的 XAddr,应以 GetCapabilities 的返回值为准。
五、步骤三:获取 RTSP 视频流地址
1. 选择主码流或子码流
主码流通常具有更高分辨率和码率,适合录像、视觉分析和数据留存;子码流带宽和解码成本较低,适合预览、设备健康检查及大规模并发接入。应根据 Profile 中的编码参数选择,而不是仅依赖 Profile 名称。
2. 调用 GetStreamUri
调用时需要指定目标 Profile Token,并将传输方式设置为 RTP-Unicast。优先请求 RTSP 传输;部分客户端还能选择 RTP over TCP,以改善存在丢包或 UDP 受限时的稳定性。
典型返回地址类似:
rtsp://192.168.1.20:554/Streaming/Channels/101设备可能返回不含账号密码的地址,这是正常情况。账号应由客户端单独提交,或在临时测试时放入 URI。若密码包含 @、:、/、# 等字符,需要进行 URL 编码。生产环境不要把含明文凭据的 URI 写入日志、命令历史或任务名称。
六、步骤四:验证视频流
1. 使用 VLC 人工验证
- 打开 VLC 的“打开网络串流”。
- 输入 GetStreamUri 返回的 RTSP 地址。
- 按提示输入摄像头账号和密码。
- 观察首帧耗时、画面连续性、时间戳以及音频是否存在。
2. 使用 FFprobe 检查编码参数
export RTSP_URL='rtsp://user:password@192.168.1.20:554/Streaming/Channels/101'
ffprobe -v error -rtsp_transport tcp -show_streams -show_format -of json "$RTSP_URL"重点检查返回结果中的 codec_name、width、height、avg_frame_rate 和音频流。命令能够读取到视频流信息,说明地址、权限、RTSP 协商和基础解码链路基本正常。
3. 截取一帧作为证据
ffmpeg -rtsp_transport tcp -i "$RTSP_URL" -frames:v 1 -q:v 2 snapshot.jpg打开生成的图片,检查是否为目标机位、是否存在花屏、颜色异常或隐私遮挡配置错误。只看到 FFprobe 参数而没有实际图像,不足以证明采集结果可用。
七、步骤五:使用 FFmpeg 采集视频
1. 录制 60 秒测试文件
ffmpeg -rtsp_transport tcp -i "$RTSP_URL" -t 60 -map 0:v:0 -map 0:a? -c copy test.mkv-c copy 不重新编码,CPU 占用较低,也不会引入二次压缩。MKV 对 H.264、H.265、AAC 及异常结束的容忍度通常更适合初始验证。完成后再次使用 FFprobe 检查文件时长和流信息,并完整播放首、中、尾三个位置。
2. 按五分钟分段采集
ffmpeg -rtsp_transport tcp -i "$RTSP_URL" -map 0:v:0 -map 0:a? -c copy -f segment -segment_time 300 -reset_timestamps 1 -strftime 1 'capture-%Y%m%d-%H%M%S.mkv'分段文件便于上传、重试、保留周期管理和故障隔离。由于无转码分段通常依赖关键帧,实际文件时长可能不会精确等于 300 秒。如果业务要求精确切片,需要控制摄像头 GOP,或转码并强制关键帧。
3. 需要统一编码时转码
ffmpeg -rtsp_transport tcp -i "$RTSP_URL" -t 60 -an -c:v libx264 -preset veryfast -crf 23 -pix_fmt yuv420p normalized.mp4只有在下游不兼容原始编码、需要统一分辨率或需要叠加脱敏处理时再转码。转码会增加 CPU 或 GPU 成本,并改变原始画质,不应作为默认方案。
八、步骤六:使用 Python 自动获取流地址
1. 安装依赖
python -m pip install onvif-zeep2. 枚举 Profiles 并调用 GetStreamUri
from onvif import ONVIFCamera
host = '192.168.1.20'
port = 80
username = 'onvif_user'
password = 'replace_me'
camera = ONVIFCamera(host, port, username, password)
media = camera.create_media_service()
profiles = media.GetProfiles()
for profile in profiles:
request = media.create_type('GetStreamUri')
request.ProfileToken = profile.token
request.StreamSetup = {
'Stream': 'RTP-Unicast',
'Transport': {'Protocol': 'RTSP'},
}
result = media.GetStreamUri(request)
encoder = getattr(profile, 'VideoEncoderConfiguration', None)
resolution = getattr(encoder, 'Resolution', None)
print(profile.Name, profile.token, resolution, result.Uri)不同设备和 ONVIF 版本返回的字段可能存在差异,批量程序应处理空字段、SOAP Fault、连接超时和单个 Profile 不可用等情况。不要在输出中打印密码,也不要把凭据写死在代码仓库中;可使用环境变量或密钥管理服务。
九、注意事项与故障排查
发现不到设备
- 确认采集机与设备位于相同二层网络,网卡选择正确。
- 检查 UDP 3702、组播过滤、无线客户端隔离和主机防火墙。
- 改用 DHCP 租约或厂商管理工具查找 IP,再直接连接 ONVIF 服务。
- 确认管理页面已经启用 ONVIF,而不仅是启用了 RTSP。
ONVIF 登录失败但网页能登录
- 部分设备要求单独创建 ONVIF 用户,网页管理员账号不一定可直接使用。
- 同步设备与客户端时间,检查时区和 NTP。
- 确认用户具有媒体配置读取和实时预览权限。
- 检查设备支持的认证方式以及客户端兼容性,必要时升级到厂商提供的稳定固件。
能够获取 URI 但无法播放
- 测试摄像头的实际 RTSP 端口,并检查 TCP 防火墙策略。
- 分别测试 TCP 和 UDP 传输;跨网段或存在丢包时优先尝试 TCP。
- 检查地址中返回的内网主机名或错误 IP,必要时在确认路径不变后替换为设备实际可达 IP。
- 确认并发连接数限制,关闭残留播放器或采集进程。
- 尝试子码流,排除客户端不支持 H.265、高分辨率或高码率的问题。
画面卡顿或录像损坏
- 比较摄像头码率总和与交换机、上联链路及采集机网卡容量。
- 观察丢包、RTSP 重连次数、帧率和时间戳是否连续。
- 使用分段文件降低异常退出造成的损失,并为磁盘容量设置告警和保留策略。
- 让摄像头和采集机使用同一可靠 NTP 源,避免多机位时间线错位。
- 对长期任务增加进程守护、指数退避重连、健康检查和失败文件隔离。
十、选型建议
少量局域网摄像头验证可使用 ONVIF 客户端、FFmpeg 和脚本完成;多路长期录像通常还需要 VMS、NVR 或具备设备状态、权限、存储和告警能力的采集服务。若任务进一步涉及公开网页、视频平台数据、训练数据集或跨地区网络资源,可将 Dataify 的视频数据 API、通用采集 API、多模态数据集与网络服务作为外围数据获取方案评估,但它们不替代摄像头侧的 ONVIF 接入和授权管理。
十一、验证与验收方法
- 发现验证:设备 IP、型号、序列号和 ONVIF 服务地址与资产清单一致。
- 权限验证:专用低权限账号能够读取 Profiles 和拉取实时流,但不能执行不必要的管理操作。
- 参数验证:实际分辨率、帧率、编码格式和码率符合预期。
- 内容验证:截图确认机位正确、画面清晰,隐私遮挡和时间叠加符合要求。
- 稳定性验证:连续采集至少 30 至 60 分钟,统计重连、丢帧、文件损坏和时间戳跳变。
- 资源验证:记录单路及总 CPU、内存、磁盘写入和网络带宽,为扩容预留余量。
- 恢复验证:模拟摄像头重启、网络中断和密码变更,确认任务能够告警并按策略恢复。
常见问题
ONVIF 地址和 RTSP 地址有什么区别?
ONVIF 地址用于发现设备、查询能力和取得媒体配置;RTSP 地址用于传输实际音视频。常见流程是通过 ONVIF 的 GetStreamUri 获取 RTSP URI,再使用 VLC、FFmpeg 或其他客户端拉流。
为什么 GetStreamUri 成功,拉流时仍返回 401?
ONVIF 查询与 RTSP 拉流可能分别鉴权。需要确认账号具有实时预览权限、用户名和密码正确、特殊字符已经 URL 编码,并检查设备是否要求单独创建 ONVIF 用户。
RTSP 采集应该使用 TCP 还是 UDP?
网络稳定且重视低延迟时可以测试 UDP;跨网段、存在丢包或防火墙限制时通常优先测试 TCP。应通过持续采集的丢帧、延迟和重连数据确定最终方案。
主码流和子码流应该怎样选择?
主码流适合录像、视觉分析和高质量留存,子码流适合预览、健康检查及高并发接入。选择时应核对实际分辨率、帧率、编码格式和码率,而不是只看 Profile 名称。
如何判断采集链路已经达到上线条件?
除成功播放外,还应连续采集至少 30 至 60 分钟,并验证截图内容、音视频参数、时间戳、文件完整性、资源占用、断线重连、磁盘保留策略和异常告警。
总结
本教程给出了从摄像头发现、ONVIF 能力查询、Profile 枚举和 GetStreamUri 调用,到 FFprobe 验证、FFmpeg 截图、录像及分段采集的完整流程。部署时应重点控制账号权限、凭据泄露、设备时间偏差、组播边界、并发连接、网络带宽和存储容量,并通过长时间采集及断网恢复测试完成验收。