直播延时讲解

转载请注明出处:https://blog.youkuaiyun.com/impingo
项目地址:https://github.com/im-pingo/pingos

直播延时出现的原因

在单个服务器节点的情况下,延时出现在三个地方,推流端、服务器、播放端

推流
推流端
服务器
播放端

推流端造成的延时(TCP连接)

推流端处理流程,直播内容采集→编码→封包→缓存→发送
由于采集、编码和封包高度依赖硬件配置,所以不在本文章的讨论范围内。
发送端的主要延时原因在于缓存,那么为何会有缓存呢?我们可以将采集编码看做一个生产者,编码数据在直播过程中会不断地产生,如果网络问题导致发送失败或者发送阻塞,那么新产生的编码数据就会将旧数据覆盖导致旧数据丢失,所以需要缓存来存储新生成的编码数据。如果某个时间段内网络状况差,导致数据发送不及时,发送缓存就会增加,延时也就会增加,等到网络恢复,发送端再尽可能多地将缓存中的数据发送给服务器。
到这里推流端的延时原理已经说完了,下面讲一下服务器端是如何造成延时的。

服务器端造成的延时

上面提到,发送端为了应对网络抖动,需要将数据缓存起来,服务器端同样将收到的数据加入缓存。但是服务器端加缓冲除了为了应对抖动之外还有一个重要的原因是让播放端实现秒开功能。
服务器的缓存长度一般为gop(关键帧间隔)的整数倍,这么做的原因是播放端解码需要从关键帧开始,那么服务器向播放器端下发数据的时候就必须从关键帧的位置开始下发。
为什么实现播放器秒开功能需要在服务器端添加缓存?

播放器一般要缓存够一定长度的数据后才开始解码播放。为了让播放器马上播放,服务器就要一次性给播放器下发足够的数据。

播放器造成的延时

上文中描述秒开功能时已经提高播放器端也有一个缓存,这个缓存存在的意义在于,如果某一段时间内服务器到播放器的网络不好,播放器可以播放缓存里的数据,等网络恢复后服务器将积累的数据尽量发给播放器,播放器再填充本地缓存。通过这样的操作,播放端看起来播放效果会更好,即使出现短时间的网络抖动,画面也不至于会卡。

总结延时原因

延迟端原因缓存大小
推流端应对网络抖动不定,可配置
服务器应对网络抖动、实现秒开功能不定,可配置,大于等于整数个gop
播放端应对网络抖动不定,可配置

下篇文章将介绍如何降低直播延时。

QQ交流群:697773082

QQ交流群:697773082

<think>嗯,用户想了解延时函数的概念和用法,特别是作用、原理、实现方法、使用场景和编程教程。首先,我需要从提供的引用中找到相关信息。引用1提到延时函数用于在程序中引入延迟,暂停执行,应用场景有LED闪烁、按键去抖、通信协议时序控制等。作用应该包括暂停程序、控制时序、模拟延迟。原理可能涉及阻塞式等待或系统调用,比如Arduino的delay函数通过检查系统时钟实现。实现方法方面,引用5展示了Arduino的代码,使用delay函数,而引用2提到了Linux下用usleep和nanosleep。引用4中的回调函数可能和异步处理有关,但用户可能更关注同步延时。需要区分不同系统下的实现,比如单片机、Linux、Python等。使用场景要列举LED控制、按键去抖、通信协议、模拟测试这些。编程教程部分需要提供示例代码,比如Arduino和Python的例子。还要注意注意事项,比如阻塞式延时的缺点,在实时系统中需谨慎使用。可能的问题包括如何避免阻塞,替代方法如使用定时器中断或异步编程。需要确保回答结构清晰,分点说明,并正确引用资料。还要生成相关问题,比如原理、优化方法、应用场景对比等。检查是否符合格式要求,数学公式用$...$,独立公式用$$...$$,但可能这里不需要数学公式。最后确保用中文,语法正确,引用标识自然添加。</think>### 延时函数的概念与用法详解 #### 1. **作用** 延时函数的主要功能是让程序在指定时间内暂停执行,常用于以下场景: - **硬件控制**:如LED闪烁、舵机转动时序调节[^1][^5]。 - **信号处理**:按键去抖(消除机械开关的抖动干扰)。 - **通信协议**:满足UART、I2C等协议的时序要求。 - **模拟测试**:模拟真实环境中的延迟现象[^2]。 #### 2. **原理** 延时函数的核心原理是通过**阻塞式等待**或**系统级时间检查**实现: - **阻塞式**:程序持续检查系统时钟,直到达到预定时间后才继续执行(如Arduino的`delay()`)[^5]。 - **非阻塞式**:通过定时器中断或异步任务实现,允许程序在等待期间执行其他操作(需结合硬件或操作系统特性)[^4]。 数学表示(阻塞式延时): $$ t_{\text{current}} = t_{\text{start}} + \Delta t $$ 其中$\Delta t$为预设的延时时间,程序循环检测当前时间$t_{\text{current}}$是否满足条件。 #### 3. **实现方法** **示例1:Arduino中的阻塞式延时** ```cpp void setup() { pinMode(13, OUTPUT); // 初始化引脚13为输出模式 } void loop() { digitalWrite(13, HIGH); delay(500); // 阻塞500ms,期间无法执行其他操作 digitalWrite(13, LOW); delay(500); // 再次阻塞500ms } ``` 此代码实现LED闪烁,但会占用全部CPU时间。 **示例2:Linux下的非阻塞延时(C语言)** ```c #include <unistd.h> usleep(500000); // 微秒级延时(500ms) // 或使用更高精度的nanosleep struct timespec delay = {0, 500000000}; // 500ms nanosleep(&delay, NULL); ``` 此方法通过系统调用实现,允许操作系统调度其他任务。 **示例3:Python中的延时** ```python import time time.sleep(0.5) # 延时0.5秒 ``` #### 4. **使用场景对比** | 场景 | 推荐方法 | 注意事项 | |--------------|------------------------|------------------------| | 实时性要求高 | 定时器中断或异步延时 | 避免阻塞主程序 | | 简单硬件控制 | 阻塞式延时(如Arduino)| 代码简单,但效率低 | | 高精度需求 | 系统级API(如nanosleep)| 依赖操作系统支持 | #### 5. **编程教程要点** - **Arduino入门**:使用`delay()`控制LED,但需注意其阻塞特性。 - **Linux应用开发**:优先选择`usleep`或`nanosleep`以实现任务调度。 - **优化建议**:在需要多任务处理的场景中,改用状态机或事件驱动模型[^4]。 #### 注意事项 - **阻塞风险**:长时间阻塞可能导致系统无响应[^5]。 - **精度限制**:软件延时会受系统负载影响,硬件定时器更精确。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值