首页 > 其他分享 >live555作为RTSP流媒体服务器时Server端多track而客户端仅请求一个track,当客户端关闭时没有关闭流的问题解决方案

live555作为RTSP流媒体服务器时Server端多track而客户端仅请求一个track,当客户端关闭时没有关闭流的问题解决方案

时间:2023-09-08 18:35:12浏览次数:45  
标签:noSubsessionsRemain track clientTrackNum trackNum fStreamStates video 关闭 客户端


当我们使用live555作为流媒体服务器时,某个通道对应的所有客户端断开后, 不能正常回调关闭。
某一通道同时支持视频和音频输出, 即video和audio两个track
VLC和EasyPlayer播放库来中的RTSPClient则都会请求(所以不存在问题);
而某些客户端则只请求了一个track, 比如video;

此时再关闭,会有两种情况:
在VLC或自有播放库来断开连接时,都会正常回调关闭;
在仅请求了video的客户端断开连接时, 一定不会回调关闭;

分析问题:

在RTSPClient断开时,一定会调用RTSPServer::stopTCPStreamingOnSocket, 当流为RTP Over TCP时, 则会调用deleteStreamByTrack;
在deleteStreamByTrack函数中, 是一个for循环,检测fStreamStates的subsession, 因为sdp中存在video和audio, fNumStreamStates的值为2, 而客户端只请求了video,所以在以下的代码中,判断不成立:

Boolean noSubsessionsRemain = True;
  for (unsigned i = 0; i < fNumStreamStates; ++i) {
    if (fStreamStates[i].subsession != NULL) {
      noSubsessionsRemain = False;		//因为存在video和audio, 所以此处条件会成立
      break;
    }
  }

因为noSubsessionsRemain为False, 所以下面的代码不会被执行;

if (noSubsessionsRemain) delete this;

顺便说一下, delete this是删除RTSPClientSession, 在ClientSession的析构函数中,会减少引用计数,如果计数为0, 则删除fOurServerMediaSession;

解决问题:

在RTSPClientConnection中增加一个计数变量, 用于记录客户端请求的track个数, 然后在deleteStreamByTrack中递减,如果为0, 则使上面的noSubsessionsRemain为True;
修改如下:

//在RTSPClientConnection的声明中,增加以下两个变量
	int	clientRequestTrackNum;		//for rtp over tcp
	char fClientSessionIdStr[16];	//for rtp over udp
	
	void RTSPServer::RTSPClientSession
	::handleCmd_SETUP(UsageEnvironment *pEnv, RTSPServer::RTSPClientConnection* ourClientConnection,
			  char const* urlPreSuffix, char const* urlSuffix, char const* fullRequestStr) {
			  
			  ......
			  
			  
	    if (streamingMode == RTP_TCP) {
	      // Note that we'll be streaming over the RTSP TCP connection:
	      fStreamStates[trackNum].tcpSocketNum = ourClientConnection->fClientOutputSocket;
	      fOurRTSPServer.noteTCPStreamingOnSocket(fStreamStates[trackNum].tcpSocketNum, this, trackNum);

				//此处增加计数
		  	ourClientConnection->clientRequestTrackNum ++;
	    }		
	    
	    ......
	}

修改deleteStreamByTrack的声明和实现:

void deleteStreamByTrack(UsageEnvironment *pEnv, unsigned trackNum, Boolean lockFlag, int *clientTrackNum);

	void RTSPServer::RTSPClientSession::deleteStreamByTrack(UsageEnvironment *pEnv, unsigned trackNum, Boolean lockFlag, int *clientTrackNum) {

		lockClientFlag = lockFlag;

	  if (trackNum >= fNumStreamStates) return; // sanity check; shouldn't happen
	  if (fStreamStates[trackNum].subsession != NULL) {
	    fStreamStates[trackNum].subsession->deleteStream(fOurSessionId, fStreamStates[trackNum].streamToken);
	    fStreamStates[trackNum].subsession = NULL;
	  }
	  
	  // Optimization: If all subsessions have now been deleted, then we can delete ourself now:
	  Boolean noSubsessionsRemain = True;
	  for (unsigned i = 0; i < fNumStreamStates; ++i) {
	    if (fStreamStates[i].subsession != NULL) {
	      noSubsessionsRemain = False;
	      break;
	    }
	  }

	  if (NULL!=clientTrackNum)
	  {
		  if (*clientTrackNum > 0)		*clientTrackNum -= 1;
		  if (*clientTrackNum == 0)		noSubsessionsRemain = True;
	  }

	  if (noSubsessionsRemain) delete this;
	}


