Search code examples
nginxffmpeghttp-live-streamingrtmp

Streaming HLS with Nginx & FFMPEG : How to prevent repeating or skipping scenes (.ts) when playback?


I set up HLS streaming server using Nginx & FFMPEG, then i watch it using vlc or ffplay on another pc. The problem is sometimes it repeating scenes or skipping scenes for few seconds then it continue like normal, it happens at random but occurs occasionally and not always on the same spots.

Here is sample of ffplay log:

[http @ 000002c6e2611c00] Opening 'http://172.20.120.75:8080/hls/test-3.ts' for reading
[hls @ 000002c6e260bcc0] Skip ('#EXT-X-VERSION:3')sq=    0B f=0/0
[hls @ 000002c6e260bcc0] Skip ('#EXT-X-DISCONTINUITY')
[http @ 000002c6e2614500] Opening 'http://172.20.120.75:8080/hls/test-3.ts' for reading
[http @ 000002c6e2611c00] Opening 'http://172.20.120.75:8080/hls/test-4.ts' for reading
[http @ 000002c6e81c8140] Opening 'http://172.20.120.75:8080/hls/test.m3u8' for reading
[hls @ 000002c6e260bcc0] Skip ('#EXT-X-VERSION:3')sq=    0B f=1/1
[hls @ 000002c6e260bcc0] Skip ('#EXT-X-DISCONTINUITY')
[http @ 000002c6e2614500] Opening 'http://172.20.120.75:8080/hls/test-3.ts' for reading
[http @ 000002c6e2611c00] Opening 'http://172.20.120.75:8080/hls/test-4.ts' for reading
[http @ 000002c6e81c8140] Opening 'http://172.20.120.75:8080/hls/test.m3u8' for reading
[hls @ 000002c6e260bcc0] Skip ('#EXT-X-VERSION:3')sq=    0B f=2/2
[http @ 000002c6e2614500] Opening 'http://172.20.120.75:8080/hls/test-6.ts' for reading
[http @ 000002c6e2611c00] Opening 'http://172.20.120.75:8080/hls/test-7.ts' for reading
[http @ 000002c6e81c8140] Opening 'http://172.20.120.75:8080/hls/test.m3u8' for reading
[hls @ 000002c6e260bcc0] Skip ('#EXT-X-VERSION:3')sq=    0B f=2/2
[http @ 000002c6e2614500] Opening 'http://172.20.120.75:8080/hls/test-7.ts' for reading
[http @ 000002c6e81c8140] Opening 'http://172.20.120.75:8080/hls/test.m3u8' for reading
[hls @ 000002c6e260bcc0] Skip ('#EXT-X-VERSION:3')sq=    0B f=2/2
[http @ 000002c6e2611c00] Opening 'http://172.20.120.75:8080/hls/test-8.ts' for reading

From that log, repeating scenes are : test-3.ts, test-4.ts, test-7.ts, and skipped scene : test-5.ts.
My question is: how to prevent this?

When i checked .m3u8 playlist on server side it seems normal, no repeated or skipped .ts file. Here is .m3u8 file:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:17
#EXT-X-TARGETDURATION:4
#EXTINF:3.600,
test-1.ts
#EXTINF:3.560,
test-2.ts
#EXTINF:3.600,
test-3.ts
#EXTINF:3.600,
test-4.ts
#EXTINF:3.600,
test-5.ts
#EXTINF:3.600,
test-6.ts
#EXTINF:3.600,
test-7.ts
#EXTINF:3.520,
test-8.ts
#EXTINF:3.600,

My Nginx Configuration:

worker_processes 4;
events {
        worker_connections 1024;
        use epoll;
        multi_accept on;
}

# RTMP configuration
rtmp {
    server {
        listen 1935; # Listen on standard RTMP port
        chunk_size 4096;

        application show {
            live on;
            # Turn on HLS
            hls on;
            hls_path /tmp/hls/;
            hls_fragment 3;
            hls_playlist_length 60;
            # disable consuming the stream from nginx as rtmp
            deny play all;
        }
    }
}

http {
        sendfile off;
        tcp_nopush on;
        tcp_nodelay on;
        reset_timedout_connection on;
        directio 512;
        default_type application/octet-stream;

    server {
        listen 8080;

        location /hls {
            # Disable cache
            add_header 'Cache-Control' 'no-cache';
            access_log off;
            # CORS setup
            add_header 'Access-Control-Allow-Origin' '*' always;
            add_header 'Access-Control-Expose-Headers' 'Content-Length';
            # allow CORS preflight requests
            if ($request_method = 'OPTIONS') {
                add_header 'Access-Control-Allow-Origin' '*';
                add_header 'Access-Control-Max-Age' 1728000;
                add_header 'Content-Type' 'text/plain charset=UTF-8';
                add_header 'Content-Length' 0;
                return 204;
            }

            types {
                application/dash+xml mpd;
                application/vnd.apple.mpegurl m3u8;
                video/mp2t ts;
            }

            root /tmp/;
        }
location /nginx_status {
        # Turn on stats
        stub_status on;
        allow all;
    }
}
}

My FFMPEG Command :

ffmpeg -re -stream_loop -1 -i 'video1.mp4' -vcodec libx264 -vprofile baseline -g 30 -acodec aac -strict -2 -f flv 'rtmp://172.20.120.75/show/test' &

Thank You for Your Help.


Solution

  • Okay, so i found out that the problem is caused by the latest nginx-rtmp-module. I use module from https://github.com/sergey-dryabzhinsky/nginx-rtmp-module , as of today the latest version is still version 1.2.2-r1. Fortunately i found my old server with older version of nginx-rtmp-module (probably from two or three years ago) and when i reconfigured my new server using older nginx-rtmp-module the problem is fixed.

    If anyone wants to see the difference, i put video comparison when i use latest version here , vs when i use older version here .
    And if anyone wants to check my nginx-rtmp-module that i use i will also include it here:
    Latest nginx-rtmp-module
    Older nginx-rtmp-module
    Latest module should be the same with the one available on github currently (version 1.2.2-r1), but i'm not sure about older module though as when i compare it with version 1.1.7.10 it seems a bit different, cmiiw.

    My setup : OS Ubuntu 22.04 LTS , NGINX 1.23.0 , FFMPEG 4.4.2