直播服务器简单实现 http_flv和hls 内网直播桌面

转载 2017年01月12日 10:09:05

直播都不陌生了,如今主流的协议分析的对比图,个人见解。

协议

httpflv

rtmp

hls

dash

传输层

http流

tcp流

http

http

视频格式

flv

flv tag

Ts文件

Mp4 3gp webm

延时

数据分段

连续流

连续流

切片文件

切片文件

Html5播放

可通过html5解封包播放(flv.js)

不支持

可通过html5解封包播放(hls.js)

如果dash文件列表是mp4webm文件,可直接播放

http_flv&rtmp

这两个协议实际上传输数据是一样的,数据都是flv文件的tag。http_flv是一个无限大的http流的文件,相比rtmp就只能直播,而rtmp还可以推流和更多的操作。但是http有个好处,就是是以80http通信的,穿透性强,而且rtmp是非开放协议。

这两个协议是如今直播平台主选的直播方式,主要原因就是延时极低。

hls

hls是Apple推出的直播协议,是通过视频流切片成文件片段来直播的。客户端首先会请求一个m3u8文件,里面会有不同码率的流,或者直接是ts文件列表,通过给出的ts文件地址去依次播放。在直播的时候,客户端会不断请求m3u8文件,检查ts列表是否有新的ts切片。

这种方式直播的主要弊端就是延迟过大,最小延时为ts单个文件的时长。

dash

dash实际工作原理和hls一样的,只不过不是mpegts文件,dash可以支持多种切片文件,比如mp4切片。当为mp4切片,客户端直接可用js控制利用html5直接播放。同样的,dash有延时。

 


http-flv到底是怎么直播?

这里我们主要研究httpflv和hls。看了主流几个web直播平台,发现几乎都是以httpflv为主来直播的,那么这么火httpflv到底是怎么达到直播的?

首先我们都知道在媒体格式里,几乎都以h264视频编码。如今httpflv直播的flv数据也都是h264&aac为主的。flv封装单元是以tag来表示的,一个tag可以是音频tag或者视频tag,或者脚本tag及其其他类型。

值得注意的是flv里面字节序是网络字节序,

flv的格式:

1
flvheader+[脚本tag(metadata)]+[第一个视频tag(h264_spspps)]+[第一个音频tag(aac_header)]+[第二个视频tag(h264第一个关键帧)]+ 后面就是音频和视频tag交互存在

tag的格式:

1
TYPE[1byte] + body size[3byte] + timestamp [4byte] +streamID [3byte] +[body data]+[previousTagSize 4byte]

这里的timestamp是这样存在的[ time tamp 3b,time tamp ex 1b]

h264视频tagbody:

这里存储的h264是没有nal分割符的,在t的body里面是这样存储的,

1
[isKeyFrame(1byte)]+0x01+[compositionTime 3byte]+[h264 size 4byte]

compositionTime是h264编码结果dts和pts之间的偏移。

aac视频tag的body:

1
0xaf+0x01+aac raw

以上就是flv格式的详细说明,可以看出格式简单,封装的前后数据关联很小,当我们得到音频头和视频头,就可以从后面任意的一个关键帧开始播放。

当然想要httpflv正常播放,不能缺少matedata,就是第一个脚本tag里面,这里面指定了分辨率,音视频编码格式等。

 httpflv直播实际上单纯就是往客户端发送flvtag,当然是先发送flv前面那几个关键的tag,然后第一帧是关键帧。

假如客户端是obs推流软件,以rtmp方式向服务器推流,在开始握手及其创建stream完成以及发送Metadata完成,及其一系列数据发送完毕,服务器就向obs发送publish result指令,此后,obs就开始向服务器推送flv tag数据,开始直播,而服务器也得到了flv数据。

当某个客户端想要来获取直播数据,比如httpflv的方式来观看直播,服务器会怎么做呢?

服务器会先发送前面几个flvtag,header+metadata+spspps+aacheader,当这几个tag发送完毕,服务器会从直播流tag中,找到最新的视频关键帧tag,从这个关键帧tag开发数据,为什么呢?因为视频流是IBP帧相互存在的,I是完整数据,BP解码都需要I帧和前面的帧,所以,正常视频数据,必须是从I帧开始发送的。这里就涉及到gop间距了,rtmp低延时秒开就是这个原理。当然发送的时候,每个连接的tag开始时间戳戳要从0开始递增的。

至此,httpflv客户端就可以接受到flv流数据,解码观看直播了。

 

hls到底是怎么直播?

hls就相对简单粗暴了,服务器将直播流数据的h264和aac,封装切片成一个个的ts文件。客户端获取直播的数据的时候,先请求m3u8文件,下面就是一个m3u8的文件,

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:5 ts最大时常5s
#EXT-X-MEDIA-SEQUENCE:2 第一个ts文件的标识
#EXTINF:4.993,//第一个ts文件,时长4.993,url地址/hls/2.ts
/hls/2.ts
#EXTINF:4.034,
/hls/3.ts
#EXTINF:4.980,
/hls/4.ts

如果是直播,客户端会不停的去请求这个m3u8文件,当这个列表有新的ts文件,客户端会请求新的ts文件追加到本地播放序列。

