美文网首页
音视频流媒体开发【四十八】RTMP流媒体4-直播推拉流

音视频流媒体开发【四十八】RTMP流媒体4-直播推拉流

作者: AlanGe | 来源:发表于2023-04-21 11:06 被阅读0次

音视频流媒体开发-目录
iOS知识点-目录
Android-目录
Flutter-目录
数据结构与算法-目录
uni-pp-目录

  1. 推流分析
  2. 拉流分析

RTMP流媒体Demo

第一章 推流分析

1 推流框架

PCM S16交错 -> float 棋盘格类型
采样率

  1. 模块初始化顺序
  2. 采集时间戳
  3. 音视频编解码
  4. 音视频编码队列控制
  5. 关键时间点
1.1 模块初始化顺序

推流模块(网络连接耗时) > 音视频编码模块 >音视频采集模块()

1.2 采集时间戳-帧间隔模式

优点:能输出frame duration稳定的音视频时间戳。

风险:
(1)当系统负载比较重时有可能初学采集间隔不稳定的情况,比如 预计1秒采集25帧图像,但实际采集了20帧,而音视频的时间戳是通过帧 间隔累计的,这样计算出来的时钟就不正确了。
(2)帧间隔涉及到无限小数时,比如预计30帧,通常按帧间隔33毫秒处理, 但实际是33.3333333毫秒。累积3333帧(约111秒)就出现1秒的误差。

1.2 采集时间戳-直接系统时间模式

优点:能够实时纠正时间戳,只要系统正常运转,就能立即恢复正确的时间戳。

风险:帧间隔不均匀,能否正常播放依赖于终端。

比如,假如音频一帧间隔为24毫秒,被采集的回调时间可能为20毫秒,28毫秒,27毫秒,21毫秒。

1.2 采集时间戳-帧间隔+直接系统时间模式

优点:大部分音视频帧的frame duration都稳定。

风险:纠正时间戳时可能会造成画面卡顿的感觉。

1.3 音视频编解码模块

关键点:

  1. 编码前:pts
  2. 编码后:dts(发送的时间戳)
  3. 封装成avframe送编码器后frame的释放
  4. 接收packet后数据的释放
1.4 音视频队列的控制
  1. 音频帧数量
  2. 视频帧数量
  3. 视频超过阈值时drop帧
    1. 直到检测到I帧停止
  4. 音频超过阈值时:
    1. drop帧;
    2. 重采样提高缩短播放时间再发送(不能简单进行重采样,需要变速不变调 sonic)
1.5 关键时间点

关键点:

  1. 采集到的第一帧视频时间
  2. 采集到的第一帧音频时间
  3. 视频第一帧编码时间
  4. 音频第一帧编码时间
  5. rtmp发送第一帧视频完成时间
    1. sequence 帧
    2. i帧
  6. rtmp发送第一帧音频完成时间
    1. sequence帧
    2. 数据帧
1.6 其他
  1. 发送数据阻塞检测,在RTMP_SendPacket函数前后加打印监 测发送耗时,比如耗时超过200ms打印警告。

  2. av队列 队列的监测,帧数, 队列数据持续播放的时间

推流后,拉流端拉流不正常:
A. 使用ffplay或者vlc进行拉流double check,根据不同的错误信息进行排查
1 如果是编码错误则需要dump编码前和编码后的数据,用ffplay进行播放;
2 如果是时间戳的问题则需要调整发送时间戳,检测时间戳是否是递增

第二章 拉流实战

2 拉流框架

  1. 模块初始化顺序
  2. 音视频数据队列(packetqueue)控制 3. 音视频解码
  3. 音频重采样
  4. 视频尺寸变换
  5. 音视频帧队列
  6. 音视频同步
  7. 关键时间点check
  8. 其他
2.1 模块初始化顺序

推流模块(网络连接耗时) > 音视频编码模块 >音视频采集模块()

音视频输出模块 >音视频解码模块 > 拉流模块

本质上来讲,就是在数据到来之前准备好一切工作

2.2 音视频数据队列

音视频队列涉及到

  1. Audio PacketQueue 还没有解码的
  2. VideoPacketQueue
    两者独立

队列设计要点:

  1. 可控制队列大小
    1. 根据packet数进行控制
    2. 根据总的duration进行控制 音频48khz, 21.3毫秒, 21.3*20 = 426ms
    3. 支持packet的size进行入队列累加,出队列则减,300,200,400,字节累加
  2. 支持packet数量统计
  3. 支持packet的duration进行入队列累加,出队列则减
  4. 支持阻塞和唤醒

目的:

  1. 统计延迟(缓存时间长度)
2.2 音视频数据队列

音视频队列涉及到

  1. AudioPacketQueue
  2. VideoPacketQueue
    两者独立

队列设计要点:

  1. 可控制队列大小
    1. 根据packet数进行控制
    2. 根据总的duration进行控制
  2. 支持packet数量统计
  3. 支持packet的size进行入队列累加,出队列则减
  4. 支持packet的duration进行入队列累加,出队列则减
  5. 支持阻塞和唤醒
2.3 音视频解码

关键点:

  1. 编码前: dts
  2. 编码后: pts
  3. packet释放
  4. frame释放
  5. 返回值处理
2.4 音频重采样

音频重采样模块AudioResampler:

注意重采样后不能直接使用linesize进行大小判断,需要使用

int size = av_get_bytes_per_sample((AVSampleFormat)(dstframe->format)) * dstframe->channels * dstframe->nb_samples ;

2.5 视频尺寸变换

图像尺寸变换模块ImageScaler:变换尺寸大小

性能的提升可以考虑 libyuv

2.6 音视频解码后帧队列

FrameQueue 解码后的数据量比较大,需要要控制解码后帧队列的大小 参考ffplay固定大小

#define VIDEO_PICTURE_QUEUE_SIZE 3  // 图像帧缓存数量
#define SUBPICTURE_QUEUE_SIZE 16    // 字幕帧缓存数量
#define SAMPLE_QUEUE_SIZE 9         // 采样帧缓存数量
#define FRAME_QUEUE_SIZE FFMAX(SAMPLE_QUEUE_SIZE, FFMAX(VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE))
2.7 音视频同步

Avsync模块
目前只支持audio master的方式。

2.8 各个模块关键时间点的监测
2.9 其他
  1. 客户端的首帧秒开,本质上就是不做同步先把第一帧显示出来。

  2. 推流没有问题时,如果拉流不能正常播放:

    1. 没有声音:dumprtmp拉流后的数据是否可以正常播放
    2. 声音异常:是否有解码错误报告,重采样前的pcm数据是否正常
    3. 没有图像:dumprtmp拉流后的数据是否可以正常播放
    4. 画面异常:是否有解码错误报告,scale前的数据是否正常

服务器首帧秒开:这个功能不能降低延迟

相关文章

网友评论

      本文标题:音视频流媒体开发【四十八】RTMP流媒体4-直播推拉流

      本文链接:https://www.haomeiwen.com/subject/brzdjdtx.html