美文网首页
音视频流媒体开发【四十八】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