HLS流媒体

HLS Spec

#EXTM3U

#EXT-X-TARGETDUATION:10

#EXT-X-MEDIA-SEQUENCE:0

#EXTINF:10

fileSequence0.ts

Maseter Playlist:

#EXTM3U

#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=20000000

gear1/prog_index.m3u8

Media Segments

由一个uri和一个可选的byte range来组成。有一个唯一的sequence number;必须是连续的不能被中断;包含足够的信息来初始化decoder,如H.264包含一个IDR帧。

支持的媒体格式

有MPEG2-ts, Fragmented MPEG-4

Playlists

如果一个playlist中所有的uri是一个playlist,那么就是一个master playlist。

PlayList Tags

ExTM3U扩展的M3U播放文件
EXT-X-VERSION兼容的版本
EXT-X-TARGETDURATION最大的Media Segment duration
EXT-X-MEDIA-SEQUENCEmedia的序列号
EXT-X-DISCONTINUITY-SEQUECE在不同的流的听众之间同步
EXT-X-I-FRAMES-ONLY所有的segment都描述了一个I-frame
EXT-X-MEDIA

被用来在PlayList中表示相同内容的不用语种/译文的版本,比如可以通过使用3个这种tag表示3中不用语音的音频,或者用2个这个tag表示不同角度的video在PlayLists中。这个标签是独立存在的,其格式如下:

#EXT-X-MEDIA:<attribute-list>:该属性列表中包含:URI、TYPE、GROUP-ID、LANGUAGE、NAME、DEFAULT、AUTOSELECT。

(a) URI:如果没有,则表示这个tag描述的可选择版本在主PlayList的EXT-X-STREAM-INF中存在;

(b) TYPE:AUDIO and VIDEO;

(c) GROUP-ID:具有相同ID的MEDIA tag,组成一组样式;

(d) LANGUAGE:确定使用的主要语言。

(e) NAME:人类可读的语言的翻译。

(f) DEFAULT: YES或是NO,默认是No,如果是YES,则客户端会以这种选项来播放,除非用户自己进行选择。

(g) AUTOSELECT:YES或是NO,默认是No,如果是YES,则客户端会根据当前播放环境来进行选择(用户没有根据自己偏好进行选择的前提下)。
————————————————
版权声明:本文为CSDN博主「路痴的旅行」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u011857683/article/details/84863250

EXT-X-STREAM-INF

指定一个包含多媒体信息的 media URI 作为PlayList,一般做M3U8的嵌套使用,它只对紧跟后面的URI有效,格式如下:

#EXT-X-STREAM-INF:<attribute-list>

<URI>

有以下属性:

(a) BANDWIDTH:带宽,必须有。

(b) PROGRAM-ID:该值是一个十进制整数,惟一地标识一个在PlayList文件范围内的特定的描述。一个PlayList 文件中可能包含多个有相同ID的此tag。(这个属性在后面的协议版本废除了)

(c) CODECS:指定流的编码类型,不是必须的。

(d) RESOLUTION:分辨率。

(e) AUDIO:这个值必须和AUDIO类别的“EXT-X-MEDIA”标签中“GROUP-ID”属性值相匹配。

(f) VIDEO:这个值必须和VIDEO类别的“EXT-X-MEDIA”标签中“GROUP-ID”属性值相匹配。

示例:

#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=500000, RESOLUTION=720x480

mid_video_index.M3U8
 

HLS playback

Android HLS播放过程

HLS prepare的过程,取消带宽切换,记录以前的带宽index:morigBandwidthIndex,目前的带宽Index:mCurBandwidthIndex; streamMask:新的URI流,resumeMask:uri没有变得流。

在ChangeConfiguration中,停止和抛弃不在需要的fetcher,如果目前的uri和新的rui相同,使用原来的fetcher,否则disFetcher=ture;

在seek的过程中,触发kwhatChangeConfiguration2,否则发送kwhatconfiguration3

处理kwahtchangeconfiguration2时,seek time>0, 清理掉已经缓冲的mPacketSource中的buffer

处理KwhatConfiguration3时,如果uri有变换,设置switching为true,依据新的URI或新增的流创建PlaylistFetcher;

PlaylistFetch:监控缓冲队列,刷新播放列表,触发下载

HttpDownload:由于下载指定的ts

