Reduce HLS latency from +30 seconds

avconv, http-live-streaming, nginx

Solution

The answer detailing reducing the hls_playlist to 4s and the hls_fragment to 1s is good. However, it is important to note that if the source video has a key frame interval greater than the hls_fragment length then nginx will usually have to create longer fragments and the latency will increase.

The lowest latency we have achived was with the hls_fragment at 1s and the source video key frame interval also at 1s. With these settings we achieved latency of less than 7 seconds.

Problem

Ubuntu 12.04 nginx 1.2.4 avconv -version ``` avconv version 0.8.10-4:0.8.10-0ubuntu0.12.04.1, Copyright (c) 2000-2013 the Libav developers built on Feb 6 2014 20:56:59 with gcc 4.6.3 avconv 0.8.10-4:0.8.10-0ubuntu0.12.04.1 libavutil 51. 22. 2 / 51. 22. 2 libavcodec 53. 35. 0 / 53. 35. 0 libavformat 53. 21. 1 / 53. 21. 1 libavdevice 53. 2. 0 / 53. 2. 0 libavfilter 2. 15. 0 / 2. 15. 0 libswscale 2. 1. 0 / 2. 1. 0 libpostproc 52. 0. 0 / 52. 0. 0 ``` I'm using avconv and nginx to create an HLS stream but right now my latency is regularly well over 30 seconds. After much reading I am aware that HLS has built in latency and that 10s is expected and even preferred but 30s seems quite extreme. I've seen a lot of discussion on the nginx-rtmp google group, this thread in particular had a lot of suggestions. I have attempted to reduce solve my issue by reducing the `hls_fragment` and the `hls_playlist_length` but they haven't had a significant effect. nginx.conf: ``` #user nobody; worker_processes 1; error_log logs/error.log debug; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 8888; server_name localhost; add_header 'Access-Control-Allow-Origin' "*"; location /hls { types { application/vnd.apple.mpegurl m3u8; video/mp2t ts; } root /tmp; } # rtmp stat location /stat { rtmp_stat all; rtmp_stat_stylesheet stat.xsl; } location /stat.xsl { # you can move stat.xsl to a different location root /usr/build/nginx-rtmp-module; } # rtmp control location /control { rtmp_control all; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } } rtmp { server { listen 1935; ping 30s; notify_method get; application myapp { live on; hls on; hls_path /tmp/hls; hls_base_url http://x.x.x.x:8888/hls/; hls_sync 2ms; hls_fragment 2s; #hls_variant _low BANDWIDTH=160000; #hls_variant _mid BANDWIDTH=320000; #hls_variant _hi BANDWIDTH=640000; } } } ``` avconv command: ``` avconv -r 30 -y -f image2pipe -codec:v mjpeg -i - -f flv -codec:v libx264 -profile:v baseline -preset ultrafast -tune zerolatency -an -f flv rtmp://127.0.0.1:1935/myapp/mystream ``` Edit I know that it's not avconv that is the bottleneck because I am also producing an RTMP stream using nginx. This RTMP stream has a very small delay (couple of seconds).

Original source