HTTP-FLV简介

HTTP-FLV,即将音视频数据封装成 FLV,然后通过 HTTP 协议传输给客户端。

HLS 其实是一个 “文本协议”,而并非流媒体协议。那么,什么样的协议才能称之为流媒体协议呢?

流(stream): 数据在网络上按时间先后次序传输和播放的连续音/视频数据流。之所以可以按照顺序传输和播放连续是因为在类似 RTMP、FLV 协议中,每一个音视频数据都被封装成了包含时间戳信息头的数据包。而当播放器拿到这些数据包解包的时候能够根据时间戳信息把这些音视频数据和之前到达的音视频数据连续起来播放。MP4、MKV 等等类似这种封装,必须拿到完整的音视频文件才能播放,因为里面的单个音视频数据块不带有时间戳信息,播放器不能将这些没有时间戳信息数据块连续起来,所以就不能实时的解码播放。

直播http-flv,之前用的是rtmp和hls。

为什么使用http-flv,它有什么优缺点?

怎么让流媒体服务器支持flv直播?

一、市场上哪家直播使用了http-flv:

通过抓包分析: 优酷的pc网页直播使用了http-flv。

斗鱼、熊猫tv、虎牙pc网页上的也使用了http-flv。

二、http-flv、rtmp和hls直播的优缺点:

A、三者的延迟性:

http-flv:低延迟,内容延迟可以做到2-5秒。

Rtmp:低延迟,内容延迟可以做到2-5秒。

Hls::延迟较高。

B、三者的易用性:

rtmp和http-flv:播放端安装率高。只要浏览器支持FlashPlayer就能非常简易的播放。

hls:最大的优点:HTML5可以直接打开播放;这个意味着可以把一个直播链接通过微信

等转发分享,不需要安装任何独立的APP,有浏览器即可。

C、rtmp和http-flv比较:

(1) 穿墙:很多防火墙会墙掉RTMP,但是不会墙HTTP,因此HTTP FLV出现奇怪问题的概率很小。

(2) 调度:RTMP也有个302,可惜是播放器as中支持的,HTTP FLV流就支持302方便CDN纠正DNS的错误。

(3) 容错:SRS的HTTP FLV回源时可以回多个,和RTMP一样,可以支持多级热备。

(4) 简单:FLV是最简单的流媒体封装,HTTP是最广泛的协议,这两个组合在一起维护性更高,比RTMP简单多了。

三、http-flv技术实现:

HTTP协议中有个约定:content-length字段,http的body部分的长度

服务器回复http请求的时候如果有这个字段,客户端就接收这个长度的数据然后就认为数据传输完成了,

如果服务器回复http请求中没有这个字段,客户端就一直接收数据,直到服务器跟客户端的socket连接断开。

http-flv直播就是利用第二个原理,服务器回复客户端请求的时候不加content-length字段,在回复了http

内容之后,紧接着发送flv数据,客户端就一直接收数据了。

四、使用和测试http-flv:

使用开源的Nginx服务器。

推流端以rtmp的形式推流到Nginx服务器,Nginx再把rtmp流转换成http-flv流。

FLV格式简介

首先介绍一下 FLV 文件格式的细节。

FLV Adobe 官方标准

FLV 文件格式标准是写在 F4V/FLV file format spec v10.1 的附录 E 里面的 FLV File Format。

单位说明

类型 说明

Unit

data

types

SI8 Signed 8-bit integer

SI16 Signed 16-bit integer

SI24 Signed 24-bit integer

SI32 Signed 32-bit integer

SI64 Signed 32-bit integer

UI8 Unsigned 8-bit integer

UI16 Unsigned 16-bit integer

UI24 Unsigned 24-bit integer

UI32 Unsigned 32-bit integer

UI64 Unsigned 64-bit integer

xxx[] Slice of type xxx

xxx[n] Array of type xxx

STRING Sequence of Unicode 8-bit characters (UTF-8), terminated with 0x00

FLV 文件头和文件体 (E.2, E.3)

从整个文件上看,FLV = FLV File Header + FLV File Body。

字段 类型 说明

FLV File Header

Signature UI8[3] 签名,总是 “FLV” (0x464C56)

Version UI8 版本,总是 0x01,表示 FLV version 1

TypeFlagsReserved UB [5] 全 0

TypeFlagsAudio UB[1] 1 = 有音频

