Skip to content

Instantly share code, notes, and snippets.

@Akagi201
Last active March 2, 2023 10:59
Show Gist options
  • Save Akagi201/32a7e9ff29c479ec8f07 to your computer and use it in GitHub Desktop.
Save Akagi201/32a7e9ff29c479ec8f07 to your computer and use it in GitHub Desktop.

adobe 官方标准

  • F4V/FLV file format (其中, Annex E 为 FLV File Format)
  • 有一些 box 是 Adobe 自定义的, 其他的 box 是标准 ISO/IEC 14496-12:2008 (MPEG-4 Part 12) 定义的.
  • F4V 几乎跟 MP4 一样(通常修改文件名为 .mp4 也能播放).
  • FLV 是 Adobe Flash Video 的旧的标准.
  • FLV, F4V, MP4都可以包含 H.264 编码的视频.

FLV文件格式解析

  • 存储多字节数字用大端序.
  • FLV 文件由 FLV header (E.2) 和 FLV File Body (E.3) 组成.
  • FLV File Body 有许多 FLV Tag(E.4.1) 组成.
  • FLV Tag 包含 audio, video, scripts 或者 encryption(可选) 的 metadata 和 payload.

单位说明

UI8 = uint8_t
SI8 = int8_t
UB = a bit in uint8_t

The FLV header + FlV Body (E.2, E.3)

${FLV header}
|-- Signature         UI8   签名, 总是 'F' (0x46)
|-- Signature         UI8   签名, 总是 'L' (0x4C)
|-- Signature         UI8   签名, 总是 'V' (0x56)
|-- Version           UI8   版本, 总是 0x01, 表示 FLV version 1
|-- TypeFlagsReserved UB[5] 全 0
|-- TypeFlagsAudio    UB[1] 1 = 有音频
|-- TypeFlagsReserved UB[1] 全 0
|-- TypeFlagsVideo    UB[1] 1 = 有视频
|-- DataOffset        UI32  整个文件头长度, 总是 9
|
${FLVFile Body}
|
|-- PreviousTagSize0   UI32     总是0
|-- Tag1               FLVTAG   第一个 tag
|-- PreviousTagSize1   UI32     前一个 tag 的大小, 包括他的 header, 即: 11 + 前一个 tag 的大小
|-- Tag2               FLVTAG   第二个 tag
...
|-- PreviousTagSizeN-1 UI32
|-- TagN               FLVTAG   最后一个 tag
|-- PreviousTagSizeN   UI32     最后一个 tag 的大小, 包括他的 header

FLV Tag (E.4)

${FLVTAG}
|-- Reserved           UB[2]    保留给FMS, 为 0
|-- Filter             UB[1]    0 = unencrypted tags, 1 = encrypted tags
|-- TagType            UB[5]    类型, 8 = audio, 9 = video, 18 = script data
|-- DataSize           UI24     message 长度, 从 StreamID 到 tag 结束(len(tag) - 11)
|-- Timestamp          UI24     相对于第一个 tag 的时间戳(unit: ms), 第一个 tag 总是 0
|-- TimestampExtended  UI8      Timestamp 的高 8 位. 扩展 Timestamp 为 SI32 类型
|-- StreamID           UI24     总是 0, 至此为 11 bytes
|
|
|-- 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

AudioTag

这里, 只说明了 AAC 编码的文件格式.

${AudioTagHeader}
|-- SoundFormat     UB[4]  音频编码格式
|-- SoundRate       UB[2]  采样率
|-- SoundSize       UB[1]  采样大小
|-- SoundType       UB[1]  音频声道数
|-- AACPacketType IF SoundFormat == 10
|                    UI8    0 = AAC sequence header, 1 = AAC raw
|
${AACAUDIODATA}
|-- Data   IF AACPacketType == 0
              AudioSpecificConfig
           ELSE IF AACPacketType == 1
              Raw AAC frame data in UI8[n] // n = [AAC Raw data length] - ([has CRC] ? 9 : 7)
// 长度为 UI16
${AudioSpecificConfig}
├── AudioObjectType        UB[5]
├── SamplingFrequencyIndex UB[4]
├── ChannelConfiguration   UB[4]
└── ${GASpecificConfig}
    ├── FrameLengthFlag     UB[1]
    ├── DependsOnCoreCoder  UB[1]
    └── ExtensionFlag       UB[1]

VideoTag

这里, 只说明了 AVC 编码的文件格式.

${VideoTagHeader}
|-- FrameType       UB[4]
|-- CodecID         UB[4]  CodecID == 7
|-- AVCPacketType   UI8
|-- CompositionTime SI24
|
${VideoTagBody}
|-- VideoTagBody      AVCVIDEOPACKET
|
${AVCVIDEOPACKET}
|-- Data           IF AVCPacketType == 0
                      AVCDecoderConfigurationRecord
                   IF AVCPacketType == 1
                      One or more NALUs (Full frames are required)
// 长度为 sizeof(UI8) * (11 + sps_size + pps_size)
${AVCDecoderConfigurationRecord}
├── ConfigurationVersion          UI8     // 1
├── AVCProfileIndication          UI8     // sps[1]
├── ProfileCompatibility          UI8     // sps[2]
├── AVCLevelIndication            UI8     // sps[3]
├── Reserved                      UB[6]   // 111111
├── LengthSizeMinusOne            UB[2]   // NALUnitLength - 1, 一般为 3
├── Reserved                      UB[3]   // 111
├── NumberOfSequenceParameterSets UB[5]   // sps 个数, 一般为 1
├── SequenceParameterSetNALUnits  UI8[sps_size + 2]  // sps_size(16bits) + sps(UI8[sps_size])
├── NumberOfPictureParameterSets  UI8     // pps 个数, 一般为 1
└── PictureParameterSetNALUnits   UI8[pps_size + 2]  // pps_size(16bits) + pps(UI8[pps_size])

SCRIPTDATA

ScriptTagBody 内容用 AMF 编码

ScriptTagBody

${ScriptTagBody}
|-- Name              SCRIPTDATAVALUE
|-- Vale              SCRIPTDATAVALUE

SCRIPTDATAVALUE

${SCRIPTDATAVALUE}
|-- Type              UI8
|-- ScriptDataValue   各种类型

onMetadata (E.5)

FLV metadata object 保存在 SCRIPTDATA 中, 叫 onMetaData. 不同的软件生成的 FLV 的 properties 不同.

分析工具

flv下载

adobe specs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment