简体   繁体   English

低延迟DASH Nginx RTMP

[英]Low Latency DASH Nginx RTMP

I use arut nginx-rtmp-module ( https://github.com/arut/nginx-rtmp-module ) on the media server, then I tried to stream using FFmpeg to the dash application, then I test the stream by playing it using VLC. 我在媒体服务器上使用arut nginx-rtmp-module( https://github.com/arut/nginx-rtmp-module ),然后我尝试使用FFmpeg流式传输到dash应用程序,然后我通过播放来测试流使用VLC。

And it waits around 30secs to start playing, and it plays from the beginning, not the current timestamp. 它等待大约30秒开始播放,它从头开始播放,而不是当前的时间戳。

This is my current config on the RTMP block 这是我在RTMP块上的当前配置

rtmp {
    server {
        listen 1935;

        application live {
            live on;

           exec ffmpeg -re -i rtmp://localhost:1935/live/$name
              -c:a libfdk_aac -b:a 32k  -c:v libx264 -b:v 128K -f flv rtmp://localhost:1935/hls/$name_low
              -c:a libfdk_aac -b:a 64k  -c:v libx264 -b:v 256k -f flv rtmp://localhost:1935/hls/$name_mid
              -c:a libfdk_aac -b:a 128k -c:v libx264 -b:v 512K -f flv rtmp://localhost:1935/hls/$name_hi
              -c:a libfdk_aac -b:a 128k -c:v libx264 -b:v 512K -f flv rtmp://localhost:1935/dash/$name_dash;
        }

        application hls {
             live on;

             hls on;
             hls_path /tmp/hls;
             hls_nested on;

             hls_variant _low BANDWIDTH=160000;
             hls_variant _mid BANDWIDTH=320000;
             hls_variant _hi  BANDWIDTH=640000;
        }

        application dash {
            live on;

            dash on;
            dash_path /tmp/dash;
            dash_nested on;
        }
    }
}

This is the command I use for streaming 这是我用于流式传输的命令

ffmpeg -re -i 2014\ SPRING.mp4 -c copy -f flv 
rtmp://52.221.221.163:1935/dash/spring

How can I reduce the delay, and make it play from the same timestamp as the streamer? 如何减少延迟,并使其与流媒体的时间戳相同?

Can I achieve under 5s latency? 我能达到5秒以下的延迟吗?

UPDATE UPDATE

Tried to change the playlist length and fragment length, using this directive 尝试使用此指令更改播放列表长度和片段长度

dash_playlist_length 10s;
dash_fragment 2s;

But still got some latency problem, sometimes it's smaller than before, sometimes it's the same 但仍然存在一些延迟问题,有时它比以前小,有时它是相同的

Can I achieve under 5s latency? 我能达到5秒以下的延迟吗?

No. DASH is a segmented protocol, meaning your media is chopped up into relatively large chunks. DASH是一种分段协议,意味着您的媒体被切割成相对较大的块。 The player has to download some chunks before it can start playing them. 玩家必须先下载一些块才能开始播放它们。 Your encoder has to upload entire chunks before these chunks even appear in the manifest. 您的编码器必须在这些块甚至出现在清单中之前上传整个块。 This is the wrong tool for the job, and any attempts at reducing latency by cranking the chunk size down are adding massive overhead to your project. 这是工作的错误工具,任何通过降低块大小来减少延迟的尝试都会给项目增加大量开销。 You're using the wrong tool for the job if latency is important to you . 如果延迟对您很重要,那么您正在使用错误的工具

How can I reduce the delay, and make it play from the same timestamp as the streamer? 如何减少延迟,并使其与流媒体的时间戳相同?

You can't. 你不能。 Physics! 物理! It's impossible for you to play the same thing at the exact same time as it is being encoded. 你不可能在编码的同时播放同样的东西。 You're sending data over a packet-switched network, with many encoding/decoding steps in the way which all require a buffer as they work in chunks. 您通过分组交换网络发送数据,其中许多编码/解码步骤都需要缓冲区,因为它们以块的形式工作。 The only way to playback what's coming in simultaneously is to go analog... at least there your only delay is the speed of light. 回放同时播放内容的唯一方法是去模拟...至少在那里,你唯一的延迟就是光速。

The best you can do is switch to a protocol designed for low latency, like WebRTC. 您可以做的最好的事情是切换到专为低延迟而设计的协议,例如WebRTC。 Just be sure you understand the tradeoffs. 只要确定你理解权衡。 Your codecs will be optimized for latency, not quality... so your quality will suffer. 您的编解码器将针对延迟而非质量进行优化...因此您的质量将受到影响。 WebRTC over UDP (optional but common) means that some packets will get lost, causing your viewing experience to suffer. WebRTC over UDP(可选但常见)意味着某些数据包会丢失,导致您的观看体验受损。 When you care about latency, it doesn't matter so much if you lose a chunk here or there, what matters is that you keep going. 当你关心延迟时,如果你在这里或那里丢失了一块,那么重要的是你继续前进。 You can use WebRTC over TCP and keep your reliability at only a slight increase in latency. 您可以通过TCP使用WebRTC,并使您的可靠性仅略微增加延迟。

Decide what really matters to you. 确定对你来说真正重要的事情。 In almost every case, it isn't actually low latency. 几乎在所有情况下,实际上并不是低延迟。 You can't have it all ways. 你无法全力以赴。 There are tradeoffs to every approach. 每种方法都有权衡。 You must decide what is best for your specific situation. 您必须决定什么是最适合您的具体情况。

I also have the same issue with VLC media player. 我对VLC媒体播放器也有同样的问题。 Most of the latency is by the client player, you can use the ffplayer with no buffer to check it. 大多数延迟是由客户端播放器,您可以使用没有缓冲区的ffplayer来检查它。

ffplay -fflags nobuffer rtmp://192.168.1.66/myapp/live

Results of mine, 我的结果,

  • latency of VLC: 6~7s VLC的潜伏期:6~7s
  • latency of ffplay: 500ms ffplay的延迟:500ms

For more refer to comment of narlex of issue how to reduce latency on github 有关如何减少 github 延迟的问题,请参阅narlex的评论

You may need to change the GOP size in ffmpeg command. 您可能需要在ffmpeg命令中更改GOP大小。 The default GOP size for ffmpeg is 250 which means there will be a key frame every 250 frames. ffmpeg的默认GOP大小为250,这意味着每250帧会有一个关键帧。 If your output is 25fps, then you will have a key frame every 10s in worst case (if scene cut detection is enabled, you may have shorter key frame interval). 如果您的输出是25fps,那么在最坏的情况下您将每10秒有一个关键帧(如果启用了场景剪切检测,则可能有更短的关键帧间隔)。

For both HLS and DASH, the segments must start with a key frame. 对于HLS和DASH,段必须以关键帧开始。 So you will have a lot of segments with 10s duration. 所以你会有很多段,持续时间为10秒。 You need to reduce the segment duration (the GOP size) in order to reduce latency. 您需要减少段持续时间(GOP大小)以减少延迟。

Try to modify your ffmpeg command as follow to see if it helps 尝试修改您的ffmpeg命令,如下所示,看它是否有帮助

exec ffmpeg -re -i rtmp://localhost:1935/live/$name
          -c:a libfdk_aac -b:a 32k  -c:v libx264 -g 50 -b:v 128K -f flv rtmp://localhost:1935/hls/$name_low
          -c:a libfdk_aac -b:a 64k  -c:v libx264 -g 50 -b:v 256k -f flv rtmp://localhost:1935/hls/$name_mid
          -c:a libfdk_aac -b:a 128k -c:v libx264 -g 50 -b:v 512K -f flv rtmp://localhost:1935/hls/$name_hi
          -c:a libfdk_aac -b:a 128k -c:v libx264 -g 50 -b:v 512K -f flv rtmp://localhost:1935/dash/$name_dash;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM