直播后台浅谈

引言



直播后台包括信令服务及流媒体服务。信令服务主要接收外部业务请求,进而控制流媒体的行为(包括创建/停止频道、转码、录制等),本文主要讨论流媒体的工作原理。



一、目的
很容易想到的是数据分发功能,解决观看带宽问题。但实际上还包括了一系列的可扩展功能,比如后台统一转码,视频录制以及流状态控制(外部审核)。



二、RTMP(直播后台核心逻辑)
直播采用的是RTMP协议进行传输数据,不仅包括客户端与服务端之间音视频传输(直播/观看),也包括服务端各节点之间数据的传输。按照实际使用经验,RMTP直播效果优于hls、http/flv,延迟在1-2秒左右。

RTMP包含一系统AMF命令:
发布方:(connect->createstream->publish)




观看方:(connect->play->onmetadata)




对于发布方/观看方来讲,RTMP层的业务握手完成后,会发送AMF命令与服务端进行交互,最终再传输音、视频数据。




三、与信令服务通信
流媒体运转过程中,避免不了与外界信令服务器进行通信,通过信令服务器发送自定义TLV指令,来控制整个直播过程。与信令服务器通信包含主动发送请求(作为tcp_client)及被动接收请求(作为tcp_server)。

主动发送请求:
流媒体作为tcp_client,可以使用nginx中的ngx_peer_connection_t实现,peer_connection_t作为主动连接与外部建连。
        pc = ngx_pcalloc(pool, sizeof(ngx_peer_connection_t));
        if (pc == NULL) {
            goto error;
        }
                //设置连接参数
        ...
        rc = ngx_event_connect_peer(pc);
        if (rc != NGX_OK && rc != NGX_AGAIN ) {
            ngx_log_debug0(NGX_LOG_DEBUG_CORE, log, 0, "netcall: connection failed");
            goto error;
        }

被动接收请求:
流媒体作为tcp_server,需要开启一个自定义端口监听外部请求。借助开源nginx_tcp_proxy_module模块,通过代理请求到自定义的ngx_tcp_protocol_t实现。
        ngx_tcp_process_session(ngx_connection_t *c)
        {
            ....
            cscf->protocol->init_session(s);
        }

epoll:
流媒体后台IO的读写是基于epoll事件驱动方式。鉴于此,tcp_server、tcp_client也采用此方式,开发中实际就是处理事件的回调函数.读写事件的触发交由epoll去实现,降低了开发成本,并且epoll处理高并发连接的效率很高,适合直播这种场景。
    struct ngx_event_s {
           ....
           ngx_event_handler_pt  handler;
    }



四、数据流转
流媒体数据流转顺序:
client推流至publisher,publisher分发至dispatcher,再由dispatcher转发至叶子节点,提供给客户端进行观看。client->publisher->dispatcher->edge->client

转码流转顺序:
client推流至publisher,publisher分发至transcoder转码,再由dispatcher转发至叶子节点,提供给客户端进行观看。client->publisher->transcoder->dispatcher->edge->client

简要流程图:







五、缓存GOP
一个GOP包含一组视频帧(I、B、P、B、B、P、B帧),只有I帧可以独立解码,所以如果服务端第一帧发送的是B或者P帧,则客户端会出现黑屏。缓存GOP实际主要是解决保证客户端收到的第一帧为I。这里需要注意的一点是缓存的是一组GOP,即当前所属的GOP,而非一个I帧,单独一个I帧,一样会造成显示模糊,卡顿。

其它注意点:
1.发送I帧前还需要发送sps帧,sps包含编码所用的profile,图像的宽和高等信息。如果不发送,则视频不会显示。
2.视频帧的timestamp设置:与缓存flv的视频帧不同,rtmp视频帧timestamp不能设置成0。SPS帧可设置成0,其它帧以相对时间为准。




六、监控
监控流量不可避免,此处把进出带宽打印下来,对于定位问题有很大帮助。可以实时查看收发包的流量信息。




猜你喜欢

转载自beck5859509.iteye.com/blog/2371299