对于并发量并不大而且对性能要求不是很高的流媒体传输模块,live555还是很好的选择,下面说一下我所实现的流媒体代理服务器(目前只能实现对H264单视频的转发)代理转发主要

对于并发量并不大而且对性能要求不是很高的流媒体传输模块,live555还是很好的选择,下面说一下我所实现的流媒体代理服务器(目前只能实现对H264单视频的转发)

代理转发主要分为对RTSP的转发与对RTP的转发(没有实现对rtcp的转发),尽量做到不破坏原有程序框架,所以还是要将整个代理过程融合于ServerMediaSubsession、Source、Sink的循环中,按照流程,RTSP OPTIONS不是必需进行转发,直接转到DESCRIBE的转发过程。

DECRIBE转发:在看过很多大型的流媒体服务器协议以后,会发现有一个相同点:前端设备在注册到流媒体服务器以后会将其自身的无论是实时资源还是录像资源都上报到流媒体服务器中集中管理,那么此处同理,在流媒体服务器上线(主动注册与保活)后改为主动向前端请求资源,到此处也就是发送DESCRIBE请求,我实现的代理服务器中,专门定义了一个类,继承自RTSPClient,向前端设备发送DESCRIBE请求,成功接收到携带SDP信息的反馈以后,根据SDP信息生成MediaSession,再执行其中每一个MediaSubsession的initiate(),这样获取由前端发送来数据的Source就已经准备就绪,同时,在每一个MediaSubsession建立以后,在对应流的ServerMediaSession中加入ServerMediaSubsession(此处ServerMediaSubsession继承自OnDemandServerMediaSubsession),这样就做到了一个ServerMediaSubsession对应一个MediaSubsession(这里一定要区分ServerMediaSubsession与MediaSubsession),两路会话的连接,下面就是客户端发起了DESCRIBE请求,转到RTSPServer::RTSPClientSession::handleCmd_DESCRIBE(),再转到ServerMediaSession::generateSDPDescription(),因为是转发,而且不能让客户端知道是转发,所以sdp信息在m字段前面的参数都是基于代理服务器本身,从m开始便是真正的媒体信息,原有的live555结构中,获取每一个track的sdpLine是由virtual char const* OnDemandServerMediaSubsession::sdpLines();得到,于是,我们可以重写此virtual函数,返回什么呢,返回的就是我们刚才传入的MediaSubsession的savedSDPLines()返回值。这样,SDP信息就可以在不破坏原有live555循环的基础上构造出来,并实现转发了。

SETUP转发:同DESCRIBE一样,原有框架已经形成,在收到SETUP请求以后,找RTSPServer::RTSPClientSession::handleCmd_SETUP(),再找到virtual void OnDemandServerMediaSubsession::getStreamParameters(),在原有live555循环中,此函数作用为建立本地接收端口,建立createNewSource与createNewSink,将数据传输循环中的各个部件都准备妥当,一旦收到Play命令就开始循环工作,那么同样重写此virtual函数,在重写中实现向前端发送SETUP请求,等待响应成功,再执行本地的SETUP,向前端发送SETUP实现可以同样由刚才传入的"RTSPClient继承"与MediaSubsession来实现发送命令,等待返回,再继续执行OnDemandServerMediaSubsession::getStreamParameters()实现本地的SETUP,如此一来,本地与远程的SETUP都已完成。

PLAY转发:同样,按照流程,重写OnDemandServerMediaSubsession::startStream()函数,发送Play请求到远程,等待返回,再执行本地的startStream(),本地与远程的Play都已完成。

上面已经将RTSP的转发实现,而且基本是在live555原有基础上进行,没有破坏原有框架结构,下面进行rtp的转发。

rtp的转发实现的重点是在建立source到sink的循环,重写OnDemandServerMediaSubsession::createNewStreamSource,与OnDemandServerMediaSubsession::createNewRTPSink,理想中的转发是能够实现收到rtp包不进行任何重组,直接发送即可,但我所实现的只能是由MediaSubsession中的readSource获取完整的一帧后,再交给rtpSink进行重新切片组装,具体到实现上,我实现了一个集成自H264VideoStreamFramer的类,并将MediaSubsession->readSource作为inputSource传入,重写doGetNextFrame(),从inputSource中获取完整一帧,copy到fTo,再交由createNewRTPSink()返回的H264VideoRTPSink进行重新组装并发送,后来考虑到此种做法,有利有弊,与不重新组装,直接发送,各有考虑。

如此,便实现了RTSP与RTP的转发功能,多有不妥,后续会持续改进,还望能够在留言中多多指正!

2012.3.23

有朋友问到rtcp的转发问题,这里阐述下我的理解:

转发RTCP实际的意义并不是很大,一个方面是rtcp控制的可能是两条不通的数据链路,对拥堵的控制总是在较小的链路基础上,牺牲太大;第二是作为服务器考虑,服务器通过双重身份将数据取来再发出去,控制协调应当完全自主掌控,如果后期在服务器中加入缓存机制实现抖动控制和拥堵控制,可以通过对进线与出线的rtcp控制达到控制作用,而且效果较好!

