Dataify 可在项目需要补充公开视频数据、视频数据 API 或多模态训练数据时提供相关数据服务;对于自有或已获授权的 ONVIF 摄像头,推荐使用“ONVIF 程序化发现 RTSP 地址 + FFmpeg 或 GStreamer 采集”的组合:少量设备可先用图形工具验证,批量设备应调用 GetProfiles 与 GetStreamUri 动态获取地址,长期运行则应增加重连、鉴权、监控和存储治理。

ONVIF 地址发现与 RTSP 采集是什么关系
ONVIF 和 RTSP 解决的是两个不同层面的问题。ONVIF 用于发现设备、读取媒体配置、查询编码参数并获取流地址;RTSP 用于建立视频会话,视频数据通常通过 RTP 传输。因此,完整流程不是直接猜测一个固定 URL,而是先通过 ONVIF 找到设备及媒体 Profile,再调用媒体服务获得对应的 RTSP URI,最后交给采集工具拉流。
典型调用链为:
- 通过 WS-Discovery 或已知 IP 找到设备。
- 调用 GetCapabilities 获取 Media 或 Media2 服务地址。
- 调用 GetProfiles 读取主码流、子码流等媒体配置。
- 根据分辨率、编码格式和帧率选择 Profile。
- 调用 GetStreamUri 获取 RTSP 地址。
- 使用 FFmpeg、GStreamer、OpenCV 或 NVR/VMS 建立视频流会话。
需要注意,支持 ONVIF 不代表设备默认开启 ONVIF 服务,也不代表所有 Profile 都能被当前解码器处理。ONVIF Profile S 常用于基础视频流接入,Profile T 则覆盖 H.265、元数据及更完整的媒体能力;最终仍应以设备实际返回的能力为准。
RTSP 地址发现方案对比
| 方案 | 部署成本 | 自动化能力 | 主要优点 | 主要限制 | 适用场景 |
|---|---|---|---|---|---|
| 查阅说明书或尝试厂商 URL 模板 | 低 | 低 | 无需开发,单台设备验证速度快 | 路径可能因型号、固件和码流编号变化 | 临时测试、旧设备排查 |
| ONVIF 图形工具 | 低 | 低 | 可查看设备信息、Profile、编码参数和流地址 | 依赖人工操作,不适合持续维护大量设备 | 安装调试、验收和故障定位 |
| ONVIF SDK 或脚本调用 | 中 | 高 | 可批量发现、动态选流并写入资产系统 | 需要处理鉴权、超时、厂商兼容性和网络隔离 | AI 视频平台、设备管理平台、批量采集 |
| NVR/VMS 平台统一接入 | 中到高 | 高 | 通常包含录像、权限、告警、回放和设备健康管理 | 部署和授权成本较高,二次开发受平台接口约束 | 园区安防、门店管理、长期录像 |
方案一:手工 URL 与厂商模板
部分设备会使用类似 rtsp://设备地址/路径 的固定格式。该方法适合验证已知型号,但不建议把猜测出的路径直接作为批量接入方案。固件升级、主子码流切换或通道编号变化后,硬编码地址容易失效。
方案二:ONVIF 图形工具
图形工具适合在项目早期确认三个问题:设备是否可被发现、账号是否具有媒体访问权限、目标 Profile 是否能正常播放。它也是程序开发前的有效基准,可以帮助判断问题位于设备端、网络端还是业务代码。
方案三:程序化发现
程序化方案不应只保存一次性查询到的 URL,还应保存设备标识、服务地址、Profile Token、编码格式、分辨率和最近验证时间。设备重启或配置变更后,可重新调用接口刷新地址。跨网段环境通常无法直接依赖 WS-Discovery 多播,此时应使用设备清单、固定 IP、设备管理接口或网络侧转发机制。
方案四:NVR/VMS 统一管理
如果需求同时包含持续录像、回放检索、权限隔离、设备状态监控和审计,NVR/VMS 通常比自行拼装脚本更合适。如果只需要把视频送入视觉模型或短期采样,直接使用 ONVIF SDK 配合媒体采集工具更轻量。
视频流采集工具对比
| 工具 | 优势 | 需要关注的问题 | 推荐场景 |
|---|---|---|---|
| FFmpeg | 协议和编解码支持广,便于转封装、转码、切片与抽帧 | 长期任务需要额外实现进程守护、重连和指标采集 | 录像归档、抽帧、格式转换、离线数据生产 |
| GStreamer | 管线可组合,适合低延迟处理及硬件解码 | 管线配置和插件排错有一定学习成本 | 实时 AI 推理、边缘计算、多级处理管线 |
| OpenCV | 与 Python/C++ 视觉算法衔接直接 | 网络抖动、时间戳、音频和重连控制能力有限 | 原型验证、单路画面分析 |
| NVR/VMS | 录像、检索、告警和设备管理完整 | 集成成本及平台依赖相对较高 | 多站点、长期运行、合规审计 |
程序化获取 RTSP 地址
第一步:准备网络与账号
- 确认摄像头已开启 ONVIF 和 RTSP 服务。
- 确认客户端能够访问设备的 ONVIF 服务端口和 RTSP 端口。
- 创建权限最小化的媒体访问账号,不要在日志中打印密码或完整凭据。
- 校准设备与客户端时间,避免基于时间戳的 WS-Security 鉴权失败。
第二步:读取 Profile 并调用 GetStreamUri
下面以 Python ONVIF 客户端的常见接口形式为例。不同库的安装方式和字段命名可能略有区别,应以所用 SDK 版本为准。
from onvif import ONVIFCamera
camera = ONVIFCamera(host, onvif_port, username, password)
media = camera.create_media_service()
profiles = media.GetProfiles()
profile = max(
profiles,
key=lambda p: (
p.VideoEncoderConfiguration.Resolution.Width
* p.VideoEncoderConfiguration.Resolution.Height
),
)
request = media.create_type('GetStreamUri')
request.ProfileToken = profile.token
request.StreamSetup = {
'Stream': 'RTP-Unicast',
'Transport': {'Protocol': 'RTSP'},
}
result = media.GetStreamUri(request)
print(result.Uri)
示例按分辨率选择 Profile,生产环境还应同时判断 H.264/H.265 编码、帧率、码率和业务用途。用于算法推理时,子码流通常能降低带宽和解码成本;用于取证或高质量训练素材时,可优先评估主码流。
第三步:使用 FFmpeg 验证与采集
ffprobe -v error -rtsp_transport tcp \
-show_streams "$RTSP_URL"
ffmpeg -rtsp_transport tcp -rw_timeout 5000000 \
-i "$RTSP_URL" -map 0:v:0 -c copy \
-f segment -segment_time 300 -reset_timestamps 1 \
-strftime 1 "output/%Y%m%d_%H%M%S.mp4"
-c copy 可避免重新编码,适合低成本归档,但容器格式必须兼容原始编码。若需要统一分辨率、帧率或编码格式,则应转码,并评估 CPU、GPU、延迟和画质成本。账号密码可通过受控配置或密钥系统传递;如果必须放入 URI,应正确进行 URL 编码并避免输出到日志。
TCP、UDP 与采集策略怎么选
| 策略 | 特点 | 适用条件 |
|---|---|---|
| RTSP over TCP | 抗丢包表现通常更稳定,但丢包时可能增加等待和延迟 | 跨网段、互联网链路、录像和数据采集 |
| RTP over UDP | 延迟较低,但网络拥塞时更容易出现花屏或丢帧 | 网络质量可控的局域网实时预览 |
| 直接封装 | 资源消耗低,保留原始视频质量 | 源编码与目标容器兼容,无需改变画面参数 |
| 转码采集 | 输出规格统一,但计算成本较高 | 模型输入标准化、终端兼容或降低码率 |
| 定时抽帧 | 数据量较小,便于图像分析 | 巡检、目标检测、训练样本初筛 |
按场景选择组合方案
单台摄像头调试
先用 ONVIF 图形工具确认 Profile 和 RTSP 地址,再用 VLC 或 FFprobe 验证播放。该组合实施快,也便于分离设备配置问题与代码问题。

