java封装264成flv,将H.264封装为FLV格式-Go语言中文社区

本文将介绍如何将H.264封装成flv格式。

在看本文之间,建议先看一看下面两篇文章:

首先说一说构建一个FLV文件需要什么?

FLV Header + FLv script tag + FLV Video tag + FLV Audio tag

由于这里只是封装H.264,所以不包括Audio tag。

下面将通过分析示例来说明FLV Header + FLv script tag + FLV Video tag这三部分如何构建。

1、FLV Header

通过阅读上面的文章《FLV格式详解》应该就很清楚FLV Header的内容了。

下面来分析一个实例:

756f80fa8e8a503fec7b99c0081ee19e.png

Signature:0x46('F')

Signature:0x4c('L')

Signature:0x56('V')

Version:01

Flags:01

TypeFlagsReserved [Bit 3-7]:0

TypeFlagsAudio [Bit 2]:0

TypeFlagsReserved [Bit 1]:0

TypeFlagsVideo [Bit 0]:1

DataOffset:00 00 00 09

preTagSize:00 00 00 00 // 第一个tag默认为0

2、FLv script tag

又称Metadata Tag,位于flv header后的第一个tag

下面来分析一个实例

ff450a64e0b7406dff4e2ae841e1bb4c.png

Tag Header:

TagType:12(表示这是一个script tag)

Datasize:00 00 9f(Tag Data 部分的大小)

Timestamp:00 00 00(该Tag的时间戳)

Timestamp_ex:00(时间戳的扩展部分)

StreamID::00 00 00(总是0)

Tag data:

因为TagType为0x12,所以这部分的数据为两个AMF包

第一个AMF包:

type:02(表示字符串)

stringLen:00 0a(字符串长度为10)

string:6f 6e 4d 65 74 61 44 61 74 61(onMetaData)

第二个AMF包:

type:08(表示数组)

arrayNum:00 00 00 07(数组元素个数)

stringLen:00 08(第一个数组元素字符串长度)

string:64 75 72 61 74 69 6f 6e(duration)

valType:00(数据类型,double型)

val:40 03 70 a3 d7 0a 3d 71(double型)

stringLen:00 05

string:77 69 64 74 68(width)

...

end:00 00 09

preTagSize:00 00 00 aa

3、FLV Video Tag

这部分封装着图像数据,也就是H.264的数据封装在这里。

H.264是由一个一个NALU组成,NALU的类型有(SPS、PPS、I帧的SLICE、非I帧的SLICE)

封装H.264就是将这些NALU一个一个取出来,然后封装成Tag。

需要注意的是,SPS与PPS必须封装在一个Tag中。

下面分别通过实例来分析各种NALU(SPS、PPS、I帧的SLICE、SEI、非I帧的SLICE)是怎么封装的。

1、SPS与PPS

806a7c8229580407cae59d0ced684dfd.png

Tag Header:

TagType:09(Tag的类型,包括音频(0x08)、视频(0x09)、script data(0x12))

Datasize:00 00 2e(Tag Data 部分的大小)

Timestamp:00 00 00(时间戳,19ms)

Timestamp_ex:00(时间戳的扩展部分)

StreamID:00 00 00(总是0)

Tag data:

FrameType | CodecID:17(keyframe | AVC)(视频tag的参数)

AVCVideoPaket:(因为CodecID==7,所以VideoData为AVCVideoPaket)

AVCPaketType:00(ACVPacket的类型,0: AVC sequence header;1: AVC NALU;2: AVC end of sequence)

CompositionTime:00 00 00

(因为ACVPaketType==0,所以Data=AVCDecoderConfigurationRecord)

AVCDecoderConfigurationRecord:

configurationVersion:01

AVCProfileIndication:64

profile_compatibility:00

AVCLevelIndication:1e

lengthSizeMinusOne:ff

numOfSequenceParameterSets:e1(低五位为SPS的个数,计算方法为:numOfSequenceParameterSets & 0x1F=1)

sequenceParameterSetLength:00 18(SPS的长度,24)

sequenceParameterSetNALUnits:67 64 00 1e ac d9 40 a0 33 b0 11 00 00 03 02 47 00 00 6d 34 0f 16 2d 96(SPS)

numOfPictureParameterSets:01(PPS的个数)

pictureParameterSetLength:00 06(PPS的长度)

pictureParameterSetNALUnits:68 eb e3 cb 22 c0(PPS)

previousTagSize:00 00 00 39

2、I帧的SLICE

fbbfacbce62bb5131b115d94b36815e9.png

Tag Header:

TagType:09(Tag的类型,包括音频(0x08)、视频(0x09)、script data(0x12))

Datasize:00 35 78(Tag Data 部分的大小)

Timestamp:00 00 0a(时间戳,19ms)

Timestamp_ex:00(时间戳的扩展部分)

StreamID:00 00 00(总是0)

Tag data:

FrameType | CodecID:17(key frame | AVC)(视频tag的参数)

因为CodecID==7,所以VideoData为AVCVideoPaket

AVCVideoPaket:

AVCPaketType:01(ACVPacket的类型,0: AVC sequence header;1: AVC NALU;2: AVC end of sequence)

CompositionTime:00 00 0a

NaluLen:00 00 35 6f

NaluData:...

preTagSize:00 00 35 83

对于SEI的封装跟I帧是一样的。

3、非I帧的SLICE

非I帧的封装格式和I帧的封装格式基本一样,唯一不同的是FrameType | CodecID:部分,应该设置为:

FrameType | CodecID:27(inter frame | AVC)(视频tag的参数)

总结:以上通过实例讲解了FLV的头部信息,script tag,以及H.264不同类型的NALU如何封装成tag,下面放出源码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值