zoukankan      html  css  js  c++  java
  • EasyDarwin自动停止推流

    原文转自:http://blog.csdn.net/ss00_2012/article/details/51441753


           我们使用EasyDarwin的推流转发来进行媒体直播的时候,有时会有这样一个需求,当推流端推送的媒体没有客户端观看时,就希望推流端不再推送,也就是实现按需推送,当推流端使用4G网络时这个需求会更加强烈。

           需求明确,那么说下实现。实现分为两步:触发和通知。

           触发,EasyDarwin为每一路推流转发维护一个ReflectorSession对象,该对象的fNumOutputs属性用来指示当前拉流客户端的数量。当客户端停止拉流时会调用QTSSReflectorModule::DestroySession()->QTSSReflectorModule::RemoveOutput()->ReflectorSession::RemoveOutput(),其中ReflectorSession::RemoveOutput()代码如下:

    [cpp] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. void    ReflectorSession::RemoveOutput(ReflectorOutput* inOutput, Bool16 isClient)  
    2. {  
    3.     (void)atomic_sub(&fNumOutputs, 1);  
    4.     for (UInt32 y = 0; y < fSourceInfo->GetNumStreams(); y++)  
    5.     {  
    6.         fStreamArray[y]->RemoveOutput(inOutput);  
    7.         if (isClient)  
    8.             fStreamArray[y]->DecEyeCount();    
    9.     }  
    10. }  

           其中(void)atomic_sub(&fNumOutputs, 1);用来减少当前的客户端数量,我们可以在此判断fNumOutputs是否为0,为0就表示满足我们的触发条件,修改后的代码如下:

    [cpp] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. void    ReflectorSession::RemoveOutput(ReflectorOutput* inOutput, Bool16 isClient)  
    2. {  
    3.     (void)atomic_sub(&fNumOutputs, 1);  
    4.     for (UInt32 y = 0; y < fSourceInfo->GetNumStreams(); y++)  
    5.     {  
    6.         fStreamArray[y]->RemoveOutput(inOutput);  
    7.         if (isClient)  
    8.             fStreamArray[y]->DecEyeCount();    
    9.     }  
    10.  //移除客户端之后判断fNumOutputs是否为0,add  
    11.  if(fNumOutputs == 0)  
    12.  {  
    13.   //调用角色,停止推流  
    14.   qtss_printf("客户端都不看啦 ");  
    15.   QTSS_RoleParams theParams;  
    16.   theParams.easyStreamStopParams.inSerial = fSerial;  
    17.   theParams.easyStreamStopParams.inChannel= fChannel;  
    18.   QTSSModule* theModule = QTSServerInterface::GetModule(QTSSModule::kStreamStopRole, 0);  
    19.   (void)theModule->CallDispatch(Easy_StreamStop_Role, &theParams);  
    20.  }  
    21.  //  
    22. }  

           触发之后我们就调用Easy_StreamStop_Role角色来通知完成停止推流。

           上述触发并不完美,对于推流之后并没有客户端拉流这种情况无法处理。因此我们又增加了循环检测的机制,通过将ReflectorSession继承Task,然后在其Run函数里循环检测fNumOutputs是否为0可以有效的解决这种情况,ReflectorSession::Run()代码如下:

    [cpp] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. SInt64 ReflectorSession::Run()  
    2. {  
    3.  if(fIfFirstRun)  
    4.   fIfFirstRun = false;//第一次的时候还没有拉流,就不要进行处理了;客户端拉流不要过慢。  
    5.  else  
    6.  {  
    7.   if(fNumOutputs == 0)  
    8.   {  
    9.    //调用角色,停止推流  
    10.    qtss_printf("没有客户端观看当前转发媒体 ");  
    11.    QTSS_RoleParams theParams;  
    12.    theParams.easyStreamStopParams.inSerial = fSerial;  
    13.    theParams.easyStreamStopParams.inChannel= fChannel;  
    14.    QTSSModule* theModule = QTSServerInterface::GetModule(QTSSModule::kStreamStopRole, 0);  
    15.     (void)theModule->CallDispatch(Easy_StreamStop_Role, &theParams);  
    16.   }  
    17.  }  
    18.  return 15*1000;  
    19. }  

           另外不要忘了在ReflectorSession的构造函数中调用this->Signal(Task::kStartEvent);来开始循环检测。

           通知,OK,到此触发就搞定了,下面我们就需要把停止推流这个信息告诉推流端就OK了,由谁告诉?对于推流端的管理是由EasyCMS来进行的,因此我们需要先将停止推流信息告诉EasyCMS,然后让EasyCMS告诉指定的推流端。为此我们创建了EasyCMSSession来和EasyCMS进行通讯,创建了EasyCMSModule为外面调用角色提供接口。详细代码请参考https://github.com/EasyDarwin/EasyDarwin


  • 相关阅读:
    vue开发chrome扩展,数据通过storage对象获取
    Vue手动集成less预编译器
    Google Translate寻找之旅
    Javascript Range对象的学习
    Javascript Promises学习
    SublimeText 建立构建Node js系统
    We're sorry but demo3 doesn't work properly without JavaScript enabled. Please enable it to continue.
    npm安装包出现UNMET DEPENDENCY报错
    (转载)命令行说明中格式 尖括号 中括号的含义
    Linux重启网卡服务Failed to start LSB: Bring up/down networking.
  • 原文地址:https://www.cnblogs.com/babosa/p/5904643.html
Copyright © 2011-2022 走看看