arut / nginx-rtmp-module

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

how make video straming real-time without delays, because of some buffers in hls.js and nginx-rtmp-module #899

Open proxy-m opened 7 years ago

proxy-m commented 7 years ago
Steps to reproduce
  1. Use nginx + nginx-rtmp-module for streaming as HLS.
  2. Use ffmpeg to move online video stream from RTSP camera to nginx.
  3. Use hls.js to get HLS stream from nginx in browser JavaScript.
Expected behavior

No some seconds video delay from real time video.

Actual behavior

Delay near 15 or even more seconds, because of video buffering.

Question:

How to make buffers minimum as possible (e.g. something like 1 second or even less)? I need real-time online streaming.

tolsee3 commented 7 years ago

So, you are using ffmpeg as a encoder of camera? I think the problem is that ffmpeg is slower than what apple recommended command line tools. Have you ever tried with apple command line tools?

proxy-m commented 7 years ago

I don't change stream by ffmpeg. I copy it as is: h.264. I only change container: 1) form rtsp (camera) to flv-rtmp (nginx) 2) then nginx-rtmp change it to HLS 3) then I get it with HLS.js on browser side.

Aslai commented 7 years ago

Short answer: You're probably out of luck. HLS is inherently laggy.

Edit: You can take a look at the hls_fragment and hls_playlist_length options, which appear to let you specify chunk length and playlist length. I don't know the performance implications, but can probably reduce latency with them to a few seconds.

Due to the way HLS works, the closest to real-time you can get is around 5 seconds of delay (See edit). The stream is split into several chunks of approximately 5 seconds each (though it's implementation dependent, again, see edit), and they are not made available until the entire chunk is ready, so the minimum stream delay is the length of one chunk.

Since the length of chunks can potentially vary by a few seconds, most players will play content from one or two chunks behind the latest chunk. Even the official twitch player plays one chunk behind the latest chunk. Many HLS players will start from the oldest chunk available though, which can possibly entail a 30+ second delay.

In my own personal experience, playing HLS incurs a delay of around 15 seconds with default configured players and servers. This is why I still use RTMP for low latency applications, where I can get the latency down to sub-second with the right configuration. The only downside of course is that you need a native application or plugin (flash) to display it.

jgmio commented 7 years ago

RTSP also requires a negotiation phase (UDP / TCP) I'm using GStreamer and this phase can delay input for 5+ seconds. I believe this depends on firewall settings and the like. I do not have a workaround besides trying to get your input from another protocol, or force TCP transfer instead of the default UDP.

As @Aslai said: HLS serves chunks of files (default is 10 seconds?). Meaning that first nginx-rtmp waits for the first 10 seconds to be recorded to file. The client can then download the file (X time) Then start playing.

Again as @Aslai said, you can set the hls_fragment to reduce this