我通过 ffmpeg 使用 hls 流。
在流媒体开始时,存在几秒钟的延迟。
当我想在存在非常延迟的情况下从流中传输 4k 视频时。
我能做什么?
4k 视频
...
在流媒体开始时存在几秒钟的延迟
是的,当然可以。缓冲足够的数据来播放非常高的比特率需要时间。不仅如此,您的 HLS 播放器在解码开始之前通常需要一些片段。正如 @iangetz 所说,您可以减少段长度,但现在由于所有额外的 HTTP 请求,您将有更多的开销。
减少 HLS 流式传输的延迟
不要使用 HLS。 HLS 以及任何其他分段流协议(如 DASH)都针对低延迟进行了优化。它针对 HTTP CDN 的重复使用、能够在网络变化(例如从 WiFi 变为 LTE 时)下继续播放以及客户端可选(通常是动态)质量进行了优化。
分段协议的本质要求将相对较大的缓冲区进行分块,然后单独上传到服务器/CDN。这确实很有用,但如果您需要低延迟,则不是一个好的权衡。
如果延迟对您很重要,那么您需要一种完全不同的技术。看看 WebRTC。通过这项技术,视频流可以实时传输,编解码器针对延迟而非质量进行优化,并且可靠性会降低以利于延迟。它还需要对分销基础设施进行大量投资。
我无法想象关心 4k 视频的人会认为降低质量以换取低延迟是值得的。你不可能拥有你想要的一切......你必须选择对你真正重要的东西并从那里进行优化。如果您想要低延迟,您将不得不降低质量并在基础设施上花费大量金钱和时间来支持这一工作。如果您想要高质量和可靠的流,您可以在使用 DASH(或 HLS)在现有的基于 HTTP 的 CDN 上进行分发的同时保持良好的编码参数。
这可能是播放器在开始播放之前用足够的内容填充了缓冲区。
您可以使用“hls_time”减小视频片段的大小,以便每个片段的下载速度更快,但这会给您的服务器带来更多的 HTTP 请求。此外,您可以使用“hls_init_time”减少第一个段,并按原样保留其他段。
http://ffmpeg.org/ffmpeg-all.html#hls-1
hls_init_time 秒 设置初始目标段长度 秒。默认值为 0。片段将在下一个关键帧处被剪切 过了这个时间后,第一个 m3u8 列表就出来了。初始后 播放列表已满 ffmpeg 将在持续时间等于 hls_时间
hls_time 秒 设置目标片段长度(以秒为单位)。默认 值为 2。该时间之后的下一个关键帧将剪切片段 已经过去了。
另一个选择是减少播放器开始播放之前所需的缓冲区量。我不确定您使用的是什么播放器,但大多数都有此选项。
对于 HLS 和其他流格式,有多种选项可以控制 ffmpeg 中的延迟(请参阅此问题以获取一些示例)。 “社区”低延迟 (LHLS) 在主要 HLS 播放器之一 (hls.js) 中得到支持,但现在已已被弃用,取而代之的是 Apple 的低延迟 HLS。
在我看来,LHLS 并没有那么“棒”。请注意,通常 HLS 编码为 6 秒长的片段,对于 LHLS,建议将其设置为 2 秒。 现在,这是变得棘手的部分。如果您有一群用户和几个 Web 服务器来提供片段,您认为如果您的片段只有 2 秒,它会是什么样子。长的?您的服务器看起来像是受到了 DDOS 攻击,因为您必须交付超过 2 倍的段,因为切片时间缩短至 2 秒。我个人使用 9 秒长的片段,并将播放器设置为缓冲至少 2-3 分钟的视频。因此有足够的时间在后台获取 9 秒长的片段(此处为 VideoJS)。
此外,使用 9 秒长的片段,客户端生成的 http 请求更少。例如,如果您作为 CDN 提供商在 CloudFlare 上运行,也许启用了 Cloudflare 负载均衡器,那么您还需要支付更少的费用,因为您生成的请求更少,欢呼。