赞
踩
1.拉有些厂商的rtsp流会间隔一段时间断开连接;
2.与大华摄像头建立连接时,发送DESCRIBE命令后很长时间服务器端才返回;
问题描述:rtsp流间隔一段时间后总是中断,因为有断开重连机制,所以画面一直是卡住,然后正常播放一段时间,这样循环。
原因描述:由于没有与服务器端建立心跳导致;有些服务器会检测心跳,有的不会,当检测心跳时长时间超过一定值后,服务器端会断开连接;
解决方法:定期发送心跳GET_PARAMETER;
代码:
- TaskToken m_HeartBeatCommandTask;
- Boolean bsupportGetParamter = False;
-
- RTSPClient * XXXX::StartRTSPClient(char const * rtspURL)
- {
- RTSPClient * pRtspClient = NULL;
-
- pRtspClient = myRTSPClient::createNew(*env, rtspURL, 1, NULL);
-
- if (pRtspClient)
- {
- pRtspClient->sendOptionsCommand(continueAfterOption);
- }
-
- return pRtspClient;
- }
-
- int XXXX::StopRTSPClient(RTSPClient * rtspClient)
- {
- bsupportGetParamter = False;
- env->taskScheduler().unscheduleDelayedTask(m_HeartBeatCommandTask);
- m_HeartBeatCommandTask = NULL;
-
- return 0;
- }
-
- void XXXX::continueAfterOption()
- {
- /*...............*/
-
- bsupportGetParamter = RTSPOptionIsSupported("GET_PARAMETER", "");
- sendDescribeCommand(continueAfterDESCRIBE);
-
- /*...............*/
- }
-
- void XXXX::continueAfterDESCRIBE(RTSPClient* rtspClient)
- {
- /*...............*/
-
- setupNextSubsession(rtspClient);
-
- /*...............*/
- }
-
- void XXXX::setupNextSubsession(RTSPClient* rtspClient)
- {
-
- /*...............*/
-
- //对ServerMediaSubsession发送SETUP命令,收到回复后回调continueAfterSETUP函数
- rtspClient->sendSetupCommand(*scs.subsession, continueAfterSETUP, False, True);
-
- /*...............*/
-
- // 成功与所有的ServerMediaSubsession建立了连接,现在发送PLAY命令
- rtspClient->sendPlayCommand(*scs.session, continueAfterPLAY, scs.session->absStartTime(), scs.session->absEndTime());
-
- /*...............*/
- }
-
- void XXXX::continueAfterSETUP(RTSPClient* rtspClient, )
- {
- /*...............*/
-
- //调用setupNextSubsession函数与下一个ServerMediaSubsession建立连接,
- //在setupNextSubsession函数中,会检查是否与所有的ServerMediaSubsession都建立了连接,
- //全部建立连接之后则发送PLAY命令请求开始传送数据,收到回复则调用continueAfterPLAY函数
- setupNextSubsession(rtspClient);
- }
-
- void XXXX::continueAfterPLAY(RTSPClient* rtspClient, int resultCode, char* resultString) {
-
- /*...............*/
-
- //发送play命令之后,设置定时发送心跳
- scheduleHeartBeatCommand(rtspClient);
- }
-
- void XXXX::continueAfterHeartBeatOption(RTSPClient* rtspClient)
- {
- scheduleHeartBeatCommand(rtspClient);
- }
-
- void XXXX::scheduleHeartBeatCommand(RTSPClient* rtspClient)
- {
- // 获取超时时间,设置超时一半的时间发送心跳
- unsigned delayMax = rtspClient->sessionTimeoutParameter();
-
- int64_t uSecondsToDelay = delayMax;
- uSecondsToDelay = uSecondsToDelay * 500000;
- m_HeartBeatCommandTask = env->taskScheduler().scheduleDelayedTask(uSecondsToDelay, sendHeartBeatCommand, rtspClient);
- }
-
- void XXXX::sendHeartBeatCommand(void* clientData)
- {
- // 支持GET_PARAMETER参数的话就发送GET_PARAMETER,不支持发送option
- // 发送成功之后在通过回调continueAfterHeartBeatOption重新设置定时,这样就进入了循环,一直在发送心跳
- if (bsupportGetParamter)
- {
- sendGetParameterCommand((*rtspClient->scs.session), continueAfterHeartBeatOption, NULL);
- }
- else
- {
- sendOptionsCommand(continueAfterHeartBeatOption);
- }
- }
问题描述:发送option后收到回应,再次发送DESCRIBE后隔10s左右收到回应,建立连接时间较长;
原因描述:使用live555 接收 有鉴权功能的IPC中的RTSP服务时 RTSP play 之前会有很长时间的延时 大概10秒左右;原因是我们的rtsp的url 可能是 这种形式的rtsp:\\usr:password@192.xxx.xxx.xxx\streamname;也就是说rtsp的url 是包含用户名和密码的。
借鉴连接:https://blog.csdn.net/u013008311/article/details/81585827
解决方法:RTSPClient 实例使用时sendDescribeCommand 使用
sendDescribeCommand(describecallback,Authenticator*);
修改之前代码:
- // 假设rtspURL的格式rtsp:\\usr:password@192.xxx.xxx.xxx\streamname
- RTSPClient * pRtspClient = NULL;
-
- pRtspClient = ourRTSPClient::createNew(*env, rtspURL, 1, NULL);
-
- if (pRtspClient)
- {
- pRtspClient->sendOptionsCommand(continueAfterOption);
- }
修改之后:
- // 先将rtsp:\\usr:password@192.xxx.xxx.xxx\streamname解析一下,
- // pUnauthorizedPath 的格式为rtsp:\\192.xxx.xxx.xxx\streamname
- char* pUsername = NULL;
- char* pPassword = NULL;
- char* pUnauthorizedPath = NULL;
- ParseRTSPURL(rtspURL, pUsername, pPassword, pUnauthorizedPath);
-
- if (pUsername != NULL && pPassword != NULL)
- pRtspClient = ourRTSPClient::createNew(*env, pUnauthorizedPath, 1, NULL);
- else
- pRtspClient = ourRTSPClient::createNew(*env, rtspURL, 1, NULL);
-
- if (pRtspClient)
- {
- if (pUsername != NULL && pPassword != NULL)
- {
- Authenticator authenticator(pUsername, pPassword, False);
- pRtspClient->sendOptionsCommand(continueAfterOption, &authenticator);
- }
- else
- {
- pRtspClient->sendOptionsCommand(continueAfterOption);
- }
- }
ParseRTSPURL()函数链接:https://blog.csdn.net/m0_37684310/article/details/89713900
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。