标签:noSubsessionsRemain,track,clientTrackNum,trackNum,fStreamStates,video,关闭,客户端
From: https://blog.51cto.com/u_16247540/7412145

相关文章

  • live555做流媒体服务器时解决rtp over udp模式下, 客户端没有发送teardown时直接关闭
    在我们使用live555作为RTSP服务器时,客户端在rtpoverudp模式下,rtsp客户端没有发送teardown而直接断开连接时需要等待65秒才回调关闭的问题。分析问题在RTSPClientConnection中没有保存相应的session值,所以在RTSPClientConnection断开时,并没有删除相应的RTSPClientSession;解......
  • live555作为RTSP客户端对接大华的某款球机RTSP流时不能预览问题的解决方案
    我们使用live555作为RTSP客户端拉取对接大华的球机RTSP直播流时,不能正常预览,球机在客户现场,型号未知。这种情况下,我们分析了,我们使用live555已接过N多种不同的摄像机,包括大华的相机之前也接过,没有出现过这种问题.而客户现场的电脑抓包软件也有问题,不能正常工作.只能加日志打印......
  • live555 RTSPClient客户端修正多网卡多ip情况下解码器不能解码显示问题
    问题海康NVR接入正常,但接入海康解码器出不来图像;分析海康解码器是以rtpoverudp的方式进行取流;如果运行streamingServer的PC,网络设置为以下两种情况,则都可以正常上墙显示:本机仅设置一个IP,且和解码器在同一网段;本机有两个IP,如192.168.xx.xx和190.168.xx.xx,解码器网......
  • 3. Oracle数据库异常关闭,导致错误3. Oracle数据库异常关闭,导致错误ERROR: ORA-01034:
    之前由于电脑没电,强制关机,导致Oracle数据库异常关闭,再次启动电脑登陆数据库时,发生以下错误:当我尝试重新启动数据库时,发生错误:经过查阅资料后得知:缺少INITXE.ORA文件,需要从下图目录中复制到上图指定目录中,并重命名为initXE.ora即可(这里initxxx.ora中的xxx要取决于你的SID)再......
  • NFS:使⽤ NFS 为远程客户端提供共享文件系统
    写在前面分享一些nfs搭建的笔记考试顺便整理内容涉及nfs服务端客户端的搭建配置理解不足小伙伴帮忙指正对每个人而言,真正的职责只有一个:找到自我。然后在心中坚守其一生,全心全意,永不停息。所有其它的路都是不完整的,是人的逃避方式,是对大众理想的懦弱回归,是随波逐流,是对内心的......
  • Windows上要启动和停止关闭Nginx
    要启动和停止关闭Nginx,在Windows上,你可以使用以下命令:启动Nginx:```nginx```停止关闭Nginx:```nginx-sstop```如果你使用`startnginx`命令在后台启动了Nginx,则可以使用以下命令将其停止关闭:```nginx-squit```使用`stop`参数将会优雅地关闭Nginx,而使用`quit`参数将会......
  • mysql8关闭binlog并清空Binlog
    编辑my.ini或者my.cnf文件清空binlog信息#查看现存的binlog文件列表showmasterlogs;#重置清空binlog文件resetmaster;#重置清空后重新查看现存的binlog文件列表是否都被清空了showmasterlogs;停用binlog功能为啥要关闭binlog功能呢?是因为反正是个测试服务器,......
  • svn客户端重置密码
    svn客户端重置密码`Windows:C:\Users\YourUsername\AppData\Roaming\Subversion\auth\svn.simple``macOS:/Users/YourUsername/.subversion/auth/svn.simple``Linux:/home/YourUsername/.subversion/auth/svn.simple`这里输入引用文本打开里面的文件,找到对应的svn链接的......
  • linux部署NFS服务端与客户端测试(共享文件目录)
    部署NFS服务端与客户端并测试NFS服务端需要安装rpcbind和nfs-utilsNFS客户端只需要安装nfs-utilsnfs端口号2049RPC端口号111++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++服务端:使用yum安装#yuminstall-ynfs-u......
  • 关闭Ubuntu Server系统自动更新
    修改配置文件/etc/apt/apt.conf.d/10periodic中相关设置,进行关闭即可。$sudovim/etc/apt/apt.conf.d/10periodic0是关闭,1是开启,将所有值改为0APT::Periodic::Update-Package-Lists"0";APT::Periodic::Download-Upgradeable-Packages"0";APT::Periodic::Autocle......