欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

怎么搭建hls低延时直播(lowlatency hls)

程序员文章站 2022-07-06 18:00:24
...

转载请注明出处:https://blog.csdn.net/impingo
项目地址:https://github.com/im-pingo/nginx-rtmp-module

hls延时现状

hls延时太大是众所周知的情况,网上也有非常多的资料分析为何产生那么大的延时。然而降低延时的方案却非常少。

血脉纯正的lowlatency hls方案

2019年WWDC大会上苹果公司提出了lowlatency hls解决方案,声称要将延时降低到2s以内。但是据同行公开的测试结果表示目前苹果官方设备还没有完全支持这种方案。
由于这套方案是基于http2.0实现的,实现过程非常复杂,大规模推广需要得到CDN厂商和各个浏览器厂商的大力支持。
这是非常大的软件升级,真正落地不知是何年月,甚至最终在其真正推广开来之前是否会出现更优的解决方案都未可知。
所以就目前而言使用苹果提出的lowlatency hls方案实现低延时是不现实的。
这里有个lowlatency hls解决方案的说明和测试资料大家可以参考。

出身草根的HLS+

网上有人提出过hls+的解决方案,大概思路就是为每个播放端维护一个虚拟session。
第一 保证第一个切片以最近的I帧开始,第二 保证切片足够小(小于等于1s)。
实际测试下来延时大概能够缩小到4s左右。例如这篇文章提到的解决方案

这种解决方案虽然看起来是比较野路子一些,但是确实目前实现成本最低(基于http 1.0 或者 1.1 没有对m3u8做任何改动)并且可维护性更高的一种方案。它的优点正如这篇文章提到的:
(1)大幅降低传统HLS协议的延时;

(2)HLS+与RTMP/FLV等协议共用同一个流媒体服务器集群,CDN网络可省一套设备组(众多机房和设备建设);

(3)HLS+与RTMP/FLV/HLS等使用同一个域名,用户配置简单,使用简单,域名CNAME简单;

(4)数据统一,系统给出的在线人数,带宽,计费,防盗链,鉴权认证等,全部统一实现,无需单独区分协议;

(5)合并回源,访问RTMP/FLV/HLS+只需回一路RTMP,并且是访问时才回源,大幅降低了客户源站带宽与回源压力;

(6)快速排错,HLS+使用观止云BMS可追溯日志,可以毫秒级抓取到每个客户端链接数据,实现快速排错;

(7)快速启动,通过GOP优化能做到无感官差异的快速启动;

(8)避免404,HLS是切片文件分发,会有一定概率的404,而HLS+为流式回源杜绝了此情况;

(9)避免每次回源取片的时间,HLS每个切片从源站到边缘都得回源,而HLS+使用长连接回源。

使用开源项目pingo搭建hls+服务

项目地址:https://github.com/im-pingo/nginx-rtmp-module

pingo项目是基于nginx-rtmp-module实现的支持hls hls+ http-ts http-flv rtmp多种直播协议的流媒体服务器,并且当前已经有数家公司在使用。其他协议的配置可以参考我之前的文章分布式直播系统(二)【搭建单点rtmp\http-flv\hls流媒体服务器】,里面详细介绍了各个协议的配置方法并且有详细的配置模板。
这里只提供hls+的配置模板。

user  root;
daemon on;
master_process on;
worker_processes  1;
#worker_rlimit 4g;
#working_directory /usr/local/openresty/nginx/logs;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
error_log  logs/error.log  info;

worker_rlimit_nofile 102400;
worker_rlimit_core   2G;
working_directory    /tmp;

#pid        logs/nginx.pid;

events {
    use epoll;
    worker_connections  1024;
    multi_listen unix:/tmp/http 80;
}

stream_zone buckets=1024 streams=4096;

rtmp {
    log_format log_json '{$remote_addr, [$time_local]}';
    access_log logs/rtmp.log trunc=2s;
    server {
        listen 1935;
        serverid 000;
        out_queue 2048;
   
        application live {
            rtmp_auto_pull on;
            rtmp_auto_pull_port unix:/tmp/rtmp;
            live on;
            hls on;
            hls_path /tmp/hls;
            hls_fragment 1300ms;
            hls_max_fragment 1800ms;
            hls_playlist_length 3900ms;

            hls2memory on;
            mpegts_cache_time 20s;

            hls2_fragment 1000ms;
            hls2_max_fragment 1300ms;
            hls2_playlist_length 3000ms;

            wait_key on;
            wait_video on;
            cache_time 3s;
            low_latency off;
            fix_timestamp 0s;
# h265 codecid, default 12
            hevc_codecid  12;
        }
    }
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_X-Forwarded-For" "$http_X-Real-IP" "$host"';


    access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #reset_server_name www.test1.com www.test2.com;
    #gzip  on;
    server {
         listen 80;
        location /rtmp_stat {
            rtmp_stat all;
            rtmp_stat_stylesheet /stat.xsl;
        }

        location /xstat {
            rtmp_stat all;
        }

        location /sys_stat {
            sys_stat;
        }

         location /live {
            flv_live 1935;
         }
         location /hls {
            # Serve HLS fragments
             types {
                 application/vnd.apple.mpegurl m3u8;
                 video/mp2t ts;
             }
             root /tmp;
             expires -1;
             add_header Cache-Control no-cache;
         }

        location /hls2 {
             hls2_live 1935 app=live;
         }
        location /hls3 {
            proxy_pass http://unix:/tmp/http.0:/hls2;
        }
         location / {
             chunked_transfer_encoding on;
             root html/;
         }
    }
}

使用上面的配置模板测试推流:
rtmp推流地址:rtmp://ip/live/{ip}/live/{stream}
hls+ (http短连接)播放地址:http://ip/hls2/{ip}/hls2/{stream}
hls+ (http长连接)播放地址:http://ip/hls3/{ip}/hls3/{stream}
http-flv播放地址:http://ip/live/{ip}/live/{stream}
rtmp播放地址:rtmp://ip/live/{ip}/live/{stream}

hls+ 测试效果

以上面的配置模板为例,推流端设置为2s gop大小,最终测试延时大概在4s~5s。
hls+与http-flv、rtmp和传统hls直播延时的对比情况如图:
怎么搭建hls低延时直播(lowlatency hls)

QQ交流群:697773082(流媒体人)