EasyDarwin开源流媒体服务器如何实现按需推送直播的
--本文转自EasyDarwin开源团队成员邵帅的博客:http://blog.csdn.net/ss00_2012/article/details/51441753
我们使用EasyDarwin的推流转发来进行媒体直播的时候,有时会有这样一个需求,当推流端推送的媒体没有客户端观看时,就希望推流端不再推送,也就是实现按需推送,当推流端使用4G网络时这个需求会更加强烈。
需求明确,那么说下实现。实现分为两步:触发和通知。
触发,EasyDarwin为每一路推流转发维护一个ReflectorSession对象,该对象的fNumOutputs属性用来指示当前拉流客户端的数量。当客户端停止拉流时会调用QTSSReflectorModule::DestroySession()->QTSSReflectorModule::RemoveOutput()->ReflectorSession::RemoveOutput(),其中ReflectorSession::RemoveOutput()代码如下:
- void ReflectorSession::RemoveOutput(ReflectorOutput* inOutput, Bool16 isClient)
- {
- (void)atomic_sub(&fNumOutputs, 1);
- for (UInt32 y = 0; y < fSourceInfo->GetNumStreams(); y++)
- {
- fStreamArray[y]->RemoveOutput(inOutput);
- if (isClient)
- fStreamArray[y]->DecEyeCount();
- }
- }
其中(void)atomic_sub(&fNumOutputs, 1);用来减少当前的客户端数量,我们可以在此判断fNumOutputs是否为0,为0就表示满足我们的触发条件,修改后的代码如下:
- void ReflectorSession::RemoveOutput(ReflectorOutput* inOutput, Bool16 isClient)
- {
- (void)atomic_sub(&fNumOutputs, 1);
- for (UInt32 y = 0; y < fSourceInfo->GetNumStreams(); y++)
- {
- fStreamArray[y]->RemoveOutput(inOutput);
- if (isClient)
- fStreamArray[y]->DecEyeCount();
- }
- //移除客户端之后判断fNumOutputs是否为0,add
- if(fNumOutputs == 0)
- {
- //调用角色,停止推流
- qtss_printf("客户端都不看啦\n");
- QTSS_RoleParams theParams;
- theParams.easyStreamStopParams.inSerial = fSerial;
- theParams.easyStreamStopParams.inChannel= fChannel;
- QTSSModule* theModule = QTSServerInterface::GetModule(QTSSModule::kStreamStopRole, 0);
- (void)theModule->CallDispatch(Easy_StreamStop_Role, &theParams);
- }
- //
- }
触发之后我们就调用Easy_StreamStop_Role角色来通知完成停止推流。
上述触发并不完美,对于推流之后并没有客户端拉流这种情况无法处理。因此我们又增加了循环检测的机制,通过将ReflectorSession继承Task,然后在其Run函数里循环检测fNumOutputs是否为0可以有效的解决这种情况,ReflectorSession::Run()代码如下:
- SInt64 ReflectorSession::Run()
- {
- if(fIfFirstRun)
- fIfFirstRun = false;//第一次的时候还没有拉流,就不要进行处理了;客户端拉流不要过慢。
- else
- {
- if(fNumOutputs == 0)
- {
- //调用角色,停止推流
- qtss_printf("没有客户端观看当前转发媒体\n");
- QTSS_RoleParams theParams;
- theParams.easyStreamStopParams.inSerial = fSerial;
- theParams.easyStreamStopParams.inChannel= fChannel;
- QTSSModule* theModule = QTSServerInterface::GetModule(QTSSModule::kStreamStopRole, 0);
- (void)theModule->CallDispatch(Easy_StreamStop_Role, &theParams);
- }
- }
- return 15*1000;
- }
另外不要忘了在ReflectorSession的构造函数中调用this->Signal(Task::kStartEvent);来开始循环检测。
通知,OK,到此触发就搞定了,下面我们就需要把停止推流这个信息告诉推流端就OK了,由谁告诉?对于推流端的管理是由EasyCMS来进行的,因此我们需要先将停止推流信息告诉EasyCMS,然后让EasyCMS告诉指定的推流端。为此我们创建了EasyCMSSession来和EasyCMS进行通讯,创建了EasyCMSModule为外面调用角色提供接口。详细代码请参考https://github.com/EasyDarwin/EasyDarwin。
EasyDarwin开源流媒体服务器如何实现按需推送直播的的更多相关文章
- 基于EasyDarwin开源流媒体服务器框架实现EasyNVR H5无插件直播流媒体服务器方案
背景分析 在之前的一篇博客<web无插件播放RTSP摄像机方案,拒绝插件,拥抱H5!>中,描述了实现一套H5无插件直播方案的各个组件的参考建议,又在博客<EasyNVR H5流媒体服 ...
- NodeJS版本EasyDarwin开源流媒体服务器开发心得
title: Node版本EasyDarwin开发心得 date: 2018-03-27 22:46:15 tags: 年后着手Node版本EasyDarwin的开发工作,截止到今天2018年03月2 ...
- EasyDarwin开源流媒体服务器Golang版本:服务端录像功能发布
EasyDarwin开源流媒体服务器(www.easydarwin.org)现在使用Go版本实现了.最新的代码提交,已经支持了推流(或者拉流)的同时进行本地存储. 本地存储的原理,是在推流的同时启动f ...
- EasyDarwin开源流媒体服务器Golang版本:拉转推功能之拉流实现方法
EasyDarwin开源流媒体服务器(www.easydarwin.org),拉转推是一个很有意义的功能,它可将一个独立的RTSP数据源"拉"到服务器,再通过转发协议转发给多个客户 ...
- EasyDarwin开源流媒体服务器实现RTSP直播同步输出MP4、RTMP、HLS的方案思路
背景 近期跟开源团队商量,想在EasyDarwin上继续做一些功能扩展,目前EasyDarwin开源流媒体服务器只能够实现高效的RTSP推流直播转发/分发功能,输入与输出都是RTSP/RTP流,不能够 ...
- EasyDarwin开源流媒体服务器性能优化之Work-stealing优化方案
本文转自EasyDarwin开源团队成员Alex的博客:http://blog.csdn.net/cai6811376/article/details/52400226 EasyDarwin团队的Ba ...
- EasyDarwin开源流媒体服务器将select改为epoll的方法
本文来自EasyDarwin团队Fantasy(fantasy(at)easydarwin.org) 一. EasyDarwin网络模型介绍 EventContext负责监听所有网络读写事件,Even ...
- 解决用EasyDarwin开源流媒体服务器做HLS直播时Flash Player卡住的问题
最近在开发EasyDarwin开源流媒体服务器HLS直播的时候发现一个现象:在PC上用flash player播放HLS和在ios上面播放HLS时,效果明显不同,在ios上播放非常稳定,而在flash ...
- EasyDarwin开源流媒体服务器提供的TS切片/HLS直播打包库
EasyHLS Github:https://github.com/EasyDarwin/EasyHLS EasyHLS是什么? EasyHLS是EasyDarwin开源流媒体社区开发的一款HLS打 ...
随机推荐
- vue.js源码学习分享(一)
今天看了vue.js源码 发现非常不错,想一边看一遍写博客和大家分享 /** * Convert a value to a string that is actually rendered. *转换 ...
- java内部类的四大作用
一.定义 放在一个类的内部的类我们就叫内部类. 二. 作用 1.内部类可以很好的实现隐藏 一般的非内部类,是不允许有 private 与protected权限的,但内部类可以 2.内部类拥有外围类的所 ...
- Objective_C与Swift混编遇到的坑(一)
swift推出已经很长一段时间了,前段时间突然想尝试一些简单的类用swift编写于是便开始了混编的路程. 1.在oc代码里引用swift类:找了很多资料需要添加头文件格式为 #import " ...
- 第5章 Spring Boot 功能
Spring Boot 功能 本节将会介绍Spring Boot的一些细节. 在这里,您可以了解您将要使用和自定义的主要功能. 如果还没有准备好,您可能需要阅读第二部分“入门指南”和第三部分“使用 S ...
- 断路器Hystrix与Turbine集群监控-Spring Cloud学习第三天(非原创)
文章大纲 一.Hystrix基础介绍二.断路器Hystrix简单使用三.自定义Hystrix请求命令四.Hystrix的服务降级与异常处理五.Hystrix的请求缓存与请求合并六.Hystrix仪表盘 ...
- 转 Tesseract-OCR 字符识别---样本训练
转自:http://blog.csdn.net/feihu521a/article/details/8433077 Tesseract是一个开源的OCR(Optical Character Recog ...
- 转载cookie理解
本文转自https://www.cnblogs.com/dojo-lzz/p/5580301.html 服务器端像客户端发送Cookie是通过HTTP响应报文实现的,在Set-Cookie中设置需要像 ...
- 这一篇里面有很多关于scala的list的操作的好的知识
https://www.cnblogs.com/weilunhui/p/5658860.html 1.++[B] 在A元素后面追加B元素 1 2 3 4 5 6 7 8 9 10 11 12 13 ...
- Java Unsafe类
参考了这篇文章:http://blog.csdn.net/aesop_wubo/article/details/7537278 <JAVA并发编程学习笔记之Unsafe类> Unsafe开 ...
- Git安装及SSH Key管理之Windows篇
一.安装环境 1.本机系统:Windows 10 Pro(64位)2.Git版本:Git-2.11.0-64-bit.exe(64位) 二.Git安装 去官网下载完后一路下一步完成安装,如下图: ...