Overview

Flash Video(简称FLV),是一种流行的音视频流媒体封装格式。目前国内外大部分视频分享网站都是采用的这种格式.

rtmp协议是adobe公司定制的,用于传输音视频的协议。

flv文件概述

从整个文件上开看,FLV是由The FLV header 和 The FLV File Body 组成.

1.The FLV header

Field Type Comment
Signature UI8 Signature byte always 'F' (0x46)
Signature UI8 Signature byte always 'L' (0x4C)
Signature UI8 Signature byte always 'V' (0x56)
Version UI8 File version (for example, 0x01 for FLV version 1)
TypeFlagsReserved UB [5] Shall be 0
TypeFlagsAudio UB [1] 1 = Audio tags are present
TypeFlagsReserved UB [1] Shall be 0
TypeFlagsVideo UB [1] 1 = Video tags are present
DataOffset UI32 The length of this header in bytes

Signature: FLV 文件的前3个字节为固定的‘F’‘L’‘V’,用来标识这个文件是flv格式,ffmpeg在做格式探测的时候,

如果发现前3个字节为“FLV”,就认为它是flv格式。

Version: 第4个字节表示flv版本号.

Flags: 第5个字节中的第0位和第2位,分别表示 video 与 audio 存在的情况.(1表示存在,0表示不存在)

DataOffset : 最后4个字节表示FLV header 长度.

2.The FLV File Body

Field Type Comment
PreviousTagSize0 UI32 Always 0
Tag1 FLVTAG First tag
PreviousTagSize1 UI32

Size of previous tag, including its header, in bytes. For FLV version1,

this value is 11 plus the DataSize of the previous tag.

Tag2 FLVTAG Second tag
... ... ...
PreviousTagSizeN-1 UI32 Size of second-to-last tag, including its header, in bytes.
TagN FLVTAG Last tag
PreviousTagSizeN UI32 Size of last tag, including its header, in bytes

FLV header之后,就是 FLV File Body.

FLV File Body是由一连串的back-pointers + tags构成.back-pointers就是4个字节数据,表示前一个tag的size.

FLV Tag Definition

FLV文件中的数据都是由一个个TAG组成,TAG里面的数据可能是video、audio、scripts.

下表是TAG的结构:

1.FLVTAG

Field Type Comment
Reserved UB [2] Reserved for FMS, should be 0
Filter UB [1] Indicates if packets are filtered.
0 = No pre-processing required.
1 = Pre-processing (such as decryption) of the packet is
required before it can be rendered.
Shall be 0 in unencrypted files, and 1 for encrypted tags.
See Annex F. FLV Encryption for the use of filters.
TagType UB [5]

Type of contents in this tag. The following types are
defined:
8 = audio
9 = video
18 = script data

DataSize UI24 Length of the message. Number of bytes after StreamID to
end of tag (Equal to length of the tag – 11)
Timestamp UI24 Time in milliseconds at which the data in this tag applies.
This value is relative to the first tag in the FLV file, which
always has a timestamp of 0.
TimestampExtended UI8 Extension of the Timestamp field to form a SI32 value. This
field represents the upper 8 bits, while the previous
Timestamp field represents the lower 24 bits of the time in
milliseconds.
StreamID UI24 Always 0.
AudioTagHeader IF TagType == 8
AudioTagHeader
 
VideoTagHeader IF TagType == 9
VideoTagHeader
 
EncryptionHeader IF Filter == 1
EncryptionTagHeader
 
FilterParams IF Filter == 1
FilterParams
 
Data IF TagType == 8
AUDIODATA
IF TagType == 9
VIDEODATA
IF TagType == 18
SCRIPTDATA
Data specific for each media type.

TagType: TAG中第1个字节中的前5位表示这个TAG中包含数据的类型,8 = audio,9 = video,18 = script data.

DataSize:StreamID之后的数据长度.