TypeFlagsReserved UB[1] 全 0

TypeFlagsVideo UB[1] 1 = 有视频

DataOffset UI32 整个文件头长度,对于FLV v1,总是 9

FLV File Body

PreviousTagSize0 UI32 总是 0

Tag1 FLVTAG 第一个 tag

PreviousTagSize1 UI32 前一个 tag 的大小, 包括他的 header,即:11 + 前一个 tag 的大小

Tag2 FLVTAG 第二个 tag

PreviousTagSizeN-1 UI32 前一个 tag 大小

TagN FLVTAG 最后一个 tag

PreviousTagSizeN UI32 最后一个 tag 大小,包括他的 header

通常,FLV 的前 13 个字节(flv header + PreviousTagSize0)完全相同,所以,程序中会单独定义一个常量来指定。

FLV Tag (E.4)

字段 类型 说明

FLV Tag

Reserved UB[2] 保留给FMS, 应为 0

Filter UB[1] 0 = unencrypted tags,1 = encrypted tags

TagType UB [5] 类型,0x08 = audio,0x09 = video,0x12 = 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 == 0x08

VideoTagHeader   IF TagType == 0x09

EncryptionHeader   IF Filter == 1

FilterParams   IF Filter == 1

Data   AUDIODATA 或者 VIDEODATA 或者 SCRIPTDATA

Timestamp 和 TimestampExtended 组成了这个 TAG 包数据的 PTS 信息,PTS = Timestamp | TimestampExtended << 24。

AudioTag (E.4.2)

由于 AAC 编码的特殊性,这里着重说明了 AAC 编码的 Tag 格式。

字段 类型 说明

Audio Tag

AudioTagHeader

SoundFormat UB[4] 音频编码格式。2 = MP3,10 = AAC,11 = Speex

SoundRate UB[2] 采样率。0 = 5.5 kHz,1 = 11 kHz,2 = 22 kHz,3 = 44 kHz

SoundSize UB[1] 采样大小。 0 = 8-bit,1 = 16-bit

SoundType UB[1] 音频声道数。0 = Mono,1 = Stereo

AACPacketType UI8 只有当 SoundFormat 为 10 时,才有该字段。0 = AAC sequence header,1 = AAC raw

AACAUDIODATA

Data AudioSpecificConfig IF AACPacketType == 0,包含着一些更加详细音频的信息

Data Raw AAC frame data in UI8 [n] IF AACPacketType == 1,audio payload,n = [AAC Raw data length] - ([has CRC] ? 9:7)

AudioTagHeader 的第一个字节,也就是接跟着 StreamID 的 1 个字节包含了音频类型,采样率等的基本信息。

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

AudioSpecificConfig 结构描述非常复杂,在标准文档中是用伪代码描述的,这里先假定要编码的音频格式,做一下简化。

音频编码为:AAC-LC,音频采样率为 44100。

字段 类型 说明

AudioSpecificConfig

audioObjectType UB[5] 编码结构类型,AAC-LC 为 2

samplingFrequencyIndex UB[4] 音频采样率索引值,44100 对应值 4

channelConfiguration UB[4] 音频输出声道,2

GASpecificConfig

frameLengthFlag UB[1] 标志位,用于表明 IMDCT 窗口长度,0

dependsOnCoreCoder UB[1] 标志位,表明是否依赖于 corecoder,0

extensionFlag UB[1] 选择了 AAC-LC,这里必须为 0

在 FLV 的文件中,一般情况下 AAC sequence header 这种包只出现1次,而且是第一个 audio tag,为什么需要这种 tag,因为在做 FLV demux 的时候,如果是 AAC 的音频,需要在每帧 AAC ES 流前边添加 7 个字节 ADST 头,ADST 是解码器通用的格式,也就是说 AAC 的纯 ES 流要打包成 ADST 格式的 AAC 文件,解码器才能正常播放。就是在打包 ADST 的时候,需要 samplingFrequencyIndex 这个信息,samplingFrequencyIndex 最准确的信息是在 AudioSpecificConfig 中,这样,你就完全可以把 FLV 文件中的音频信息及数据提取出来,送给音频解码器正常播放了。

VideoTag (E.4.3)

由于 AVC(H.264) 编码的特殊性,这里着重说明了 AVC(H.264) 编码的 Tag 格式。