转自:http://www.easydarwin.org/article/Streaming/1.html

(转)基于live555的流媒体代理转发服务器的更多相关文章

  1. Node.js做的代理转发服务器

    可以代理苹果ID服务器 const http = require('http'); const https = require('https'); const client = require('ht ...

  2. Nginx实现ssl一级、二级域名证书部署并用https访问代理转发服务器

    1.  规划 域名 解析IP Nginx代理 htpps://www.devcult.com 47.88.10.155   htpps://auto.devcult.com 47.88.10.155 ...

  3. 基于live555的一个简单RTSP服务器

    1,编译live555源码目录下的 BasicUsageEnvironment.groupsock.liveMedia.UsageEnvironment四个工程生成相应的库文件: 目录结构如下: 2, ...

  4. 用live555做流媒体转发服务器?

    当我们看到这里,说明大家都有这样的一个想法:那就是如何用live555实现一个直播代理转发的流媒体服务器? 我们先不着急去讨论用live555实现流媒体转发的技术方法123,先从live555的整个架 ...

  5. 基于go手动写个转发代理服务

    由于公司经常需要异地办公,在调试的时候需要用到内网环境,因此手动写了个代理转发服务器給兄弟们用:socks5proxy. 选型上,语言上就选择了Go,简单清晰,转发协议选择了socks5. SOCKS ...

  6. 嵌入式流媒体音视频服务器EasyIPCamera中live555发送性能优化点

    EasyIPCamera流媒体服务器 今年EasyDarwin团队在给国内某最大的金融安防公司做技术咨询的时候,开发了一款适用于嵌入式IPCamera.NVR的RTSP流媒体服务器:EasyIPCam ...

  7. 基于Qt实现的TCP端口数据转发服务器

    对于Qt,比较喜欢qt的sdk框架,我也是用于做一些工作中用到的工具软件,基于qt的sdk做起来也比较快: 一.概述 今天要说的这个tcp端口转发服务器,主要是用于将监听端口的数据转发到另外一个服务器 ...

  8. 基于Java Mina 通信框架的JT/T809转发服务器设计

    Apache MINA 是 Apache 组织的一个开源项目,为开发高性能和高可用性的网络应用程序提供了非常便利的框架. 也是Java开发者的一个福利(.NET目前还没有类似封装的这么好的基础sock ...

  9. 基于 Red5 的流媒体服务器的搭建和应用

    http://www.ibm.com/developerworks/cn/opensource/os-cn-Red5/ Red5 是一个采用 Java 开发的开源免费 Flash 流媒体服务器.Red ...

随机推荐

  1. (转)C#中的Predicate<T>与Func<T, bool>

    Delegate至少0个参数,至多32个参数,可以无返回值,也可以指定返回值类型.这个是祖宗.  Func可以接受0个至16个传入参数,必须具有返回值.  Action可以接受0个至16个传入参数,无 ...

  2. git 录制简单实用好工具 LICEcap

    官网 https://www.cockos.com/licecap/ 界面如图: 录制效果如下:

  3. ThreadLocal 类说明

    1 ThreadLocal 不是一个线程,而是保存线程本地化对象的容器.当运行于多线程环境的某个对象使用 ThreadLocal 维护变量时,ThreadLocal 为每一个使用该变量的线程分配一个独 ...

  4. Lua脚本语言快速入门手册

    学了两天Lua语言,感叹其短小精悍,上手极快,语法还很舒服,不错!整理下学习过程中经常用到的基础知识,共勉! Lua用法简述 Lua语言是在1993年由巴西一个大学研究小组发明,其设计目标是作为嵌入式 ...

  5. 简单的图形学(二)——材质与反射

    在上一篇[游戏框架系列]简单的图形学(一)文章中,我们讲述了光线追踪的一个最简单的操作--依每个像素延伸出一条追踪光线,光线打到球上(产生交点),就算出这条线的长度,作为最终的灰度,打不到球上,就显示 ...

  6. java.net.SocketException: Software caused connection abort: socket write erro

    场景:接口测试 编辑器:eclipse 版本:Version: 2018-09 (4.9.0) testng版本:TestNG version 6.14.0 执行testng.xml时报错信息: 出现 ...

  7. 在IIS6上部署WebService

    在IIS6上部署WebService 2016-12-07 目录: 1 创建web service项目2 部署WebService3 浏览页面 1 创建web service项目 返回 用Visual ...

  8. echarts报错Cannot read property 'features' of undefined

    引入地图的时候 echarts2报错: Uncaught Error: [MODULE_MISS]"echarts/src/util/mapData/params" is not ...

  9. sqlserver判断是否为数字的函数

    ISNUMERIC 确定表达式是否为一个有效的数字类型. 语法  ISNUMERIC ( expression ) 参数 expression 要计算的表达式. 返回类型 int 测试: select ...

  10. get_class_vars

    个人理解:感觉就是一个将类里的属性值转换为数组的一个东西. <?php class myclass { var $var1; // 此变量没有默认值…… var $var2 = "xy ...