RTMP协议
adobe公司设计用在flash播放视频,rtmp 基于 flv流媒体传输。
flv格式分析
-
flv 格式主要是包含 flv header + body.
1. Flv header Signature(3 Byte)+Version(1 Byte)+Flags(1 Bypte)+DataOffset(4 Byte) signature 占3个字节 固定FLV三个字符作为标示。一般发现前三个字符为FLV时就认为他是flv文件。 Version 占1个字节 标示FLV的版本号。这里我们看到是1 Flags 占1个字节 内容标示。第0位和第2位,分别表示 video 与 audio 存在的情况.(1表示存在,0表示不存在)。 DataOffset 4个字节 表示FLV的header长度。这里可以看到固定是9 2. body FLV的body部分是由一系列的back-pointers + tag构成 back-pointers 固定4个字节,表示前一个tag的size。 tag 分三种类型,video、audio、scripts。 3. tag tag type+tag data size+Timestamp+TimestampExtended+stream id+ tag data type 1个字节。8为Audio,9为Video,18为scripts tag data size 3个字节。表示tag data的长度。从streamd id 后算起。 Timestreamp 3个字节。时间戳 TimestampExtended 1个字节。时间戳扩展字段 stream id 3个字节。总是0 tag data 数据部分
librtmp 测试
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "librtmp/rtmp.h"
#include "librtmp/log.h"
/*
// 这个下面的分析是 错误的,请勿参考。
// 以后有时间重新修改
rtmp 发送的是 message 结构,但是实际上设计时发送,是将message 结构分为多个chunk进行发送,每个chunk大小为128字节。
每个chunk有 chunk header + 数据 。
chunk 包最大长度为128字节,超过128的数据会分成多个包,并且这几个包头只有一个字节。
chunk Header size : 12 8 4 1
header bits 12 : header type(1 bit) | timerstamp(3 bit) | AMFsize (3 bit) | AMFtype (1 bit) | streamId (4 bit), total bits 1 + 3 + 3 + 1 + 4 = 12
header bits 8 : header type(1 bit) | timerstamp(3 bit) | AMFsize (3 bit) | AMFtype (1 bit)
header bits 4 : header type(1 bit) | timerstamp(3 bit) | AMFsize (3 bit)
header bits 1 : header type(1 bit)
总共有4种类型的包,其中 header type 前两个字节 & 0xc0 = 包头的长度,后面6位决定了channel id ,并且 streamId = (channel id - 4) / 5 + 1.
对于包头后面的数据可以分为多个类型(AMFtype):
AMFTYPE = 0x09 时,数据包含多个video tag.
关于AVCDecoderConfigurationRecord 及 AudioSpecificConfig 参考: https://blog.csdn.net/jwybobo2007/article/details/9221657
https://blog.csdn.net/chgaowei/article/details/51243345
*/
typedef struct Nalu{
char * data;
int size;
}NALU;
typedef struct protcol_rtmp{
char url[512];
RTMP * rtmp;
int push;
char * vsps;
char * vpps;
}RTMP_s;
typedef struct rtmp_buffer{
NALU nalus[10];
int type; //
int count;
}RTMP_buffer;
typedef struct flv_video_tag_header{
unsigned frame_type : 4;
unsigned codec_id : 4;
unsigned packet_type : 8;
unsigned composition_time : 24;
}VideotagHeader;
typedef struct flv_audio_tag_header{
unsigned sound_format : 4; // AAC ,pcm etc.
unsigned sound_rate : 2;
unsigned sound_size : 1;
unsigned sound_type : 1;
unsigned packet_type : 8; // sps or raw data.
}AudiotagHeader;
int rtmp_init(char * url,RTMP_s ** r)
{
int ret = 0;
RTMP_s * rtmp = NULL;
if(!url)
sprintf(stderr,"Waring url is not set \n");
if(!rtmp && r)
rtmp