• EasyDarwin开源流媒体服务器Golang版本:拉转推功能之拉流实现方法


    EasyDarwin开源流媒体服务器(www.easydarwin.org),拉转推是一个很有意义的功能,它可将一个独立的RTSP数据源“拉”到服务器,再通过转发协议转发给多个客户端,或者通过EasyDarwin的本地存储功能进行存储。国内大多摄像机都支持RTSP协议,通过拉转推可将第三方摄像机接入到EasyDarwin服务器。


    IPCEasyDarwin第三方RTSP源本地存储Client1Client2Client3拉流拉流ffmpeg转发转发转发IPCEasyDarwin第三方RTSP源本地存储Client1Client2Client3

    拉转推需要服务器不仅实现服务端,还要实现客户端。这里我们介绍下拉流功能的实现。

    RTSP的客户端拉流流程为:

    1. 发送RTSP命令
    2. 接收RTP媒体流

    发送RTSP命令,又有如下几步:

    • OPTIONS 获取Server端支持的REQUEST请求集合
    • DESCRIBE 获取码流的SDP
    • SETUP 根据SDP信息,配置单个媒体流的传输方式
    • PLAY 启动播放

    我们结合代码分析下拉流是如何实现的。RTSP的拉流实现在rtsp-client.go文件里,我们定义了一个结构体RTSPClient,实现了两个方法StartStop
    Start接口,开始拉流

    在Start函数里面,主要有两部分,RTSP命令交互部分,即requestStream和媒体流收发部分,即stream
    先看requestStream

    • 解析URL的host和port,建立TCP链接,准备进行命令交互
      EasyDarwin开源流媒体服务器
    • 发送OPTION和DESCRIBE请求,这里的Request接口,是封装的一个进行RTSP命令交互的接口,该接口发送报文,并接受响应,解析响应信息。返回值分别是RTSP的响应和错误。在代码里,每一个请求都判断了错误,如果错误了则直接返回。
      EasyDarwin开源流媒体服务器
    • 解析DESCRIBE返回的SDP信息,并针对每一个Stream,发送SETUP命令。这里使用了开源的SDP解析类go-sdp来解析SDP,其地址为https://github.com/pixelbender/go-sdp 在代码可以看出SDP解析出来后,遍历每一个stream,如果是video或者audio那就分别发送SETUP信息
      EasyDarwin开源流媒体服务器
    • 发送PLAY命令,向服务器端申请流
      EasyDarwin开源流媒体服务器
      发送了PLAY命令后,requestStream结束,然后整个流程进入stream部分.
      stream部分主要是持续接收媒体流或者Server端发来的RTSP命令报文(包括请求和响应),必要的情况下再发送心跳包给服务器。
    1. 初始化,这里根据OptionIntervalMillis参数是否大于0来判断是否需要发送心跳包给服务器端。如果需要,那以该值为周期,定期发送OPTIONS请求。注意这里的OPTIONS不能阻塞接收响应,这是因为此刻服务器端也在不断地发送着RTP数据,这种情况下阻塞接受响应的话,可能会受到RTP数据。响应报文由后续的持续接收数据部分进行处理。
      EasyDarwin开源流媒体服务器
    2. 接收RTP数据。根据RTP数据格式,我们先读一个字节的头,如果这个头的值为0x24,则其为RTP数据。否则就是RTSP命令数据。对于RTP数据,接下来我们的工作,就是将其完全接收,然后放到队列里面。
      EasyDarwin开源流媒体服务器
    3. 这里是RTP包的解析过程,可以看到,首先收取一个包的长度,然后根据这个长度,接收完成所有的一整包。再去解析包的内容,最后将包回调出去。RTP包有四种类型,VIDEO、AUDIO、VIDEOCONTROL、AUDIOCONTROL,这些类型通过channel来区分开来。channel是在SETUP的时候指定的。
      EasyDarwin开源流媒体服务器
    4. 非RTP数据包的接收,就比较简单了。由于RTSP是文本协议,逐行读取文本,直到读出一个长度为0的行。同时判断是否包括Content-Length?如果有的话,再读取Content-Length长度的数据包。否则接收完成。完全接收到一个整包后,这里单纯打印出来,不做后续操作。但是我们还是要把它完全接收,不然会导致数据包的解析完全乱套。
      EasyDarwin开源流媒体服务器

    接收到的RTP数据包,我们在这里仅仅将其回调给上层处理。上层要维护一个队列,并将RTP数据包入队了。当有Client连接时,从队列里面去除RTP包,分发给Client,便实现了拉流转发功能。

    资源链接

    EasyDarwin官网:www.easydarwin.org
    EasyDarwin Github:https://github.com/easydarwin

  • 相关阅读:
    大文件上传
    http协议
    memcache通过hash取模算法,实现多服务器存取值
    页面静态化案例---一键生成详情页面静态化(全站静态化+局部动态)
    页面静态化案例---一键生成详情页面静态化(全站静态化)
    页面静态化案例---数据列表静态化
    LCD1602液晶显示模块的单片机驱动深入详解之硬件篇
    ANDROID开发之GC_CONCURRENT freed
    ANDROID开发之OOM:一张图片(BitMap)占用内存的计算 图片内存优化
    ANDROID开发 Fatal signal 11(SIGSEGV) at 0x问题解决方案
  • 原文地址:https://www.cnblogs.com/babosa/p/10459850.html
Copyright © 2020-2023  润新知