字段 类型 说明

Video Tag

VideoTagHeader

FrameType UB[4] 1 = key frame,2 = inter frame

CodecID UB[4] 7 = AVC

AVCPacketType UI8 IF CodecID == 7,0 = AVC sequence header(AVCDecoderConfigurationRecord),1 = One or more AVC NALUs (Full frames are required),2 = AVC end of sequence

CompositionTime SI24 IF AVCPacketType == 1 Composition time offset ELSE 0

VideoTagHeader 的第一个字节,也就是接跟着 StreamID 的 1 个字节包含着视频帧类型及视频 CodecID 等最基本信息。

VideoTagHeader 之后跟着的就是 VIDEODATA 部分了。但是,这里有个特例,如果视频格式(CodecID)是 AVC,VideoTagHeader 会多出 4 个字节的信息。

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

AVCDecoderConfigurationRecord 长度为 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 (E.4.4)

ScriptTagBody 内容用 AMF 编码

字段 类型 说明

SCRIPTDATA

ScriptTagBody

Name SCRIPTDATAVALUE Method or object name. SCRIPTDATAVALUE.Type = 2 (String)

Vale SCRIPTDATAVALUE AMF arguments or object properties.

SCRIPTDATAVALUE

Type UI8 ScriptDataValue 的类型

ScriptDataValue 各种类型 Script data 值

一个 SCRIPTDATAVALUE 记录包含一个有类型的 ActionScript 值。

onMetadata (E.5)

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

字段 类型 说明

onMetaData

audiocodecid Number Audio codec ID used in the file

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

keyframes 索引信息

官方的文档中并没有对 keyframes index 做描述,但是,flv 的这种结构每个 tag 又不像 TS 有同步头,如果没有 keyframes index 的话,需要按顺序读取每一个tag, seek 及快进快退的效果会非常差。后来在做 flv 文件合成的时候,发现网上有的 flv 文件将 keyframes 信息隐藏在 Script Tag 中。

keyframes 几乎是一个非官方的标准, 也就是民间标准。两个常用的操作 metadata 的工具是 flvtool2 和 FLVMDI,都是把 keyframes 作为一个默认的元信息项目。在 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” 和 “times”分别指的是关键帧的文件位置和关键帧的 PTS。通过 keyframes 可以建立起自己的 Index,然后在 seek 和快进快退的操作中,快速有效地跳转到你想要找的关键帧位置进行处理。

大家好,我的第一本书正式出版了,可以在京东各大店铺抢购哦。

《FFmpeg入门详解--音视频原理及应用:梅会东:清华大学出版社》

京东自营链接:https://item.jd.com/13377793.html
京东其它链接:https://search.jd.com/Search?keyword=FFmpeg%E5%85%A5%E9%97%A8%E8%AF%A6%E8%A7%A3--%E9%9F%B3%E8%A7%86%E9%A2%91%E5%8E%9F%E7%90%86%E5%8F%8A%E5%BA%94%E7%94%A8&enc=utf-8&suggest=1.his.0.0&wq=&pvid=24e80535073b4e1f98e30a3e6963fe81

 

出书过程非常艰辛,来回校正了好几遍,后续还有FFmpeg系列的其它图书。

第一本:FFmpeg入门详解--音视频原理及应用--梅会东--清华大学出版社

第二本:FFmpeg入门详解--流媒体直播原理及应用--梅会东--清华大学出版社

第三本:FFmpeg入门详解--命令行及音视频特效原理及应用--梅会东--清华大学出版社

第四本:FFmpeg入门详解--SDK二次开发及直播美颜原理及应用--梅会东--清华大学出版社

===================================

