直播协议 HTTP-FLV 详解
传统的直播协议要么使用 Adobe 的基于 TCP 的 RTMP 协议,要么使用 Apple 的基于 HTTP 的 HLS 协议。
今天我要向大家介绍另外一种结合了 RTMP 的低延时,以及可以复用现有 HTTP 分发资源的流式协议 HTTP-FLV。
FLV
首先介绍一下 FLV 文件格式的细节。
FLV Adobe 官方标准
FLV 文件格式标准是写在 F4V/FLV file format spec v10.1 的附录 E 里面的 FLV File Format。
单位说明


FLV 文件头和文件体 (E.2, E.3)
从整个文件上看,FLV = FLV File Header + FLV File Body。


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


Timestamp 和 TimestampExtended 组成了这个 TAG 包数据的 PTS 信息,PTS = Timestamp | TimestampExtended << 24。
AudioTag (E.4.2)
由于 AAC 编码的特殊性,这里着重说明了 AAC 编码的 Tag 格式。

AudioTagHeader 的第一个字节,也就是接跟着 StreamID 的 1 个字节包含了音频类型,采样率等的基本信息。
AudioTagHeader 之后跟着的就是 AUDIODATA 部分了。但是,这里有个特例,如果音频格式(SoundFormat)是 AAC,AudioTagHeader 中会多出 1 个字节的数据 AACPacketType,这个字段来表示 AACAUDIODATA 的类型:0 = AAC sequence header,1 = AAC raw。
AudioSpecificConfig 结构描述非常复杂,在标准文档中是用伪代码描述的,这里先假定要编码的音频格式,做一下简化。
音频编码为:AAC-LC,音频采样率为 44100。

在 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 格式。


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)。


SCRIPTDATA (E.4.4)
ScriptTagBody 内容用 AMF 编码

onMetadata (E.5)
FLV metadata object 保存在 SCRIPTDATA 中, 叫 onMetaData。不同的软件生成的 FLV 的 properties 不同。


keyframes 索引信息
官方的文档中并没有对 keyframes index 做描述,但是,flv 的这种结构每个 tag 又不像 TS 有同步头,如果没有 keyframes index 的话,需要按顺序读取每一个tag, seek 及快进快退的效果会非常差。后来在做 flv 文件合成的时候,发现网上有的 flv 文件将 keyframes 信息隐藏在 Script Tag 中。
keyframes 几乎是一个非官方的标准, 也就是民间标准。两个常用的操作 metadata 的工具是 flvtool2 和 FLVMDI,都是把 keyframes 作为一个默认的元信息项目。在 FLVMDI 的主页上有描述:

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

HTTP-FLV
HTTP-FLV,即将音视频数据封装成 FLV,然后通过 HTTP 协议传输给客户端。
HLS 其实是一个 “文本协议”,而并非流媒体协议。那么,什么样的协议才能称之为流媒体协议呢?
流(stream): 数据在网络上按时间先后次序传输和播放的连续音/视频数据流。之所以可以按照顺序传输和播放连续是因为在类似 RTMP、FLV 协议中,每一个音视频数据都被封装成了包含时间戳信息头的数据包。而当播放器拿到这些数据包解包的时候能够根据时间戳信息把这些音视频数据和之前到达的音视频数据连续起来播放。MP4、MKV 等等类似这种封装,必须拿到完整的音视频文件才能播放,因为里面的单个音视频数据块不带有时间戳信息,播放器不能将这些没有时间戳信息数据块连续起来,所以就不能实时的解码播放。
延迟分析
理论上(除去网络延迟外),FLV 可以做到仅仅一个音视频 tag 的延迟。
相比 RTMP 的优点:

直播协议 HTTP-FLV 详解的更多相关文章
- HTTP协议Keep-Alive模式详解
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp22 HTTP协议Keep-Alive模式详解 1.什么是Keep-Aliv ...
- HTTP协议状态码详解(HTTP Status Code)(转)
原文链接:HTTP协议状态码详解(HTTP Status Code) 使用ASP.NET/PHP/JSP 或者javascript都会用到http的不同状态,一些常见的状态码为: 200 – 服务器成 ...
- http协议之报文详解
一. 概述 用于HTTP协议交互的信息被称为HTTP报文.请求端(客户端)的http报文叫做请求报文,响应端的叫做响应报文. 报文,是网络中交换和传输的数据单元,即站点一次性要发送的数据块.报文包含了 ...
- HTTP协议头域详解
HTTP协议头域详解 Requests部分 Accept 指定客户端能够接收的内容类型 Accept: text/plain, text/html Accept-Charset 浏览器可以接受的字符编 ...
- 让Chrome看不了WWDC直播的HLS技术详解
Requirements: Live streaming uses Apple's HTTP Live Streaming (HLS) technology. HLS requires an iPho ...
- RTP协议分析和详解
一.RTP协议分析 第1章. RTP概述 1.1. RTP是什么 RTP全名是Real-time Transport Protocol(实时传输协议).它是IETF提出的一个标准,对应的RF ...
- 浏览器 HTTP 协议缓存机制详解
最近在准备优化日志请求时遇到了一些令人疑惑的问题,比如为什么响应头里出现了两个 cache control.为什么明明设置了 no cache 却还是发请求,为什么多次访问时有时请求里带了 etag, ...
- HTTP协议状态码详解
HTTP状态码,我都是现查现用. 我以前记得几个常用的状态码,比如200,302,304,404, 503. 一般来说我也只需要了解这些常用的状态码就可以了. 如果是做AJAX,REST,网络爬虫, ...
- nginx平台初识(二) 浏览器 HTTP 协议缓存机制详解
1.缓存的分类 缓存分为服务端侧(server side,比如 Nginx.Apache)和客户端侧(client side,比如 web browser). 服务端缓存又分为 代理服务器缓存 和 反 ...
- 网络基础知识-TCP/IP协议各层详解
TCP/IP简介 虽然大家现在对互联网很熟悉,但是计算机网络的出现比互联网要早很多. 计算机为了联网,就必须规定通信协议,早期的计算机网络,都是由各厂商自己规定一套协议,IBM.Apple和Micro ...
随机推荐
- 虚幻引擎UE4如何制作可拖动(Drag and Drop)的背包(Scrollbox)
本教程适合初学者(学习经历已有30天的UE4初学者). 最终效果 由于隐私保护,不想截实际的效果图,下面给出了示意图,左边是背包A,右边是背包B,将其中的子项目从左侧拖往右侧的背包,然后在插入位置放置 ...
- [HDU1512/ZOJ2334]Monkey King-左偏树-可合并堆
Problem Monkey King Solution 本题是裸的左偏树,一个模板就可以过了.对于每个操作对节点先删除/2再合并. 注意本题在HDU上评测特别坑,是多组数据,而且经常出现MLE的情况 ...
- JS操作数组常用的方法
JS操作Array对象的方法 concat(arr1,arr2,...):连接数组indexOf(value):返回数组中value的第一个索引join(separator):将数组中所有的元素连接由 ...
- Oozie时出现org.apache.oozie.service.ServiceException: E0103: Could not load service classes, Cannot load JDBC driver class 'com.mysql.jdbc.Driver'
不多说,直接上干货! 问题详情 查看你的$OOZIE_HOME/logs 我的是/home/hadoop/app/oozie-4.1.0-cdh5.5.4/logs/oozie.log文件 [hado ...
- CSS外边距合并问题
今天无意中碰到了外边距合并的问题,于是便研究了一下.这里做个笔记. 所谓外边距合并,指的是当两个垂直外边距相遇时,它们将形成一个外边距.合并后的外边距的高度等于两个发生合并的外边距的高度中的较大者. ...
- Java多线程缓存器简单实现
package com.charles.utils; import java.util.HashMap; import java.util.Map; import java.util.concurre ...
- iOS TextField输入限制(限制长度、只能输入数字,只能输入数字字母……)
项目中各个地方都会用到TextField,textField的输入也会有各种需求,各种限制,每次用到的时候要重写一遍这些限制,导致各种垃圾代码,各种重复,有一天,我终于看不下去了,于是把textFie ...
- CSharpGL(43)环境映射(Environment Mapping)-天空盒(Skybox)反射(Reflection)和折射(Refraction)
CSharpGL(43)环境映射(Environment Mapping)-天空盒(Skybox)反射(Reflection)和折射(Refraction) 开始 如图所示,本文围绕GLSL里的sam ...
- 百度地图JavaScript API使用
最近在完成优达学城前端开发(入门)课程的P4项目中,要求调用google地图进行交互,项目已提供部分js代码和html代码.但在申请google地图API密钥时由于网络等原因,打不开或者连接超时,所以 ...
- 一.CPU,Mem过高怎么办 --这是个开始
本身是名Java开发,在做了一段大数据的工作后,猛然间想对Java做个总结. 从未写过技术博客,一时不知如何开始,思虑后,暂且以自己喜爱的方式来开篇. 工作中遇到过CPU或内存过高的问题,解决步骤: ...