网站建设费合同,网络营销的有形层,杭州微网站,门户网站模板 html文章目录 前言一、HTTP-FLV 简介1、市场上使用 http-flv 的商家2、http-flv、rtmp 和 hls 直播的优缺点3、http-flv 技术实现 二、Nginx 配置 http-flv1、Windows 安装 nginx#xff0c;已经集成 nginx-http-flv-module2、nginx.conf 配置文件3、运行 nginx 服务器4、ffmpeg 推… 文章目录 前言一、HTTP-FLV 简介1、市场上使用 http-flv 的商家2、http-flv、rtmp 和 hls 直播的优缺点3、http-flv 技术实现 二、Nginx 配置 http-flv1、Windows 安装 nginx已经集成 nginx-http-flv-module2、nginx.conf 配置文件3、运行 nginx 服务器4、ffmpeg 推流5、VLC 播放6、flv.js 网页播放 三、FLV 格式简介1、简介2、FLV 格式解析①、header②、body 四、FLV Adobe 官方标准1、单位说明2、FLV 文件头和文件体 (E.2, E.3)3、FLV Tag (E.4)4、AudioTag (E.4.2)5、VideoTag (E.4.3)6、SCRIPTDATA (E.4.4)7、onMetadata (E.5)8、keyframes 索引信息 五、FlvAnalyzer 分析 flv 文件 前言
传统的直播协议要么使用 Adobe 的基于 TCP 的 RTMP 协议 要么使用 Apple 的基于 HTTP 的 HLS 协议。本文介绍另外一种结合了 RTMP 的低延时 以及可以复用现有 HTTP 分发资源的流式协议 HTTP-FLV。 一、HTTP-FLV 简介
HTTP-FLV即将音视频数据封装成 FLV然后通过 HTTP 协议传输给客户端。
HLS 其实是一个 “文本协议” 而并非流媒体协议(ts0,ts1,…)。 那么什么样的协议才能称之为流媒体协议呢 答流stream数据在网络上按时间先后次序传输和播放的连续音/视频数据流。之所以可以按照顺序传输和播放连续是因为在类似 RTMP、FLV 协议中每一个音视频数据都被封装成了包含时间戳信息头的数据包。而当播放器拿到这些数据包解包的时候能够根据时间戳信息把这些音视频数据和之前到达的音视频数据连续起来播放。 MP4、MKV 等等类似这种封装必须拿到完整的音视频文件才能播放因为里面的单个音视频数据块不带有时间戳信息播放器不能将这些没有时间戳信息数据块连续起来所以就不能实时的解码播放。 1、市场上使用 http-flv 的商家
优酷的 pc 网页直播斗鱼、 熊猫 tv、 虎牙 pc 网页上也使用了 http-flv
2、http-flv、rtmp 和 hls 直播的优缺点
三者的延迟性 http-flv低延迟内容延迟可以做到 2-5 秒Rtmp低延迟内容延迟可以做到 2-5 秒。Hls延迟较高ts0segment-time510s。 三者的易用性 rtmp 和 http-flv播放端安装率高。只要浏览器支持 FlashPlayer 就能非常简易的播放。hls最大的优点HTML5 可以直接打开播放这个意味着可以把一个直播链接通过微信等转发分享不需要安装任何独立的 APP有浏览器即可。 rtmp 和 http-flv 比较 穿墙很多防火墙会墙掉 RTMP但是不会墙 HTTP因此 HTTP FLV 出现奇怪问题的概率很小。调度RTMP 也有个 302可惜是播放器 as 中支持的HTTP FLV 流就支持 302 方便 CDN 纠正 DNS 的错误。容错SRS 的 HTTP FLV 回源时可以回多个和 RTMP 一样可以支持多级热备。简单FLV 是最简单的流媒体封装HTTP 是最广泛的协议这两个组合在一起维护性更高比 RTMP 简单多了。
3、http-flv 技术实现
HTTP 协议中有个约定content-length 字段http 的 body 部分的长度。
服务器回复 http 请求的时候如果有这个字段客户端就接收这个长度的数据然后就认为数据传输完成了。如果服务器回复 http 请求中没有这个字段客户端就一直接收数据直到服务器跟客户端的 socket 连接断开。 (流式传输
http-flv 直播就是利用第二个原理服务器回复客户端请求的时候不加 content-length 字段在回复了 http 内容之后紧接着发送 flv 数据客户端就一直接收数据了。
二、Nginx 配置 http-flv
1、Windows 安装 nginx已经集成 nginx-http-flv-module
RTMP 服务器Nginxrtmpwindows的环境搭建如有需要可自取
链接https://pan.baidu.com/s/1AcIVERWUPbJL1zu8yCcAzw 提取码mtdf
2、nginx.conf 配置文件
nginx.conf 配置文件如下
worker_processes 1;#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#error_log logs/error.log debug;#pid logs/nginx.pid;events {worker_connections 1024;
}# 添加RTMP服务
rtmp {server {listen 1935; # 监听端口chunk_size 4000;application live {live on;gop_cache on;hls on;hls_path html/hls;}}
}# HTTP服务
http {include mime.types;default_type application/octet-stream;#access_log logs/access.log main;server {listen 8080; # 监听端口location /flv {flv_live on;chunked_transfer_encoding on; add_header Access-Control-Allow-Origin *;add_header Access-Control-Allow-Credentials true;add_header Access-Control-Allow-Methods *;add_header Access-Control-Allow-Headers Content-Type,Access-Token;add_header Access-Control-Expose-Headers *; }location /stat.xsl {root html;}location /stat {rtmp_stat all;rtmp_stat_stylesheet stat.xsl;}location / {root html;}}
}其中涉及到跨域问题#http-flv location /flv {flv_live on;chunked_transfer_encoding on; add_header Access-Control-Allow-Origin *;add_header Access-Control-Allow-Credentials true;add_header Access-Control-Allow-Methods *;add_header Access-Control-Allow-Headers Content-Type,Access-Token;add_header Access-Control-Expose-Headers *; }3、运行 nginx 服务器
双击 nginx8080.exe 在任务管理器可以看到目前 nginx 已开始工作
4、ffmpeg 推流
ffmpeg -re -i SampleVideo_1280x720_20mb.mp4 -vcodec libx264 -acodec aac -f flv -y rtmp://127.0.0.1:1935/live/test1这个命令使用 FFmpeg 工具来将输入视频文件 SampleVideo_1280x720_20mb.mp4 转换为 FLV 格式并通过 RTMP 协议流式传输到指定的 URL 地址 rtmp://127.0.0.1:1935/live/test1
-re以实时模式real-time读取输入文件模拟实时流传输的速度。-i SampleVideo_1280x720_20mb.mp4指定输入文件名为 SampleVideo_1280x720_20mb.mp4。-vcodec libx264选择 H.264 编码器作为视频编码器-acodec aac选择 AAC 编码器作为音频编码器-f flv指定输出格式为FLVFlash Video-y自动覆盖输出文件如果存在同名文件则会被替换rtmp://127.0.0.1:1935/live/test1指定输出的 URL 地址以 RTMP 协议传输到 192.168.36.176 服务器的 1935 端口的 live 应用程序中的 test1 流 5、VLC 播放
http-flvhttp://localhost:8080/flv?port1935applivestreamtest1 对应关系如下 VLC 进行拉流 rtmprtmp://127.0.0.1:1935/live/test1 Hlshttp://localhost:8080/hls/test1.m3u8
此外视频和音频内容分割为小的 TS 文件并生成相应的 M3U8 文件以便客户端能够获取和播放这些文件。M3U8 文件可以通过 HTTP 服务器提供给客户端并使用流媒体播放器如VLC、HLS播放器等进行解析和播放。 这个目录是由 nginx.conf 配置文件决定的
6、flv.js 网页播放
前面我们已经解决了跨域问题 html.flv 文件内容如下
worker_processes 1;#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#error_log logs/error.log debug;#pid logs/nginx.pid;events {worker_connections 1024;
}# 添加RTMP服务
rtmp {server {listen 1935; # 监听端口chunk_size 4000;application live {live on;gop_cache on;hls on;hls_path html/hls;}}
}# HTTP服务
http {include mime.types;default_type application/octet-stream;#access_log logs/access.log main;server {listen 8080; # 监听端口location /flv {flv_live on;chunked_transfer_encoding on; add_header Access-Control-Allow-Origin *;add_header Access-Control-Allow-Credentials true;add_header Access-Control-Allow-Methods *;add_header Access-Control-Allow-Headers Content-Type,Access-Token;add_header Access-Control-Expose-Headers *; }location /stat.xsl {root html;}location /stat {rtmp_stat all;rtmp_stat_stylesheet stat.xsl;}location / {root html;}}
}因此双击 flv.html 文件可以看到网页播放成功
三、FLV 格式简介
1、简介
FLVFlash Video是现在非常流行的流媒体格式由于其视频文件体积轻巧、封装播放简单等特点使其很适合在网络上进行应用目前主流的视频网站无一例外地使用了 FLV 格式。另外由于当前浏览器与 Flash Player 紧密的结合使得网页播放 FLV 视频轻而易举也是 FLV 流行的原因之一。
FLV 是流媒体封装格式我们可以将其数据看为二进制字节流。总体上看FLV 包括文件头File Header9 字节和文件体File Body两部分其中文件体由一系列的 Tag 及 Tag Size 对组成。
注意这个大小关系PreviosTagSize TagDataSize 11;
2、FLV 格式解析
先来一张图这是上面我们播放的视频文转换为 FLV 文件 使用 Notepad 进行查看二进制数据注这里要求 Notepad 安装了 HexEditor 插件 可以参考我以前的博客notepad安装HexEditor插件查看二进制文件 SampleVideo_1280x720_20mb.flv 文件二进制内容如下
①、header
头部分由以下几部分组成Signature3 ByteVersion1 ByteFlags1 BypteDataOffset4 Byte
signature 占 3 个字节固定 FLV 三个字符作为标示。一般发现前三个字符为 FLV 时就认为他是 flv 文件。Version 占 1 个字节标示 FLV 的版本号。 这里我们看到是 1Flags 占 1 个字节内容标示。第 0 位和第 2 位分别表示 video 与 audio 存在的情况。(1 表示存在0 表示不存在)。截图看到是 0x05也就是 00000101代表既有视频也有音频。DataOffset 4 个字节表示 FLV 的 header 长度。 这里可以看到固定是 9
②、body
FLV 的 body 部分是由一系列的 back-pointers 后向指针 tag 构成
back-pointers 固定 4 个字节表示前一个 tag 的 size。 从上图可以看到前一个 tag 的 size 为 0 tag 分三种类型video、audio、scripts。 tag 组成tag type[1B]tag data size[3B]Timestamp[3B]TimestampExtended[1B]stream id[3B] tag data type 1 个字节。8 为 Audio9 为 Video18 为 scripts 从上图可以看到 type 为 0x123 18 -- scripts tag data size 3 个字节。表示 tag data 的长度从 streamd id 后算起。 从上图可以看到 tag data size 为 0x123 297 Timestreamp 3 个字节。 时间戳 从上图可以看到 Timestreamp 为 0x000000 0 TimestampExtended 1 个字节。 时间戳扩展字段 从上图可以看到 TimestampExtended 为 0x00 0 stream id 3 个字节。 总是 0tag data 数据部分 tag 头伪代码
四、FLV Adobe 官方标准
FLV 文件格式标准是写在 F4V/FLV file format spec v10.1 的附录 E 里面的 FLV File Format。
1、单位说明 2、FLV 文件头和文件体 (E.2, E.3)
从整个文件上看FLV FLV File Header FLV File Body。 通常FLV 的前 13 个字节flv header PreviousTagSize0完全相同所以程序中会单独定义一个常量来指定。特殊比如有的视频文件没有视频流或没有音频流。
3、FLV Tag (E.4) Timestamp 和 TimestampExtended 组成了这个 TAG 包数据的 PTS 信息PTS Timestamp | TimestampExtended 24。
4、AudioTag (E.4.2)
由于 AAC 编码的特殊性 这里着重说明了 AAC 编码的 Tag 格式。 AudioTagHeader 的第一个字节也就是接跟着 StreamID 的 1 个字节包含了音频类型采样率等的基本信息。
AudioTagHeader 之后跟着的就是 AUDIODATA 部分了。但是这里有个特例如果音频格式SoundFormat是 AACAudioTagHeader 中会多出 1 个字节的数据 AACPacketType这个字段来表示 AACAUDIODATA 的类型0 AAC sequence header1 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 文件中的音频信息及数据提取出来 送给音频解码器正常播放了。
5、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)。
6、SCRIPTDATA (E.4.4)
ScriptTagBody 内容用 AMF 编码 一个 SCRIPTDATAVALUE 记录包含一个有类型的 ActionScript 值。
7、onMetadata (E.5)
FLV metadata object 保存在 SCRIPTDATA 中叫 onMetaData。不同的软件生成的 FLV 的 properties 不同。
8、keyframes 索引信息
官方的文档中并没有对 keyframes index 做描述但是flv 的这种结构每个 tag 又不像 TS 有同步头如果没有 keyframes index 的话需要按顺序读取每一个 tagseek 及快进快退的效果会非常差。后来在做 flv 文件合成的时候发现网上有的 flv 文件将 keyframes 信息隐藏在 Script Tag 中。
keyframes 几乎是一个非官方的标准也就是民间标准。两个常用的操作 metadata 的工具是 flvtool2 和 FLVMDI 都是把 keyframes 作为一个默认的元信息项目。在 FLVMDI 的主页上有描述 也就是说 keyframes 中包含着 2 个内容 “filepositions” 和 “times”分别指的是关键帧的文件位置和关键帧的 PTS。通过 keyframes 可以建立起自己的 Index然后在 seek 和快进快退的操作中快速有效地跳转到你想要找的关键帧位置进行处理。
五、FlvAnalyzer 分析 flv 文件
参考我之前的博客音视频开发常用工具
查看其中第三章的内容 我的qq2442391036欢迎交流