不厌其烦,请参考前文:SRS系列二——初步实现HLS直播
(此处对后期点播的实现作用极大,点播参考SRS系列四——实现点播功能(已真实应用))
srs实现hls直播时,会在默认配置./objs/nginx/html文件夹下产生m3u8文件和ts文件,看下图
m3u8 文件实质是一个播放列表(playlist),其内部文字使用的都是 utf-8 编码,此处内部信息记录的是一系列媒体片段资源,顺序播放该片段资源,即可完整展示多媒体资源。
***EXTM3U:***表明该文件是一个 m3u8 文件。每个 M3U 文件必须将该标签放置在第一行。
***EXT-X-VERSION:***表示 HLS 的协议版本号,该标签与流媒体的兼容性相关。该标签为全局作用域,使能整个 m3u8 文件;每个 m3u8 文件内最多只能出现一个该标签定义。如果 m3u8 文件不包含该标签,则默认为协议的第一个版本。
***EXT-X-MEDIA-SEQUENCE:***表示播放列表第一个 URL 片段文件的序列号。
***EXT-X-TARGETDURATION:***表示每个视频分段最大的时长(单位秒)。
***EXT-X-DISCONTINUITY:***该标签表明其前一个切片与下一个切片之间存在中断。
***EXTINF:***表示其后 URL 指定的媒体片段时长(单位为秒)。
***EXT-X-ENDLIST:***表明 m3u8 文件的结束。此处在直播过程中会一直产生ts文件,即使中断直播,也只是添加EXT-X-DISCONTINUITY标签,不会存在此标签,这也为我们以后实现点播功能提供了切入点。
***live/20200703/155550.ts:***表示ts文件在 ./objs/nginx/html路径下的路径。
下面我们来讲一下,hls的详细配置,可参考官方https://github.com/ossrs/srs/wiki/v3_CN_DeliveryHLS:
vhost __defaultVhost__ {
hls {
#是否开启HLS,on/off,默认off。
enabled on;
# 秒,指定ts切片的最小长度。实际上ts文件的长度由以下公式决定:
# ts文件时长 = max(hls_fragment, gop_size)
# hls_fragment:配置文件中的长度。譬如:5秒。
# gop_size:编码器配置的gop的长度,譬如ffmpeg指定fps为20帧/秒,gop为200帧,则gop_size=gop/fps=10秒。
#那么,最终ts的时长为max(5, 10) = 10秒。这也是为什么有些流配置了hls_fragment,
#但是ts时长仍然比这个大的原因。
# default: 10
hls_fragment 10;
# 倍数。控制m3u8的EXT-X-TARGETDURATION,
# EXT-X-TARGETDURATION = hls_td_ratio * hls_fragment // init
# EXT-X-TARGETDURATION = max(ts_duration, EXT-X-TARGETDURATION) // for each ts
# @see https://github.com/ossrs/srs/issues/304#issuecomment-74000081
# default: 1.5
hls_td_ratio 1.5;
#倍数。纯音频时,当ts时长超过配置的ls_fragment乘以这个系数时就切割文件。
# 例如,当ls_fragment是10秒,hls_aof_ratio是2.0时,对于纯音频,10s*2.0=20秒时就切割ts文件
# default: 2.0
hls_aof_ratio 2.0;
# 秒,指定HLS窗口大小,即m3u8中ts文件的时长之和,超过总时长后,
# 丢弃第一个m3u8中的第一个切片,直到ts的总时长在这个配置项范围之内。
# default: 60
hls_window 60;
# the error strategy. can be:
# ignore, disable the hls.
# disconnect, require encoder republish.
# continue, ignore failed try to continue output hls.
# @see https://github.com/ossrs/srs/issues/264
# default: continue
hls_on_error continue;
# HLS的m3u8和ts文件保存的路径。m3u8和ts文件都保存在这个目录中。
# default: ./objs/nginx/html
hls_path ./objs/nginx/html;
# HLS的m3u8文件名,包含可替换的[vhost],[app]和[stream]变量。
# default: [app]/[stream].m3u8
hls_m3u8_file [app]/[stream].m3u8;
# HLS的ts文件名,包含可替换的一系列变量,参考下面说明,[seq]是ts的seqence number。
# [vhost], the vhost of stream.
# [app], the app of stream.
# [stream], the stream name of stream.
# [2006], replace this const to current year.
# [01], replace this const to current month.
# [02], replace this const to current date.
# [15], replace this const to current hour.
# [04], replace this const to current minute.
# [05], replace this const to current second.
# [999], replace this const to current millisecond.
# [timestamp],replace this const to current UNIX timestamp in ms.
# [seq], the sequence number of ts.
# [duration], replace this const to current ts duration.
# default: [app]/[stream]-[seq].ts
hls_ts_file [app]/[stream]-[seq].ts;
# whether use floor for the hls_ts_file path generation.
# if on, use floor(timestamp/hls_fragment) as the variable [timestamp],
# and use enhanced algorithm to calc deviation for segment.
# @remark when floor on, recommend the hls_segment>=2*gop.
# default: off
hls_ts_floor off;
# TS的base url。可选默认为空字符串;非空时加在ts前面作为base url。
# 对于ts切片:live/livestream-0.ts
# 若配置为:hls_entry_prefix http://your-server;
# 则最后的TS的URL是:http://your-server/live/livestream-0.ts
hls_entry_prefix http://your-server;
# 默认的音频编码。当流的编码改变时,会更新PMT/PAT信息;默认是aac,因此默认的PMT/PAT信息是aac;如果流
# 是mp3,那么可以配置这个参数为mp3,避免PMT/PAT改变。
hls_acodec aac;
# 默认的视频编码。当流的编码改变时,会更新PMT/PAT信息;默认是h264。如果是纯音频HLS,可以配置为vn,可
# 以减少SRS检测纯音频的时间,直接进入纯音频模式。
hls_vcodec h264;
#是否删除过期的ts切片,不在hls_window中就是过期。可以关闭清除ts切片,实现时移和存储,使用自己的切片管理
# 系统。
hls_cleanup on;
# 在没有流时,HLS清理的过期时间(秒),系统重启或者超过这个时间时,清理HLS的所有文件,包括m3u8和ts。
# 默认为0,即不清理。
hls_dispose 0;
# 从notify服务器读取数据的长度。
hls_nb_notify 64;
# 是否按top切片,即等待到关键帧后开始切片。测试发现OS X和android上可以不用按go切片。
hls_wait_keyframe on;
#以下配置用的不多
# whether using AES encryption.
# default: off
hls_keys on;
# the number of clear ts which one key can encrypt.
# default: 5
hls_fragments_per_key 5;
# the hls key file name.
# we supports some variables to generate the filename.
# [vhost], the vhost of stream.
# [app], the app of stream.
# [stream], the stream name of stream.
# [seq], the sequence number of key corresponding to the ts.
hls_key_file [app]/[stream]-[seq].key;
# the key output path.
# the key file is configed by hls_path/hls_key_file, the default is:
# ./objs/nginx/html/[app]/[stream]-[seq].key
hls_key_file_path ./objs/nginx/html;
# the key root URL, use this can support https.
# @remark It's optional.
hls_key_url https://localhost:8080;
# Special control controls.
###########################################
# Whether calculate the DTS of audio frame directly.
# If on, guess the specific DTS by AAC samples, please read https://github.com/ossrs/srs/issues/547#issuecomment-294350544
# If off, directly turn the FLV timestamp to DTS, which might cause corrupt audio stream.
# @remark Recommend to set to off, unless your audio stream sample-rate and timestamp is not correct.
# Default: on
hls_dts_directly on;
}
}
下面是我在项目中实际用到的配置,可参考:
http_server {
enabled on;
listen 8089; # m3u8时的播放端口
dir ./objs/nginx/html; #m3u8和ts文件的相对路径
}
hls {
enabled on;
hls_fragment 5;
hls_window 86400; #ts总时长1天
hls_path ./objs/nginx/html; #m3u8和ts文件的相对路径
hls_m3u8_file [app]/[stream].m3u8; # m3u8文件在/objs/nginx/html下的路径
hls_ts_file [app]/[stream]/[2006][01][02]/[15][04][05].ts; # ts文件在/objs/nginx/html下的路径
hls_cleanup off; #不清除过期的ts文件
hls_dispose 86400; # 在没有流时,HLS清理的过期时间为1天
}
此处的回调功能,我自己在自己的微服务里提供了接口,接收srs传递过来的比如app,stream,param这些参数后,通过比如on_publish来判断推流的上线,然后利用那些参数做自己的业务逻辑,我这边涉及过鉴权、发送kafka等逻辑,可根据自己业务需要在每个回调接口里处理,如下所示:
on_connect :当客户端连接到指定的vhost和app时
on_close:当客户端关闭连接,或者SRS主动关闭连接时
on_publish:当客户端发布流时,譬如flash/FMLE方式推流到服务器
on_unpublish:当客户端停止发布流时
on_play:当客户端开始播放流时
on_stop:当客户端停止播放时。备注:停止播放可能不会关闭连接,还能再继续播放。
on_dvr :当DVR录制关闭一个flv文件时。
在配置时,只需将自己写好的回调接口配置上去即可。
比如:
http_hooks {
enabled on;
on_connect http://172.22.200.122:8000/api/v1/client/connect;
on_close http://172.22.200.122:8000/api/v1/client/close;
on_publish http://172.22.200.122:8000/api/v1/stream/publish;
on_unpublish http://172.22.200.122:8000/api/v1/stream/unPublish;
on_play http://172.22.200.122:8000/api/v1/session/play;
on_stop http://172.22.200.122:8000/api/v1/session/stop;
on_hls http://172.22.200.122:8000/api/v1/hls;
}
具体说明可参考:https://github.com/ossrs/srs/wiki/v3_CN_HTTPCallback
此处做一个提醒:官网上的每个回调接口的参数并不准确,可以自己调一下试试,根据版本不同上面的参数会有一点变动。