我目前正在使用WinForm应用程序,使用C#中的RTSP协议从IP摄像机流式传输视频。一切都很好。该应用程序的部分要求包括检查IP摄像头是否在线的功能。
所以我使用System.Net.NetworkInformation.Ping类来ping IP功能。假设相机的RTSP网址如下rtsp:// [CAMERA IP] :554 / Master0-RTSP / 1.0,我只需提取 [CAMERA IP] < / strong> part并使用Ping类来查看相机是否在线,使用其IP。
最初,它可以工作直到出现问题,比如如果输入的IP可能不是预期的IP摄像头(比如计算机的IP),如果输入的设备输入的IP是ping功能,ping功能仍然可以工作在线。
我尝试搜索类似RTSP ping的内容但找不到。希望对此事有任何建议或意见。非常感谢C#中的任何示例。感谢您的关注。
答案 0 :(得分:2)
OPTIONS
可能有效但标准指定正确的方法是使用GET_PARAMETER
。
RFC2326明确指出
http://www.ietf.org/rfc/rfc2326.txt
10.8 GET_PARAMETER
GET_PARAMETER请求检索a的参数值 URI中指定的表示或流。回复的内容 并且响应留待实施。 GET_PARAMETER没有 实体主体可用于测试客户端或服务器活跃度(“ping”)。
虽然服务器可能不支持GET_PARAMETER
,但无法告诉该服务器如何对OPTIONS
请求做出反应,甚至不需要sessionID。因此,无法保证它会使您现有的会话保持活跃状态。
通过阅读有关OPTIONS
请求
10.1选项
该行为与[H9.2]中描述的行为相同。一个选项 请求可以在任何时间发出,例如,如果客户即将发出 尝试非标准请求。它不会影响服务器状态。
示例:
C->S: OPTIONS * RTSP/1.0
CSeq: 1
Require: implicit-play
Proxy-Require: gzipped-messages
S->C: RTSP/1.0 200 OK
CSeq: 1
Public: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE
请注意,这些必然是虚构的功能(人们希望 我们不会故意忽略一个真正有用的功能 这样我们就可以在本节中有一个很好的例子。)
如果不支持GET_PARAMETER,那么您将发出一个PLAY请求,其中包含您希望保持活动的会话的SessionId。
即使OPTIONS不支持会话ID,如果您已经在播放,也不会产生任何不利影响。
对于C#RtspClient,请参阅我的项目@ https://net7mma.codeplex.com/
关于CodeProject的文章@ http://www.codeproject.com/Articles/507218/Managed-Media-Aggregation-using-Rtsp-and-Rtp
答案 1 :(得分:0)
而不是ICMP
ping,您可能希望保留一个没有视频/音频RTP流的帮助RTSP
会话,检查套接字连接的良好信誉并发送OPTIONS
或{{1} }例如,定期执行命令每分钟一次,以查看设备是否有响应。
有人建议使用DESCRIBE
代替选项,但这是次等方法。 GET_PARAMETER
是强制性的,OPTIONS
则不是。两者都有不同的用途。两者都有小的服务器端执行费用。 GET_PARAMETER
显然是两者中最好的。
某些服务器可能不支持设置流参数,因此不支持GET_PARAMETER和SET_PARAMETER。
答案 2 :(得分:0)
关于C#中的RTSP,请参阅此帖子Using RTMP or RTSP protocol in C#
关于Ping ...你可以实现为DESCRIBE操作...但要注意不要太频繁,设备应该受到影响。
答案 3 :(得分:0)
您可以使用RTSPClientSharp并执行以下操作:
public static async Task TestRTSPConnection(string rtspAddress, string user, string password)
{
var serverUri = new Uri(rtspAddress);
var credentials = new NetworkCredential(user, password);
var connectionParameters = new ConnectionParameters(serverUri, credentials);
var cancellationTokenSource = new CancellationTokenSource();
var connectTask = ConnectAsync(connectionParameters, cancellationTokenSource.Token);
if (await Task.WhenAny(connectTask, Task.Delay(15000 /*timeout*/)) == connectTask)
{
if (!connectTask.Result)
{
logger.Warn("Connection refused - check username and password");
}
logger.Info("Connection test completed");
}
else
{
logger.Warn("Connection timed out - check username and password");
}
}
private static async Task<bool> ConnectAsync(ConnectionParameters connectionParameters, CancellationToken token)
{
try
{
using (var rtspClient = new RtspClient(connectionParameters))
{
rtspClient.FrameReceived +=
(sender, frame) => logger.Info($"New frame {frame.Timestamp}: {frame.GetType().Name}");
while (true)
{
logger.Info("Connecting...");
try
{
await rtspClient.ConnectAsync(token);
}
catch (OperationCanceledException)
{
logger.Info("Finishing test before connection could be established. Check credentials");
return false;
}
catch (RtspClientException e)
{
logger.Error($"{e.Message}: {e.InnerException?.Message}");
return false;
}
logger.Info("Connected - camera is online");
return true;
}
}
}
catch (OperationCanceledException)
{
return false;
}
}
如果您只关心ping并且相机是否在线,它对我来说效果很好。当凭据不正确时,也会发生超时。如果未暴露端口或拒绝连接,则会直接失败。