FFmpeg入门详解之89:HTTP-FLV讲解相关推荐

  1. FFmpeg入门详解之83:流媒体与直播技术

    流媒体 流媒体又叫流式媒体,它是指商家用一个视频传送服务器(比如:vlc)把节目(比如:ande10.mp4)当成数据包发出,传送到网络上.用户通过解压设备对这些数据进行解压后,节目就会像发送前那样显 ...

  2. FFmpeg入门详解之117:视频监控的架构和流程

    几张架构图带您快速了解视频监控 图一 图二 图三 图四 视频监控系统的简介 视频监控 视频监控是安全防范系统的重要组成部分,英文Cameras and Surveillance.传统的监控系统包括前端 ...

  3. FFmpeg入门详解之121:颜色空间转换RGB和YUV的原理与实战

    5.颜色空间转换RGB和YUV的原理与实战 三种颜色空间模型:RGB.YUV.HSV 一.概述 颜色通常用三个独立的属性来描述,三个独立变量综合作用,自然就构成一个空间坐标,这就是颜色空间. 但被描述 ...

  4. FFmpeg入门详解之122:Qt5 FFmpeg本地摄像头采集预览实战

    6.Qt5+FFmpeg本地摄像头采集预览实战 源码工程:S26_Test2 FFmpeg命令行处理摄像头 ffmpeg -list_devices true -f dshow -i dummy 命令 ...

  5. FFmpeg入门详解之119:FFmpeg的SDK编程回顾总结并操练

    3.FFmpeg的SDK编程回顾总结并操练 参考课程:"FFmpeg4.3--系列5--SDK二次开发详解与实战" FFmpeg主要框架 FFmpeg骨架:"八大金刚&q ...

  6. FFmpeg入门详解--音视频原理及应用:梅会东:清华大学出版社

    大家好,我的第一本书正式出版了,可以在京东各大店铺抢购哦. <FFmpeg入门详解--音视频原理及应用:梅会东:清华大学出版社> 京东自营链接:https://item.jd.com/13 ...

  7. FFmpeg入门详解之125:onvif与GB/T-28181的小白入门

    onvif与GB/T-28181的小白入门 敬告:本系列不展开onvif和28181. 参考:详细内容请参考系列27和系列28 一.什么是ONVIF? 1.1形成 2008年5月,由安讯士(AXIS) ...

  8. FFmpeg入门详解之100:搭建Nginx流媒体服务器

    这里小编给大家推荐一款流媒体服务器Nginx,可以实现RTMP和HLS等.搭建完成后,可以使用FFmpeg推流,实现直播功能. 注意:操作环境是Ubuntu18.04, 总共分为几个步骤: 1.安装N ...

  9. FFmpeg入门详解之84:RTSP协议讲解

    RTSP亲手搭建直播点播 测试工具:VLC 数据源:  文件或本地摄像头 测试功能:RTSP直播点播 播放地址:rtsp://127.0.0.1:8554/rtspa001 服务端:推流 客户端:拉流 ...

最新文章

  1. C语言博客作业04--数组
  2. Python 3 的 int 类型详解(为什么 int 不存在溢出问题?)
  3. Linux下Redis服务器安装配置
  4. Python连续攀升,其他的脚本语言去哪了?
  5. python matplotlib简单使用
  6. 有效值和峰峰值的关系_4.数据预处理—缺失值处理(二)
  7. 那一天我们许下约定(组合数学,DP)
  8. UI设计灵感|高级黑网页首图就该这样设计
  9. 数据链路层点到点通讯和PPP协议
  10. 5)Thymeleaf 模板布局 th:fragment、th:replace、th:insert、th:remove
  11. java mongodb 读取文件_Java操作Mongodb之文件读写
  12. 干掉visio,这个画图神器太香了
  13. log公式如何用计算机,log计算-计算器怎么算log,如何使用科学计算器中的对数log...
  14. 使用Photoshop制作圣诞海报
  15. WordPress文章页面获取评论次数
  16. vue+element-ui 实现上传前图片压缩功能
  17. Linux内核如何私闯进程地址空间并修改进程内存
  18. 前后端分离vue2+node易购商城后台管理系统
  19. 详解温度传感器DS18B20编程与使用
  20. matlab 重复测量方差分析,DPABI重复测量方差分析时,在permutation test或后续的多重比较校正时报错...

热门文章

  1. 推荐几个阿里、头条大佬的公众号
  2. (整理)ACM荣耀之路 ACM学习路线
  3. PHP-echo换行处理
  4. java投屏刺激战场_吃鸡手游直播教程,怎么投屏直播玩刺激战场/全军出击
  5. c语言 引用定义变量,如何在c语言中定义及引用全局变量?
  6. 测试开发工作者日记:2020.9.21
  7. 微信门户开发框架-使用指导说明书(2)--基于框架的开发过程
  8. 获取屏幕的宽度用dom方式
  9. iOS14 广播组播发送失败问题
  10. 鼠标点击特效:点击网站页面显示24字核心价值观上升的特效代码