关于ts的封包,ts的封装格式要比flv更复杂,主要的数据单元是ts包,每个包有pid,一个包固定大小普通没有crc的为188,主要分为三类ts包,pat,pmt,pes,pat就是第一个包,当解析的时候会在ts包列表里找pid为0x0的包,就是pat包,pat大概作用就是入口的意思,pat里面有pmt包的pid,pmt里面存储的是流的包的pid,比如指定音频包pid是0x102,视频包pid是0x101,后面的0x102和0x101的包就是pes包了,将pes包解析并合并出原始流,就能解码播放了。

 


 小程序

 

知道了如何玩直播,于是写了一个小的程序,该程序会录制本机桌面和输出音频以及麦克风,编码为h264和aac,同时在本机利用IOCP简易的创建一个服务器,提供web服务和直播服务,支持httpflv和hls直播。

以下是小程序的架构图:

 

 

运行截图:

 

启动后可选择,填写端口号和码率,然后选择直播方式,黑屏换low api。

 

 

 

程序使用的三个库:

libx264 视频编码

libfaac 音频编码

swscale brga转yuv420

Android30分钟 DIY搭建局域网视频直播演示Demo

现在移动直播如火如荼的一片大火。而直播技术也层出不穷,各种开源的,收费的直播SDK平台也不少。以上所有种种,虽然可以快速的实现直播功能,但对于自己技术的积累和学习并没有什么好处。本例子通过不借助任何框...
  • a315823806
  • a315823806
  • 2016年12月01日 18:46
  • 2927

教你用直播大师在局域网内发布组播节目

在很多应用场景中,我们往往需要在局域网内发布组播节目,这样做的好处如下: 1.      节省骨干网带宽资源 Internet上产生的许多新的应用,特别是高带宽的多媒体应用,带来了带宽的急剧消...
  • zhiboshequ
  • zhiboshequ
  • 2018年01月30日 22:55
  • 475

直播服务器的搭建以及感想

Red5与EasyDarwin主流开源流媒体服务器有哪些? 流媒体解决方案 Live555(C++) 流媒体平台框架 EasyDarwin(C++) 实时流媒体播放服务器程序DarwinStre...
  • opooc
  • opooc
  • 2017年05月11日 14:54
  • 6727

开发实现C++ RTMP直播推流sdk

前言rtmp即Real Time Messaging Protocol(实时消息传输协议)的首字母缩写,它是由Adobe公司提出的一种应用层的协议,用来解决多媒体数据传输流的多路复用(Multiple...
  • m0_37826678
  • m0_37826678
  • 2017年06月24日 16:14
  • 1640

开发实现C++ RTMP直播拉流播放器

背景该直播播放器的背景是来源于 《拉流推流服务器设计》的一个分支,它的重点是把拉下来的流进行解码显示播放。设计点 要实现跨平台, 目前支持的平台linux和windows 要模块化和结构化 可以拉各个...
  • m0_37826678
  • m0_37826678
  • 2017年06月24日 16:15
  • 1433

RTMP局域网直播环境搭建(ffmpeg+crtmpserver+xampp+jwplayer7)

相关文章链接: 【1】ffmpeg处理RTMP流媒体的命令大全 【2】Win7(Windows 7)下用VS2013(Visual Studio 2013)编译crtmpserver 【3】xampp...
  • caoshangpa
  • caoshangpa
  • 2016年11月01日 15:45
  • 5332

基于ffmpeg的HLS开源服务器搭建配置及开发详解

本文概述:           至目前位置,HLS 是移动平台上非常重要并十分流行的流媒体传输协议。做移动平台的流媒体开发,不知道它不掌握它 ,真是一大遗憾。而HLS的平台搭建有一定的难度,本文...
  • zqf_office
  • zqf_office
  • 2016年02月26日 23:11
  • 802

搭建免费网络直播系统

本文简单的介绍了如何搭建完全免费的视频直播系统,所用的软件完全免费,您不需要任何费用即可搭建属于自己的视频直播系统。FLME,OBS与串流直播均可以用于前端编码,但FLME比较老旧,OBS与串流直播系...
  • ababab12345
  • ababab12345
  • 2016年09月02日 19:03
  • 5866

EasyDarwin开源流媒体音视频云平台遇到的奇葩问题:内网运行正常,公网流媒体不通

最近在帮助EasyDarwin的用户部署EasyNVR+EasyDarwin云平台+EasyClient方案的过程中,遇到一个问题,EasyNVR分布在用户各地区现场的内网中,EasyDarwin云平...
  • xiejiashu
  • xiejiashu
  • 2016年09月18日 12:10
  • 1898

HelixServe搭建局域网流媒体服务器

查了两天资料,有了些眉目,在成功搭建数次之后把这篇博客补上       但成功搭建并不是一蹴而就的,从开始的一脸懵逼,到中途的困难频繁造访几欲放弃打算转向研究其他实现方式,再到最后的豁然开朗,真应...
  • u012407484
  • u012407484
  • 2016年06月19日 23:14
  • 4784
收藏助手
不良信息举报
您举报文章:直播服务器简单实现 http_flv和hls 内网直播桌面
举报原因:
原因补充:

(最多只允许输入30个字)