RTMP推流详解

@Daniate  August 14, 2022

本文首发于Daniate的个人网站,文章链接:https://daniate.com/archives/300/

参考资料:

  • Adobe Flash Video File Format Specification Version 10.1
  • ISO/IEC 14496-3 Second edition 2001(Information technology — Coding of audio-visual objects — Part 3: Audio)
  • ISO/IEC 14496-15 Second edition 2010(Information technology — Coding of audio-visual objects — Part 15: Advanced Video Coding (AVC) file format)
  • ITU-T H.264(01/2012)(Advanced video coding for generic audiovisual services)

RTMP推流,需要以FLV Tag发送数据。

发送 script data

如果要发送,必须在发送音视频数据之前进行发送;但也可以完全不发送。

16501185018892.jpg

script data里面必须有onMetadata,但并不是所有的属性都需要发送,可以选择性地发送其中的几个,比如,只发送audiocodecidvideocodecidheightwidth

发送音频数据

发送 AAC sequence header

必须在发送AAC raw之前进行发送。

AudioTagHeader

其结构如下:

4位的SoundFormat,用10代表AAC
2位的SoundRate,用3代表44100Hz
1位的SoundSize,对于压缩格式(AAC属于压缩格式),用1代表16位的采样大小
1位的SoundType0代表单声道;1代表立体声;
8位的AACPacketType,用0代表AAC sequence header

16501197162416.jpg

另,根据上图中的文字信息,可以得出,这2个字节固定为:

0xAF0x00

解析如下:

16501204254395.jpg

4位的SoundFormat,取10,二进制就是1010
2位的SoundRate,取3,二进制就是11
1位的SoundSize,取1,二进制就是1
1位的SoundType,取1,二进制就是1

它们正好是1字节,也就是0xAF。

后面的1字节AACPacketType,是0x00。

AudioTagBody

对于AAC sequence header,其AudioTagBody就是AudioSpecificConfig

16501195591550.jpg

AudioSpecificConfig

audioObjectType

16501208896938.jpg

samplingFrequencyIndex

16501210272235.jpg

因为发送的是AACsamplingFrequencyIndex不会取0xf,因此,忽略占24位的samplingFrequency

channelConfiguration

16501214007515.jpg

GASpecificConfig

16501224239765.jpg

16501223707348.jpg

上图中标记为红色的字段,都取0。

计算AudioSpecificConfig

5位audioObjectType,
4位samplingFrequencyIndex,
4位channelConfiguration,
3位GASpecificConfig

16501239290327.jpg

总共2个字节,计算公式如下:

bytes[0] = ((audioObjectType & 0x1F) << 3) | ((samplingFrequencyIndex & 0x0F) >> 1))
bytes[1] = ((samplingFrequencyIndex & 0x01) << 7) | ((channelConfiguration & 0x0F) << 3) | GASpecificConfig

因为GASpecificConfig都是0,因此:

bytes[0] = ((audioObjectType & 0x1F) << 3) | ((samplingFrequencyIndex & 0x0F) >> 1))
bytes[1] = ((samplingFrequencyIndex & 0x01) << 7) | ((channelConfiguration & 0x0F) << 3)

发送 AAC raw

AudioTagHeader

其结构如下:

4位的SoundFormat,用10代表AAC
2位的SoundRate,用3代表44100Hz
1位的SoundSize,对于压缩格式(AAC属于压缩格式),用1代表16位的采样大小
1位的SoundType0代表单声道;1代表立体声;
8位的AACPacketType,用1代表AAC raw

16501197162416.jpg

另,根据上图中的文字信息,可以得出,这2个字节的数据,固定为:

0xAF0x01

AudioTagBody

也即Raw AAC frame data

发送视频数据

发送 AVC sequence header

VideoTagHeader

4位的Frame Type,用1代表关键帧(针对的是AVC,也就是H.264)
4位的CodecID,用7代表AVC
8位的AVCPacketType,用0代表AVC sequence header
24位的CompositionTime,取0

因此,这5个字节固定如下:

byte[0] = 0x17
byte[1] = 0x00;
byte[2] = 0x00;
byte[3] = 0x00;
byte[4] = 0x00;

VideoTagBody

对于AVC sequence header,其VideoTagBody就是AVCDecoderConfigurationRecord

AVCDecoderConfigurationRecord

16501671529588.jpg

16501841859406.jpg

16501844303302.jpg

计算AVCDecoderConfigurationRecord

16501826380761.jpg

发送 AVC NALU

VideoTagHeader

4位的Frame Type,用1代表关键帧,用2代表非关键帧(这两个值,针对的是AVC,也就是H.264)
4位的CodecID,用7代表AVC
8位的AVCPacketType,用1代表AVC NALU
24位的CompositionTime,取0

因此,这5个字节的计算公式如下:

byte[0] = ((FrameType & 0x0F) << 4) | (CodecID & 0x0F)
byte[1] = 0x01;
byte[2] = 0x00;
byte[3] = 0x00;
byte[4] = 0x00;

byte[0]要么是0x17,要么是0x27

VideoTagBody

对于AVC NALU,其VideoTagBody就是One or more NALUs (Full frames are required),每个NALU的最前面,不需要Start Code,但需要加上NumBytesInNALunit(也就是NALU的长度)

知识共享许可协议
本作品由Daniate采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。


评论已关闭