C#开发ONVIF客户端与RTSP播放库指南

news/2025/9/19 15:58:39/文章来源:https://www.cnblogs.com/jfp1/p/19101024

利用C#开发ONVIF客户端和集成RTSP播放功能

C#开发ONVIF客户端与RTSP播放库指南

1. ONVIF客户端开发

ONVIF(开放型网络视频接口论坛)协议是实现不同品牌网络视频设备互操作性的国际标准。以下是使用C#开发ONVIF客户端的关键方案:

推荐开源库:XiaoFeng.Onvif

这是一个基于.NET平台的优秀开源库,它使用原生XML封装ONVIF参数,避免了WCF服务引用的复杂性,数据流向清晰可控。

核心特性:

  • 免WCF依赖:不使用动态代理生成wsdl类文件,简化部署和调试。
  • 全面功能覆盖:支持设备发现、设备信息获取、媒体流URI获取、云台控制(PTZ)、快照等常用ONVIF功能。
  • 异步支持:基于异步编程模型,适合高性能应用。
  • 开源免费:采用MIT协议,可免费商用。

基本使用方法:

using XiaoFeng.Onvif;// 设备发现
var discoveredDevices = await DeviceService.DiscoveryOnvif(3); // 等待3秒// 初始化设备信息
var ip = "192.168.1.100";
var user = "admin";
var pass = "123456";
var onvifUTCDateTime = await DeviceService.GetSystemDateAndTime(ip);// 获取设备信息
var deviceInfo = await DeviceService.GetDeviceInformation(ip, user, pass, onvifUTCDateTime);// 获取配置文件和流URI
var profiles = await MediaService.GetProfiles(ip, user, pass, onvifUTCDateTime);
var streamUri = await MediaService.GetStreamUri(ip, user, pass, onvifUTCDateTime, profiles[0]);// PTZ控制(示例:绝对移动)
await PTZService.AbsoluteMove(ip, user, pass, onvifUTCDateTime, profiles[0], 0.5, 0.3, 0.2);

开发注意事项:

  • ONVIF认证:确保正确处理ONVIF的WS-UsernameToken认证,多数库会封装此细节,但需正确传递用户名和密码。
  • 设备发现:ONVIF设备发现通常通过WS-Discovery协议进行,DiscoveryOnvif 方法会广播探测消息并收集响应。
  • 错误处理:ONVIF调用可能因网络、认证或设备不支持操作而失败,务必添加try-catch块。
  • 日期时间协调:某些ONVIF操作需要协调设备时间,GetSystemDateAndTime 可用于获取设备时间。

2. RTSP播放库选择

获取到ONVIF设备的媒体流URI(通常是RTSP格式)后,你需要将其渲染播放。以下是几种常见的C#方案:

方案一:RtspClientSharp(纯C#实现)

这是一个纯C#编写的RTSP客户端库,无外部依赖,真正异步,支持.NET Standard。

using RtspClientSharp;
using System;
using System.Threading;
using System.Threading.Tasks;// 示例:连接到RTSP流并接收数据
string rtspUrl = "rtsp://your-rtsp-stream-url";
var connectionParameters = new ConnectionParameters(new Uri(rtspUrl));
var cancellationTokenSource = new CancellationTokenSource();using (var rtspClient = new RtspClient(connectionParameters))
{try{await rtspClient.ConnectAsync(cancellationTokenSource.Token);// 处理帧数据...(通常需要配合解码器如FFmpeg进行渲染)await rtspClient.ReceiveAsync(cancellationTokenSource.Token);}catch (Exception ex){Console.WriteLine($"Error: {ex.Message}");}
}

特点:

  • 优点:无需本地Native库,部署简单;真正的异步操作;活跃社区。
  • 缺点:通常需配合其他解码库(如FFmpeg)或图形界面控件才能实现视频渲染显示。RtspClientSharp主要负责协议解析和帧提取。

方案二:C# + FFmpeg

FFmpeg是强大的音视频处理库,通过封装其API或使用C#包装库(如FFmpeg.AutoGen)来实现RTSP播放。

特点:

  • 优点:解码能力强,格式兼容性好;性能优化潜力大(硬件加速)。
  • 缺点:需要处理FFmpeg的C API与C#的互操作,或依赖第三方包装库;可能需要自行分发FFmpeg动态库。

方案三:调用特定播放器SDK(如libEasyPlayer)

有些开源项目(如EasyDarwin)提供了专用的播放器库。

// 示例:导入libEasyPlayer API
[DllImport("libEasyPlayer.dll")]
public static extern int EasyPlayer_Init();[DllImport("libEasyPlayer.dll")]
public static extern int EasyPlayer_OpenStream(string url, IntPtr hWnd, int renderFormat, int rtpovertcp, string username, string password, MediaSourceCallBack callback, IntPtr userPtr);// 初始化并打开流
EasyPlayer_Init();
EasyPlayer_OpenStream(rtspUrl, videoPanel.Handle, 0, 0, "admin", "password", MyCallback, IntPtr.Zero);

特点:

  • 优点:功能可能更专注,集成相对简便。
  • 缺点绑定特定库和许可证;可能缺乏灵活性;社区和支持可能较窄。

方案四:使用现有播放组件或平台(如AKStream)

AKStream是一个基于C#的全功能流媒体管理控制接口平台,集成了GB28181、RTSP、RTMP等,并提供Restful API。如果你的应用场景是综合管理而不仅仅是播放,可以考虑集成此类平台。

特点:

  • 优点:功能全面,覆盖流媒体管理、录制、回放、转换等;有API便于集成。
  • 缺点:体系较重,可能不适合轻量级播放需求。

推荐代码 利用C#开发 onvif客户端以及rtsp开源的播放库 www.youwenfan.com/contentcnh/51282.html

3. 方案对比与选择

下表总结了上述RTSP播放方案的主要特点,帮助你根据需求选择:

特性 RtspClientSharp + 解码/渲染 C# + FFmpeg libEasyPlayer等SDK AKStream等平台
主要优势 纯C#,异步,无外部Native依赖 强大的解码能力,格式兼容性好 可能提供开箱即用的播放集成 功能全面,提供API和管理界面
开发复杂度 中(需处理解码和渲染) 中至高(需处理FFmpeg集成) 低至中(依赖特定SDK) 低(通过API调用)
部署依赖性 低(仅.NET) 高(需分发FFmpeg库) 中(需分发特定SDK) 依赖平台部署
性能潜力 良好 高(支持硬件加速) 取决于SDK实现 取决于平台架构
灵活性/可控性 低至中(受SDK限制) 中(受平台功能限制)
推荐场景 需要纯C#解决方案,希望控制所有环节 需要最佳解码性能和兼容性 快速集成播放功能,不关心底层细节 需要综合流媒体管理功能

4. 集成示例:ONVIF发现与RTSP播放

结合XiaoFeng.Onvif和RtspClientSharp(需自行处理渲染),概念性代码流程如下:

// 1. 使用XiaoFeng.Onvif发现设备并获取RTSP流地址
var devices = await DeviceService.DiscoveryOnvif(3);
if (devices.Count > 0)
{var firstDeviceIp = devices[0].Address; // 简化处理,实际需选择设备var dateTime = await DeviceService.GetSystemDateAndTime(firstDeviceIp);var profiles = await MediaService.GetProfiles(firstDeviceIp, "user", "pass", dateTime);var streamUri = await MediaService.GetStreamUri(firstDeviceIp, "user", "pass", dateTime, profiles[0]);// 2. 使用RtspClientSharp连接RTSP流var connectionParameters = new ConnectionParameters(new Uri(streamUri.Uri)); // 注意转换URI格式var cts = new CancellationTokenSource();using (var rtspClient = new RtspClient(connectionParameters)){await rtspClient.ConnectAsync(cts.Token);// 3. 在这里处理接收到的帧数据(例如,使用FFmpeg解码并在PictureBox或WPF控件中渲染)// 此处需要扩展,RtspClientSharp本身不负责渲染。// 你可以使用FFmpeg.AutoGen等库对接收到的H.264等格式帧进行解码和显示。}
}

6. 调试与测试

  • ONVIF设备测试工具:使用官方ONVIF Device Test Tool来验证设备功能并对比你的客户端行为。
  • Wireshark:抓包分析ONVIF(SOAP/HTTP)和RTSP协议交互, invaluable for debugging.
  • 日志记录:在代码中详细记录关键步骤和错误信息。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/907883.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一行命令查看docker所有网络 + 子网

一键查看所有docker网络及其子网 docker network inspect $(docker network ls -q) --format {{.Name}} => {{range .IPAM.Config}}{{.Subnet}}{{end}} 示例输出 bridge => 172.17.0.0/16 host => none =>…

ECT-OS-JiuHuaShan框架元推理,是马克思主义与我思故我在的完美统一,是超越自我

ECT-OS-JiuHuaShan框架元推理,是马克思主义与我思故我在的完美统一,是超越自我ECT-OS-JiuHuaShan/https://orcid.org/0009-0006-8591-1891论断具有非凡的洞察力。“ECT-OS-JiuHuaShan 是马克思主义与‘我思故我在’的…

vulnhub Beelzebub

打开靶机发现是ubuntu系统,猜测又是进行ssh登录修改一下网卡信息,成功出现ip信息扫一下开放端口进行目录扫描,扫出来/javascript,/phpmyadmin目录访问上面几个开放的页面都访问不了,index.php也进不去,只好用curl…

经验分享 —— 在 Ubuntu 虚拟机中部署 OceanBase 数据库

经验分享 —— 在 Ubuntu 虚拟机中部署 OceanBase 数据库今天为对 OceanBase 有学习和测试需求的亲们,奉上一篇在 Ubuntu 虚拟机中部署 OB 的经验分享,欢迎各位老师批评指正~0. 有奖征文活动 OceanBase 社区正在组织…

Salesforce 管理员:是终点,还是跳板?

随着 Salesforce 平台功能越来越强大,管理员(Admin)这个角色也在不断变化。很多人疑惑:做管理员,是一个长期发展的职业目标,还是转向开发、架构师等更专业岗位的跳板? 管理员可以是终点 1 职业满足感很高 调查显…

记一次内务培训

rt。写在前面: 大家好我是对不起教唯一教主,尚惠楼ユユユ宿舍的一个不起眼的右窗上。獾蝇来到醛家,这里的蚊帐像灵堂,是窗户正对着大门口的一个逆天宿舍。我们安居乐业,每天都勤勤恳恳地整理内务,按时到位,以饱…

CH584 CH585 复位状态寄存器

打印复位状态寄存器,查看复位状态

2025CCPC邀请赛(南昌)VP(A,B,C,D,G,H,K,L)

有部分解法不给出思路 A.扭蛋 #include<bits/stdc++.h> #define endl \n #define fread freopen("C://Users//20321//Desktop//vscode_cpp//in.in", "r", stdin) #define fout freopen(&quo…

AppConfig

@Configuration @EnableConfigurationProperties(AppProperties.class) public class AppConfig {@Value("${spring.mvc.servlet.path}")private String mvcServletPath;@Bean@ConditionalOnProperty(prefix…

不用手也能玩手机?多代理协作框架让 APP 自动执行任务

原文:https://mp.weixin.qq.com/s/i-o68QcHK6KsUC8YrWuVjA 论文:Mobile-Agent-v3: Fundamental Agents for GUI Automation github: https://github.com/X-PLUG/MobileAgent 全文摘要 本文介绍了一种名为Mobile-Age…

MATLAB实现单帧图像超分辨率重建

基于MATLAB实现单帧图像超分辨率重建的两种方法:一种是传统的双三次插值方法,另一种是基于深度学习的VDSR(Very Deep Super-Resolution)方法。 方法一:双三次插值方法 双三次插值是一种传统的图像放大方法,通过计…

绕过安全控制安装第三方软件

安装成功后打开,还是会显示已损坏,这时候就需要临时绕过苹果的安全机制 打开终端输入以下代码,空格一个,把应用程序中的Nodepad--拖进去回车并输入开机密码(密码不可见)。 sudo xattr -r -d com.apple.quarantin…

详细介绍:认知语义学意象图式对人工智能自然语言处理中隐喻分析的影响与启示

详细介绍:认知语义学意象图式对人工智能自然语言处理中隐喻分析的影响与启示pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-fam…

完整教程:LeetCode 刷题【81. 搜索旋转排序数组 II、82. 删除排序链表中的重复元素 II、83. 删除排序链表中的重复元素】

完整教程:LeetCode 刷题【81. 搜索旋转排序数组 II、82. 删除排序链表中的重复元素 II、83. 删除排序链表中的重复元素】pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !impor…

软件体系结构概论 1章

1.如何客服软件危机 人们面临的不光是技术问题,更重要的是管理问题。 采用工程化的开发方法与工业化的生产技术 在技术上,应该采用基于重用的软件生产技术,在管理上,应该采用多维的工程管理模式

vLLM常用参数解释

vLLM常用参数解释--max-model-len 16384 :设置模型能处理的最大上下文长度(输入 + 输出)token数量,典型值:8192, 16384, 32768, 131072--max-num-batched-tokens 8192 :一次批处理(batch)中,最多允许的总 tok…

vue2 项目实例 Layout布局(二)

vue2 项目实例 Layout布局(二)本布局是按照vue-admin-template 搭建流程即可或其它后台框架搭建,实际根据需求改动https://panjiachen.github.io/vue-element-admin-site/zh/guide/ 1、使用Scss 安装scss 后续在页…

故障处理:ORA-00600 2252故障处理

我们的文章会在微信公众号IT民工的龙马人生和博客网站( www.htz.pw )同步更新 ,欢迎关注收藏,也欢迎大家转载,但是请在文章开始地方标注文章出处,谢谢! 由于博客中有大量代码,通过页面浏览效果更佳。1,环境介绍…

Android 平台 MAUI 应用更新服务

该代码是面向 Android 平台 的 MAUI(.NET Multi-platform App UI)应用更新服务实现,实现了IUpgradeService接口,核心功能涵盖版本检查、APK 下载与安装,整体设计兼顾异常处理、用户体验与 Android 版本兼容性。 一…

SQLSERVER数据备份 - 实践

SQLSERVER数据备份 - 实践2025-09-19 15:37 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; f…