Timestamp和TimestampExtended组成了这个TAG 包数据的PTS信息,记得刚开始做FVL demux的时候,并没有考虑TimestampExtended的值,直接就把Timestamp默认为是PTS,后来发生的现 象就是画面有跳帧的现象,后来才仔细看了一下文档发现真正数据的PTS是PTS= Timestamp | TimestampExtended<<24.

StreamID之后的数据就是每种格式的情况不一样了,接下格式进行详细的介绍.

Audio Tags

如果TAG包中的TagType==8时,就表示这个TAG是audio。

StreamID之后的数据就表示是AudioTagHeader,AudioTagHeader结构如下:

Field Type Comment
SoundFormat UB [4] Format of SoundData. The following values are defined:
0 = Linear PCM, platform endian
1 = ADPCM
2 = MP3
3 = Linear PCM, little endian
4 = Nellymoser 16 kHz mono
5 = Nellymoser 8 kHz mono
6 = Nellymoser
7 = G.711 A-law logarithmic PCM
8 = G.711 mu-law logarithmic PCM
9 = reserved
10 = AAC
11 = Speex
14 = MP3 8 kHz
15 = Device-specific sound
Formats 7, 8, 14, and 15 are reserved.
AAC is supported in Flash Player 9,0,115,0 and higher.
Speex is supported in Flash Player 10 and higher.
SoundRate UB [2] Sampling rate. The following values are defined:
0 = 5.5 kHz
1 = 11 kHz
2 = 22 kHz
3 = 44 kHz
SoundSize UB [1]

Size of each audio sample. This parameter only pertains to
uncompressed formats. Compressed formats always decode
to 16 bits internally.
0 = 8-bit samples
1 = 16-bit samples

SoundType UB [1] Mono or stereo sound
0 = Mono sound
1 = Stereo sound
AACPacketType IF SoundFormat == 10
UI8
The following values are defined:
0 = AAC sequence header
1 = AAC raw

AudioTagHeader的头1个字节,也就是接跟着StreamID的1个字节包含着音频类型、采样率等的基本信息.表里列的十分清楚.

AudioTagHeader之后跟着的就是AUDIODATA数据了,也就是audio payload 但是这里有个特例,如果音频格式(SoundFormat)是10 = AAC,AudioTagHeader中会多出1个字节的数据AACPacketType,这个字段来表示AACAUDIODATA的类型:0 = AAC sequence header,1 = AAC raw。

Field Type Comment
Data

IF AACPacketType ==0 AudioSpecificConfig

The AudioSpecificConfig is defined in ISO14496-3. Note that this is not the same as the contents of the esds box from an MP4/F4V file.

 

ELSE IF AACPacketType == 1 Raw AAC frame data in UI8 [ ]

audio payload

AAC sequence header存放的是AudioSpecificConfig结构,该结构则在“ISO-14496-3 Audio”中描述。AudioSpecificConfig结构的描述非常复杂,这里我做一下简化,事先设定要将要编码的音频格式,其中,选择"AAC-LC"为音频编码,音频采样率为44100,于是AudioSpecificConfig简化为下表

。而且在ffmpeg中有对AudioSpecificConfig解析的函数,ff_mpeg4audio_get_config(),可以对比的看一下,理解更深刻。

AAC raw 这种包含的就是音频ES流了,也就是audio payload.

在FLV的文件中,一般情况下 AAC sequence header 这种包只出现1次,而且是第一个audio tag,为什么要提到这种tag,因为当时在做FLVdemux的时候,如果是AAC的音频,需要在每帧AAC ES流前边添加7个字节ADTS头,ADTS在ADTS音频的格式中会详细解读,这是解码器通用的格式,就是AAC的纯ES流要打包成ADTS格式的AAC文件,解码器才能正常播放.就是在打包ADST的时候,需要samplingFrequencyIndex这个信息,samplingFrequencyIndex最准确的信息是在AudioSpecificConfig中,所以就对AudioSpecificConfig进行解析并得到了samplingFrequencyIndex。