ATSParser:解析相应的playlist

AnotherPacketSource:保存相应的解析的数据

数据获取的流程

从Nuplayerdecoder的onRequesetInputBuffers->httpLivesource的dequeueAccessUnit->LiveSession的dequeueAccessunit-> AnotherPacketSource

然后queue到MediaCodec

Seek过程

根据seek的时间、firstSeqNumberInPlaylist、lastSeqNumberPlayList,获取seek的时间位于那个片段n+1内,然后startTimeUs=seektime-(0.......n)总时间为startimeUs,设置mStartTimeUsRelative=true;在seek的过程中,如果是H264,需要判断是否是IDR帧,如果是isStartTimeReached,开始保存数据。

Playlist的更新

如果每次检测playlist都没有变化,时间就会相应的增加:

INITIAL_MIINIMUM_RELOAD_DELAYitemDuration-10s
FIRST_UNCHANGED_RELOAD_ATTEMPTtargetDuration/2-5s
SECOND_UNCHANGED_RELOAD_ATTEMPTtargetDuration*3/2
THIRD_UNCHANGED_RELOAD_ATTEMPTtargetDuration*3 -30s

在refreshPlaylist中:如果发现没有变化mRefreshState+1

HLS buffering

1.获取当前缓冲的buffer的时间,如果缓冲的时间小于30s,会立刻启动下载

2.如果大于30s,就会计算下一次监控buffer的delayUS

delay的时间取决于两个要素,第一个是多缓冲的时间,和刷新playlist的时间。

多缓冲的时间T1=buffer duration-minbuffer duration

刷新的时间:T2=mLastPlaylistFetchTime+minPlaylistAgeUs-Now

delay=min(T1,T2);

带宽切换 

通过提供不同的带宽和下载速度下的资源,可以做到动态切换分辨率;主要依据两个变量,一个是实际带宽,另外一个是缓存的大小;

如果实际的带宽大于阈值,并且缓存大于阈值,就上升带宽;

如果实际带宽小于阈值,并且缓存小于阈值,就下降带宽。

带宽的计算:下载量/下载时间;

每一个ts被按照47K分片进行下载,然后记录每次下载的size,duration,和开始下载的时间。队列中的最后一项的开始时间减去第一项的就是有效期;

 当队列中的数据满足条件后,会每1s检测一次带宽;计算好的bw仍然会被保存在长度为3的带宽队列里面;

短期带宽:去对应带宽队列中的带宽的,数据队列中的item,然后是size的总和/duration;

带宽稳定性的检测:

当max小于等于最小的133%时,短期带宽大于min的70%时,是稳定的;最大最小来自带宽队列。

Buffer检测:

往下切换,min(20,targetDuration*9/4);

往上切换,min(15, targetDuration*7/4);

如果所有的track都大于kupSwitchMarkUs就会往上切换;任何一个小于kDownSwthcMarkUs就往下切换。

启动时间计算

 带宽上升时:

 

9const int64_t LiveSession::kUpSwitchMarginUs = 5000000ll;

下降:

 

带宽数据的合并:

如果带宽切换的过程中,如果下载的新数据的时间戳-旧数据时间戳大于限制,启动旧数据下载;

否则,结束旧数据下载,合并mPacketSource2和mPacketSource的数据。

ATS Parser:

TS流的包结构长度固定为188字节,而PS流的包长度可变。

节目关联表(Program Association Table,PAT)

标识    位数    说明
sync_byte    8 bits    固定是0x47
transport_error_indicator    1 bits    值为0,表示当前包没有发生传输错误。
payload_unit_start_indicator    1 bits    值为1,负载数据从包头数据1字节后开始
transport_priority    1 bits    值为0,表示当前包是低优先级。传输优先级标志(1:优先级高)
PID    13 bits    PID=0x0000,说明是PAT表。
transport_scrambling_control    2 bits    值为0x00,表示节目没有加密。
adaptation_field_control    2 bits    值为0x01,改Packet区域含控制调整字段
continuity_counter    4 bits    值为0x00,表示当前传送的相同类型的包是第0个。
节目映射表(Program Map Table, PMT)

 

PMT表中包含的数据如下:

  • 当前节目中所有Video ES流的PID
  • 当前节目所有Audio ES流的PID
  • 当前节目PCR的PID等。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值