Design p2p streaming capturer based on flv

0x1 Introduction

streaming capturer用于接收client端发送过来的媒体数据,client端类似于目前市面上的直播客户端,通过RTMP/RTSP协议把数据发送给streaming capturer。streaming capturer对接收到的数据进行解包,如果需要可以进行transcoding,然后把数据发送给后续的模块进行处理,这些模块可以把数据发送给其他服务器提供流媒体服务。下面介绍的p2p streaming capturer是把接收到和转码后的数据打包成P2P协议包,这些P2P协议包被发送给种子节点p2p seed node,p2p seed node提供p2p streaming的种子节点功能。播放器先连接到这个p2p seed node,获取播放所需要的媒体数据,而且后面进来的播放器可以从前面的播放器中得到部分播放数据,不需要都从p2p seed node处获取数据,从而显著地降低流媒体服务器的带宽负担。
Adobe FLV格式是一种流媒体格式,p2p streaming capturer接收到client发送过来的数据流以后,打包成FLV格式, 然后在FLV的基础上打包成P2P数据包的格式。

下面是系统架构图。
architecture

0x2 flv数据格式

下面简单介绍一下FLV数据格式。
如下所示,首先是9个byte的flv header。

0x21 The flv header

flv_header

在flv header之后,是Tag和Size交织组成的数据部分。

0x22 The flv file body

flv_file_body

0x23 flv tag

下面是flv tag数据部分。
flv_tag

0x3 基于flv的p2p streaming capturer的设计

流程图如下,

sequence

左边是p2p streaming capturer, 它与p2p seed node进行交互,p2p streaming capturer接收client发送的RTMP/RTSP数据包,经过解包/转码以后生成FLV数据,这个时候需要把FLV header和类似SPS/PPS之类的媒体类型信息保存起来,p2p streaming capturer还需要实现内部缓存buffer, 把打包好的FLV数据缓存起来,为了后面打包成P2P数据包发送给p2p seed node。
p2p streaming capturer连接上p2p seed node以后,先发送注册(Register)信息,然后发送媒体类型(MediaType)信息,MediaType包括SPS/PPS等信息,然后开始把前面缓存起来的数据按固定大小(16384)打包成P2P格式,然后发送给p2p seed node.
p2p seed node在p2p streaming capturer连接上来以后,需要把相关信息发送给tracker server,这样相当于tracker server增加了一个节目源。
播放器player可以连接到p2p seed node来得到播放数据。对于直播来说,由于player刚连接到p2p seed node的时候获取的数据可能并不是关键帧,这个时候不能立即播放,需要等待下一个关键帧的到来。为了减少播放等待时候,可以在p2p seed node上实现gop cache的功能,把最近一个关键帧开始的数据都保存到gop cache中,等播放器连接上来的时候,把gop cache中的数据发送给播放器,这样播放器就不需要等待。当有新的关键帧到来的时候,需要把gop cache中的数据清空,然后保存当前关键帧开始的数据。