sergey-dryabzhinsky / nginx-rtmp-module

NGINX-based Media Streaming Server
http://nginx-rtmp.blogspot.com
BSD 2-Clause "Simplified" License
1.02k stars 214 forks source link

Playback stutters, #EXT-X-DISCONTINUITY on every segment #144

Open Jamedjo opened 8 years ago

Jamedjo commented 8 years ago

I'm feeding video files in on rtmp through ffmpeg and outputting hls. It plays fine on desktops but stutters when changing segment on iphone 4 and some android tablets. If I remove the #EXT-X-DISCONTINUITY tags and serve the files from a static location it works fine on ios.

Should these only appear when a new video is played through rtmp? How do I prevent #EXT-X-DISCONTINUITY tags appearing between every segment?

PS. Compiled using dev branch to support Nginx 1.11

Jamedjo commented 8 years ago

Had the same issue on master with nginx 1.8.1.

Setting -r 24 -x264opts keyint=24:min-keyint=24:scenecut=-1 gets rid of the DISCONTINUITY tags and fixes each EXTINF to 5.000 instead of varying significantly. Playback is much smoother, but unfortunately now cuts when changing quality on iOS. Could this be because the audio and video lengths don't match? How should I go about debugging this?

Jamedjo commented 8 years ago

It doesn't cut out on every hls_variant switch: most of the time it is fine, about once every 2m it will stutter and once every 10m cut out. When it stutters or cuts out the nginx log shows Client prematurely closed connection while sending response to client.

DavidVentura commented 8 years ago

I'm getting the same thing on master branch with nginx 1.9.11.

DavidVentura commented 8 years ago

Jamedjo would you please post your entire ffmpeg options? I keep getting the DISCONTINUITY tags.

movie.m3u8
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:11
#EXT-X-TARGETDURATION:15
#EXT-X-DISCONTINUITY
#EXTINF:9.985,
movie-11.ts
#EXT-X-DISCONTINUITY
#EXTINF:9.985,
movie-12.ts
chriswiggins commented 8 years ago

Can you guys please try adding the hls_continuous off; option into your config and see if this helps?

DavidVentura commented 8 years ago

That's the default and is not set on my server

Jamedjo commented 8 years ago

Had compiled our own ffmpeg (3.0.2) while attempting to use libfdk_aac, and used roughly the command below:

exec /usr/local/bin/ffmpeg -i rtmp://localhost:1935/live/livestream -c:v libx264 -vprofile baseline -r 24 -x264opts keyint=24:min-keyint=24:scenecut=-1 -sc_threshold 0 -b:v 800k -c:a aac -strict -2 -b:a 128k -tune zerolatency -preset veryfast -f flv rtmp://localhost/hls/livestream_high

I've just added hls_continuous off; and will see if that helps the Could not load movie iOS errors

Jamedjo commented 8 years ago

Line I'd uncommented was actually hls_continuous on;, but this didn't fix it. Also tried set to off, but had the same error after 7mins.

iOS error after about 15mins

DavidVentura commented 8 years ago

To test I use this: https://dailymotion.github.io/hls.js/demo/

It shows if there's discontinuity I haven't been able to fix it yet here. I don't know what might be it. These are my ffmpeg params

ffmpeg -i rtmp://localhost/rpi/$name -c:v libx264 -threads 4 -preset slow -r 24 -x264opts keyint=24:min-keyint=24:scenecut=-1 -g 48 -b:v 450k -bufsize 900k -vf "movie=/root/logo_videos.png [watermark]; [in][watermark] overlay=(main_w-overlay_w-10):(main_h-overlay_h-30) [out]" -c:a copy -f flv rtmp://localhost:1935/s2/$name 2>>/var/log/ffmpeg-$name.log;

This works on rtmp but breaks on hls

Jamedjo commented 8 years ago

The keyint settings are an alternative to -g, so probably shouldn't use both, or at least set them the same. http://superuser.com/questions/908280/what-is-the-correct-way-to-fix-keyframes-in-ffmpeg-for-dash

DavidVentura commented 8 years ago

copy3

This is what the discontinuity looks like. Grey is video, black is the discontinuity that shouldn't be here

DavidVentura commented 8 years ago

For now I'm using only the rtmp side of this and for hls I'm using ffmpeg.

ffmpeg -i rtmp://localhost/src/movie -c copy -flags -global_header -map 0 -bsf:v h264_mp4toannexb -hls_time 6 -hls_list_size 5 -hls_wrap 25 test.m3u8

Jamedjo commented 8 years ago

Does using ffmpeg for hls fix it? Was it easy to use for live broadcasts or was there additional setup?

DavidVentura commented 8 years ago

I literally run that command on exec_push and it works (well, its inside a .sh but it's the same).

I haven't really thought about doing level switching with it (it doesn't do automatically) but it already outputs in 2 qualities with:

#!/bin/sh

commonOpts="-flags -global_header -map 0 -bsf:v h264_mp4toannexb -hls_time 6 -hls_list_size 5 -hls_wrap 25"
cd /tmp/hls/
ffmpeg  -i rtmp://localhost/src/movie \
    -c copy $commonOpts /tmp/hls/movie.m3u8 \
    -c:a copy -c:v libx264 -s 360x270 -r 10 -g 20 -preset veryfast $commonOpts /tmp/hls/low.m3u8