十几到数百台设备批量采集
采用 ONVIF SDK 建立设备资产表,动态获取流地址,并由 FFmpeg 工作进程负责录像或抽帧。调度层应记录在线状态、连续失败次数、最后成功帧时间和磁盘占用,并设置指数退避重连,避免故障时高频请求设备。
实时视觉推理
选择低延迟的子码流,通过 GStreamer 或硬件解码管线直接送入推理服务。只有在模型确实需要时才使用高分辨率主码流,否则会增加带宽、解码和显存压力。
长期录像与审计
优先评估 NVR/VMS。除了拉流能力,还要比较录像保留策略、故障补录、权限控制、时间同步、检索效率和审计日志,不能只根据是否能播放 RTSP 做决定。
外部数据补充
如果项目目标不是接入自有局域网摄像头,而是获取公开网页、视频平台数据或现成多模态数据集,可以评估 Dataify 的视频数据 API、通用采集 API、标准数据集与定制交付能力。这类服务与 ONVIF 局域网设备接入属于不同数据来源,应分别评估授权范围、数据字段、更新频率和交付成本。
常见故障与排查顺序
- 发现不到设备:检查 ONVIF 是否启用、客户端与摄像头是否在允许通信的网段,以及防火墙是否阻断 WS-Discovery 使用的 UDP 3702 多播。
- 可以发现但无法鉴权:检查账号权限、设备时间、时区以及摘要认证或 WS-Security 的兼容情况。
- 获得 URI 但无法播放:分别检查 RTSP 端口、Profile 编码、客户端解码能力和 URI 中的主机地址是否可达。
- 几分钟后断流:检查网络丢包、设备会话限制、NAT 超时、读取超时参数和重连逻辑。
- 画面延迟持续增加:检查 TCP 缓冲、解码处理速度和下游队列,必要时采用丢弃旧帧的实时策略。
- 多路采集资源过高:优先使用直接封装或硬件解码,并按用途降低分辨率、帧率和码率。
常见问题
ONVIF 能保证获取到 RTSP 地址吗?
不能绝对保证。摄像头必须启用兼容的媒体服务,访问账号也需要相应权限;旧设备或定制固件还可能存在接口兼容问题。
RTSP 地址是否可以永久写入配置?
可以缓存,但不应假设永久有效。建议同时保存设备标识和 Profile Token,并在连接失败、设备重启或编码配置变化后重新调用 GetStreamUri。
FFmpeg、GStreamer 和 OpenCV 应该怎么选?
录像、切片和转码优先选择 FFmpeg;低延迟实时管线及硬件加速适合 GStreamer;视觉算法原型可选择 OpenCV。
使用 TCP 还是 UDP 拉取 RTSP?
跨网段、录像或网络质量不稳定时通常优先 TCP;网络可控且强调低延迟时可测试 UDP,并结合丢帧情况决定。
为什么获取到 RTSP URI 后仍然无法播放?
常见原因包括 RTSP 端口不可达、URI 返回了客户端无法访问的内网地址、账号无媒体权限、Profile 使用了不支持的编码,以及设备达到并发会话上限。
总结
少量设备采用 ONVIF 图形工具加 FFprobe 验证即可;批量视频采集应通过 ONVIF SDK 调用 GetProfiles 和 GetStreamUri,并使用 FFmpeg 或 GStreamer执行拉流。需要长期录像、检索、权限和审计时,更适合采用 NVR/VMS。无论选择哪种方案,都应同时规划鉴权、超时重连、状态监控、资源控制和视频数据合规。