到这步你就完全可以把FLV 文件中的音频信息及数据提取出来,送给音频解码器正常播放了。

Video Tags

如果TAG包中的TagType==9时,就表示这个TAG是video.

StreamID之后的数据就表示是VideoTagHeader,VideoTagHeader结构如下:

Field Type Comment
Frame Type UB [4] Type of video frame. The following values are defined:
1 = key frame (for AVC, a seekable frame)
2 = inter frame (for AVC, a non-seekable frame)
3 = disposable inter frame (H.263 only)
4 = generated key frame (reserved for server use only)
5 = video info/command frame
CodecID UB [4] Codec Identifier. The following values are defined:
2 = Sorenson H.263
3 = Screen video
4 = On2 VP6
5 = On2 VP6 with alpha channel
6 = Screen video version 2
7 = AVC
AVCPacketType IF CodecID == 7
UI8

The following values are defined:
0 = AVC sequence header
1 = AVC NALU
2 = AVC end of sequence (lower level NALU sequence ender is not required or supported)

CompositionTime IF CodecID == 7
SI24
IF AVCPacketType == 1
Composition time offset
ELSE
0
See ISO 14496-12, 8.15.3 for an explanation of composition
times. The offset in an FLV file is always in milliseconds.

VideoTagHeader的头1个字节,也就是接跟着StreamID的1个字节包含着视频帧类型及视频CodecID最基本信息.表里列的十分清楚.

VideoTagHeader之后跟着的就是VIDEODATA数据了,也就是video payload.当然就像音频AAC一样,这里也有特例就是如果视频的格式是AVC(H.264)的话,VideoTagHeader会多出4个字节的信息.

AVCPacketType 和 CompositionTime。AVCPacketType 表示接下来 VIDEODATA (AVCVIDEOPACKET)的内容:

IF AVCPacketType == 0 AVCDecoderConfigurationRecord(AVC sequence header)
IF AVCPacketType == 1 One or more NALUs (Full frames are required)

AVCDecoderConfigurationRecord.包含着是H.264解码相关比较重要的sps和pps信息,再给AVC解码器送数据 流之前一定要把sps和pps信息送出,否则的话解码器不能正常解码。而且在解码器stop之后再次start之前,如seek、快进快退状态切换等,都 需要重新送一遍sps和pps的信息.AVCDecoderConfigurationRecord在FLV文件中一般情况也是出现1次,也就是第一个 video tag.

AVCDecoderConfigurationRecord的定义在ISO 14496-15, 5.2.4.1中,这里不在详细贴,

SCRIPTDATA

如果TAG包中的TagType==18时,就表示这个TAG是SCRIPT.

SCRIPTDATA 结构十分复杂,定义了很多格式类型,每个类型对应一种结构.

Field Type Comment
Type UI8 Type of the ScriptDataValue.
The following types are defined:
0 = Number
1 = Boolean
2 = String
3 = Object
4 = MovieClip (reserved, not supported)
5 = Null
6 = Undefined
7 = Reference
8 = ECMA array
9 = Object end marker
10 = Strict array
11 = Date
12 = Long string
ScriptDataValue IF Type == 0
DOUBLE
IF Type == 1
UI8
IF Type == 2
SCRIPTDATASTRING
IF Type == 3
SCRIPTDATAOBJECT
IF Type == 7
UI16
IF Type == 8
SCRIPTDATAECMAARRAY
IF Type == 10
SCRIPTDATASTRICTARRAY
IF Type == 11
SCRIPTDATADATE
IF Type == 12
SCRIPTDATALONGSTRING
Script data value.
The Boolean value is (ScriptDataValue ≠ 0).

类型在FLV的官方文档中都有详细介绍.

onMetaData

onMetaData 是SCRIPTDATA中对我们来说十分重要的信息,结构如下表:

Property Name Type Comment
audiocodecid Number Audio codec ID used in the file (see E.4.2.1 for available SoundFormat values)
audiodatarate Number Audio bit rate in kilobits per second
audiodelay Number Delay introduced by the audio codec in seconds
audiosamplerate Number Frequency at which the audio stream is replayed
audiosamplesize Number Resolution of a single audio sample
canSeekToEnd Boolean Indicating the last video frame is a key frame
creationdate String Creation date and time
duration Number Total duration of the file in seconds
filesize Number Total size of the file in bytes
framerate Number Number of frames per second
height Number Height of the video in pixels
stereo Boolean Indicating stereo audio
videocodecid Number Video codec ID used in the file (see E.4.3.1 for available CodecID values)
videodatarate Number Video bit rate in kilobits per second
width Number Width of the video in pixels

这里面的duration、filesize、视频的width、height等这些信息对我们来说很有用.

keyframes

当时在做flv demux的时候,发现官方的文档中并没有对keyframes index做描述,但是flv的这种结构每个tag又不像TS有同步头,如果没有keyframes index 的话,seek及快进快退的效果会非常差,因为需要一个tag一个tag的顺序读取。后来通过网络查一些资料,发现了一个keyframes的信息藏在SCRIPTDATA中。

keyframes几乎是一个非官方的标准,也就是民间标准.在网上已经很 难看到flv文件格式,但是metadata里面不包含 keyframes项目的视频 . 两个常用的操作metadata的工具是flvtool2和FLVMDI,都是把keyframes作为一个默认的元信息项目.在FLVMDI的主页 (http://www.buraks.com/flvmdi/)上有描述:

keyframes: (Object) This object is added only if you specify the /k switch. 'keyframes' is known to FLVMDI and if /k switch is not specified, 'keyframes' object will be deleted.
'keyframes' object has 2 arrays: 'filepositions' and 'times'. Both arrays have the same number of elements, which is equal to the number of key frames in the FLV. Values in times array are in 'seconds'. Each correspond to the timestamp of the n'th key frame. Values in filepositions array are in 'bytes'. Each correspond to the fileposition of the nth key frame video tag (which starts with byte tag type 9).

也就是说keyframes中包含着2个内容 'filepositions' and 'times'分别指的是关键帧的文件位置和关键帧的PTS.通过keyframes可以建立起自己的Index,然后再seek和快进快退的操作中,快速有效的跳转到你想要找的关键帧的位置进行处理。

rtmp协议发送mp3和aac裸流的方法相关推荐

  1. C++实现RTMP协议发送H.264编码及AAC编码的音视频

    C++实现RTMP协议发送H.264编码及AAC编码的音视频 RTMP(Real Time Messaging Protocol)是专门用来传输音视频数据的流媒体协议,最初由Macromedia 公司 ...

  2. RTMP协议发送H.264编码及AAC编码的音视频,实现摄像头直播

    RTMP协议发送H.264编码及AAC编码的音视频,实现摄像头直播 摘要: RTMP协议发送H.264编码及AAC编码的音视频,实现摄像头直播 RTMP(Real Time Messaging Pro ...

  3. java rtp 分片_RTP 协议解包为 H264 裸流

    RTP 协议解包为 H264裸流 一. 为什么使用 RTP 协议? TCP 传输流媒体数据由于其可靠性,会造成很大的网络延时和卡顿. UDP 传输由于其不可靠性,会导致丢帧,如果是关键帧,则会花屏一个 ...

  4. 音视频开发 RTMP协议发送H.264编码及AAC编码的音视频(C++实现)

    RTMP(Real Time Messaging Protocol)是专门用来传输音视频数据的流媒体协议,最初由Macromedia 公司创建,后来归Adobe公司所有,是一种私有协议,主要用来联系F ...

  5. 实现RTMP协议发送H.264编码及AAC编码的音视频

    RTMP(Real Time Messaging Protocol)是专门用来传输音视频数据的流媒体协议,最初由Macromedia 公司创建,后来归Adobe公司所有,是一种私有协议,主要用来联系F ...

  6. RTMP协议详解及实例分析

    1.简介 RTMP协议是Real Time Message Protocol(实时信息传输协议)的缩写,它是由Adobe公司提出的一种应用层的协议,用来解决多媒体数据传输流的多路复用(Multiple ...

  7. 使用 ortp 发送原始 H.264 码流

    oRTP 是一个 RTP (Real-time Transport Protocol (RFC 3550)) 协议的库实现,它完全以 C 语言来实现,因此方便应用于各种不同的平台.本文分享用 oRTP ...

  8. 通过 wireshark 抓包了解直播流媒体 RTMP 协议基本过程

    作者:Elias Zhang 声网资深工程师,拥有从Iaas层的基础信息存储服务到paas层的云服务的职业经历,喜欢python语言,习惯使用C#,熟悉基于和结合CDN的业务产品架构,点播.直播.云导 ...

  9. android 使用MediaCodec(根据设备状况硬编解码)来转码音频(MP3 to aac),并同时裁剪音频

    第一次写这样的博文,写得不好,望大家及时指出博文中的错误,以便于相互学习. 本来主要介绍如何使用mediacodec来转码音频,同时实现音频的裁剪.对于mediacodec相信大家都不陌生,没做过也听 ...

  10. C# WinForm 使用SMTP协议发送QQ邮箱验证码

    文章目录 前言 功能实现步骤 一.获取QQ邮箱授权码 二.功能界面 三.创建发送邮箱验证码的类 四.在From1中调用类中的函数,实现功能 前言   在程序设计中,发送验证码是常见的一个功能,用户在注 ...

最新文章

  1. java面向对象(包package)
  2. Sharepoint学习笔记—ECMAScript对象模型系列-- 7、获取和修改List的Lookup字段
  3. #pragma comment和#pragma 预处理指令详解
  4. 一个亿万富翁和一个陌生人的换钱计划
  5. 计算机课教学要求,《计算机基础课程教学基本要求》研制报告
  6. java中while循环练习,java练习 七、循环语句 do……while循环语句
  7. python logging详解及自动添加上下文信息
  8. python编程单词排序_Python编程20:字典的遍历和排序
  9. Python_模块_Day_
  10. 列举计算机组装所需的各个硬件,计算机组装和维修期中考试.doc
  11. android 模拟器 电脑配置,手游安卓模拟器多开对电脑配置要求与占用浅谈
  12. C语言入门之鸡兔同笼(简易版)
  13. html 图片浮层,纯css图片悬浮代码(expression)
  14. python 线性插值处理_详解Python实现线性插值法
  15. 00:编程入门--了解计算机
  16. 京东平台和商家的不同合作模式
  17. 2022数学建模国赛B题思路分析
  18. 无法创建文件夹或文件问题的解决的方法
  19. linux 字符串数组初始化,Linux命令行 – 数组
  20. 开发者举报:“除了每年收我的钱,苹果似乎什么都不想做”

热门文章

  1. 心得-计算机软考之嵌入式系统工程师
  2. IPD解读--华为500强的研发第一名,除了钱还有IPD
  3. AUTOSAR Network Wakeup(Can) Configuration
  4. HTML前端连接go语言后段,一次完整的浏览器请求响应过程-Go语言中文社区
  5. 联想台式计算机设置u盘启动不了,联想扬天M4000e台式电脑bios设置U盘启动图文方法...
  6. Laravel 生成QRCODE
  7. 北京中国科学院计算机专业怎么样,中国科学院北京计算技术研究所计算机技术怎么样...
  8. MongoTemplate根据时间查询的大坑
  9. 冉宝的每日一题-8月15日-- 拓扑排序。
  10. freemarker导出excel单元格内换行