Android 音视频——直播推流技术指南

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

一、推流架构

推流SDK客户端的模块主要有三个推流采集端、队列控制模块、推流端。其中每个模块的主要流程如下本文的主要目的就是拆分推流流程

1.1 采集端

视频采集通过Camera采集视频。

音频采集通过麦克风采集音频。

视频后处理美颜、滤镜、贴纸、翻转等特效。

音频后处理重采样、3A处理等。

视频编码支持硬编码和软编码同时支持H264和HEVC编码特别要注意编码的特殊情况。

音频编码AAC编码

采集端的很多功能都是平台相关的相机采集、编码等Android和iOS上处理都不一样。尤其是Android平台很多机型和芯片当然会有一些特殊的情况需要兼容下这个后面我们会详细描述的。

1.2 队列控制

队列控制模块是推流SDK非常重要的控制模块推流SDK就是一个很简单的“生产者——消费者模型”采集端是生产者推流端是消费者采集端采集的是本地数据推流端和服务端交互正常情况下都是推流端会出现延迟像弱网情况下推流端消费肯定会很慢但是采集端速度并不会慢下来如果没有队列控制这个降压阀那很多数据就会堆积在队列中本地数据不断堆积最终导致OOM。

队列控制应该如何控制

视频的数据比音频大很多所以队列控制主要是视频基准音频跟着视频相应丢帧。

编码之后视频队列大小设置为60在推流的过程中发现视频的队列已满需要丢弃队列最前面的一帧然后再入队新的一帧音频队列也要同步操作对应时间点的音频数据也要丢掉。

1.3 推流端

推流采用的是RTMP协议RTMP是Adobe公司开发的算是事实上的工业标准全称是Real Time Messaging Protocol虽然实时性要比HLS好一点但是也还有几秒左右的延迟。它的底层是基于TCP协议。

RTMP协议的建连流程如下

RTMP建连需要商量两件事情

  • 版本号客户端和服务器的版本号不一致无法继续工作

  • 时间戳视频播放过程中时间戳很重要如果没有后续的音视频同步无法继续开展。

首先客户端发送 C0 表示自己的版本号不必等对方的回复然后发送 C1 表示自己的时间戳。服务器只有在收到 C0 的时候才能返回 S0表明自己的版本号如果版本不匹配可以断开连接。服务器发送完 S0 后也不用等什么就直接发送自己的时间戳 S1。客户端收到 S1 的时候发一个知道了对方时间戳的 ACK C2。同理服务器收到 C1 的时候发一个知道了对方时间戳的 ACK S2。

推流的过程就是将 NALU 放在 Message 里面发送这个也称为 RTMP Packet 包。Message 的格式就像这样。

一定要记住音频和视频的头部要单独发送在发送视频头部的视频需要将NALU起始标识符去掉RTMP不需要它们。

三、技术要点

3.1 声音处理

在采集完声音之后需要对音频进行3A处理即声学回声消除AEC、背景噪声抑制ANS、自动增益控制AGC3A处理在声音后期处理中非常重要在推流场景的声音处理中应用十分广泛。

  • AEC

回声消除AEC是指在二线传输的两个方向上同时间、同频谱地占用线路在线路两个方向传输的信号完全混在一起本端发信号的回波就成为了本端信号的干扰信号利用自适滤波器可抵消回波以达到较好的接收信号质量即为回声消除。

回声消除的原理就是利用接收到的音频与本地采集的音频做对比添加反向的人造回声将远端的声音消除。

  • ANS

背景噪声抑制ANS指的是将声音中的背景噪声识别并进行消除的处理。

背景噪声分平衡噪声瞬时噪声平稳噪声频谱稳定瞬时噪声频谱能量方差小利用噪声的特点对音频数据添加反向波形处理即可消除。

目前对于平稳的噪声已经有很多种简单方法能够成功抑制但是生活中常见的一些瞬态噪声却依然缺乏好办法。

瞬态噪声的共同特点就是突发性极强在时域上呈振荡衰弱的形式持续时间在十几毫秒至上百毫秒不等在频域上分布很宽瞬态噪声的频谱基本上是和正常语音的频谱混叠在一起很难进行抑制。

  • AGC

自动增益控制AGC主要用于调整音量幅值提高语音通信系统在带噪声环境中的性能。

人们正常交谈的音量在 40-60dB 之间低于 25dB 的声音听起来很吃力而超过 100dB 的声音会让人感到不适AGC 的作用就是将音量调整到人接受的范围

音频响度及麦克风拾音控制是保证音视频沟通质量的重要技术手段一般来说音频标准、传输条件、人为失误等因素都可能导致音频信号之间出现声音突变或者响度不一致的情况这时候就需要对音频信号放大或缩小以得到自然清晰的语音通信。

3.2 视频处理

相机采集的原始数据首先要进行帧处理主播通常会应用一些特效例如美颜、滤镜等这些都会在视频帧后处理流程中开展帧处理之后才会进行编码处理。

H264和H265编码还有点不同。

H264头部由SPS和PPS组成SPS是序列参数集包括一个图像序列的所有信息如图像尺寸、视频格式等PPS是图像参数集包括一个图像的所有分片的相关信息如图片类型、序列号。

H264的码流结构如下

起始码 + SPS + 起始码 + PPS + 起始码 + SEI + 起始码 + I帧 + 起始码 + P帧 + …

H265头部除了SPS和PPS之外还有一个VPSVPS是视频参数集。

H265码流结构如下

起始码 + VPS + 起始码 + SPS + 起始码 + PPS + 起始码 + SEI + 起始码 + I帧 + 起始码 + P帧 + …

其中H264和H265的码流类型有两种一种是Annexb格式另一种是MP4格式使用最广泛的还是Annexb格式本文主要以Annexb为例。

起始码只是起到分割的作用并不是有效的视频数据起始码也有两种

  • 4字节的00 00 00 01

  • 3字节的00 00 01

但是图像编码中也有可能出现00 00 00 01和00 00 01出现这种情况怎么办

  • 00 00 00 修改为 00 00 03 00

  • 00 00 01 修改为 00 00 03 01

  • 00 00 02 修改为 00 00 03 02

  • 00 00 03 修改为 00 00 03 03

这样在编码的过程中就不会出现混淆了。

3.3 推流控制

上文也说了在采集端和推流段其实是通过一个队列控制的采集端采集本地的视频和音频然后编码好了放入队列中推流段从队列中取出视频和音频然后根据特定的格式发送到服务端。相当于采集端是往水池中注水推流段是放水。

采集端是很快的推流段是受限于网络的如果网络状态比较好的情况下可以达到一个较好的平衡但是一旦网络变差队列就会出现堆积我们不可能让队列无限堆积需要设置一个队列阈值当然队列已满需要将队列中原有的数据抛弃将新数据入队。这样就会出现丢帧这时候推流段可以适当降低码率降低丢帧的概率。

3.4 支持FLV-HEVC

flv 是不支持H265的需要手动修改FLV支持H265编码和解码的解析当然也需要拉流段支持FLV-H265。


考虑到有些小伙伴想学习音视频知识点但不知道从哪开始入手下面小编整理了份《音视频学习笔记》供大家进行参考学习里面是从入门到进阶的一个过程笔记。

音视频初级入门

音视频初级入门主要是接触Android多媒体展示相关的API通过单独的列举和使用这些API对Android音视频处理有一个基本的轮廓虽然知识点相对来说是比较散的但是点成线、线成面基本的基础掌握了通过学习Android音视频核心的API将音视频的流程串联起来这样对于音视频的了解和控制就不仅仅局限于最外层的API了而是能够通过相对底层的方式来加深对Android 音视频开发的认知。

  • Android 音视频开发(一)通过三种方式绘制图片
  • Android 音视频开发(二)使用 AudioRecord 采集音频PCM并保存到文件
  • Android 音视频开发(三)使用 AudioTrack 播放PCM音频
  • Android 音视频开发(四)使用 Camera API 采集视频数据
  • Android 音视频开发(五)使用 MediaExtractor 和 MediaMuxer API 解析和封装 mp4 文件
  • Android 音视频开发(六)MediaCodec API 详解
  • Android 音视频开发(七)音视频录制流程总结
  • ……

音视频中级进阶OpenSL ES 学习https://0a.fit/BzPVh

学习 Android 平台 OpenSL ES API了解 OpenSL 开发的基本流程使用OpenSL播放PCM数据并了解相关API的简单使用

  • Android OpenSL ES 开发Android OpenSL 介绍和开发流程说明
  • Android OpenSL ES 开发使用 OpenSL 播放 PCM 数据
  • Android OpenSL ES 开发Android OpenSL 录制 PCM 音频数据
  • Android OpenSL ES 开发OpenSL ES利用SoundTouch实现PCM音频的变速和变调
    这一部分主要是动手实践积累实战经验可以试试给自己定以下目标
  • 使用 OpenGL 显示一张图片
  • GLSurfaceviw 绘制 Camera 预览画面及实现拍照
  • 使用OpenGL ES 完成视频的录制并实现视频水印效果

  • Android OpenGL ES 开发一: OpenGL ES 介绍
  • Android OpenGL ES 开发二: OpenGL ES 环境搭建
  • Android OpenGL ES 开发三: OpenGL ES 定义形状
  • Android OpenGL ES 开发四: OpenGL ES 绘制形状
  • Android OpenGL ES 开发五: OpenGL ES 使用投影和相机视图
  • Android OpenGL ES 开发六: OpenGL ES 添加运动效果
  • Android OpenGL ES 开发七: OpenGL ES 响应触摸事件
  • Android OpenGL ES 开发八: OpenGL ES 着色器语言GLSL
  • Android OpenGL ES 开发九: OpenGL ES 纹理贴图
  • Android OpenGL ES 开发十: 通过GLES20与着色器交互
  • ……

音视频高级探究https://0a.fit/BzPVh

  • 深入学习音视频编码如H.264AAC研究使用开源编解码库如x.264JM 等
  • 深入研究音视频相关的网络协议如 rtmphls以及封包格式如flvmp4
  • 深入学习一些音视频领域的开源项目如 webrtcffmpegijkplayerlibrtmp 等等
  • 将 ffmpeg 库移植到 Android 平台结合上面积累的经验编写一款简易的音视频播放器
  • 将 x264 库移植到 Android 平台结合上面积累的经验完成视频数据 H264 软编功能
  • 将 librtmp 库移植到 Android 平台结合上面积累的经验完成 Android RTMP 推流功能

音视频编解码技术https://0a.fit/BzPVh

  • 音视频编解码技术一MPEG-4/H.264 AVC 编解码标准
  • 音视频编解码技术二AAC 音频编码技术
  • ……

流媒体协议

  • 流媒体协议一HLS 协议
  • 流媒体协议二RTMP协议
  • ……

多媒体文件格式https://0a.fit/BzPVh

  • 多媒体文件格式一MP4 格式
  • 多媒体文件格式二FLV 格式
  • 多媒体文件格式三M3U8 格式
  • 多媒体文件格式四TS 格式
  • 多媒体文件格式五PCM / WAV 格式
  • ……

FFmpeg 学习https://0a.fit/BzPVh

  • FFmpeg命令行工具学习(一)查看媒体文件头信息工具ffprobe
  • FFmpeg命令行工具学习(二)播放媒体文件的工具ffplay
  • FFmpeg命令行工具学习(三)媒体文件转换工具ffmpeg
  • FFmpeg命令行工具学习(四)FFmpeg 采集设备
  • FFmpeg命令行工具学习(五)FFmpeg 调整音视频播放速度
  • ……

  • FFmpeg 学习(一)FFmpeg 简介
  • FFmpeg 学习(二)Mac下安装FFmpeg
  • FFmpeg 学习(三)将 FFmpeg 移植到 Android平台
  • FFmpeg 学习(四)FFmpeg API 介绍与通用 API 分析
  • FFmpeg 学习(五)FFmpeg 编解码 API 分析
  • FFmpeg 学习(六)FFmpeg 核心模块 libavformat 与 libavcodec 分析
  • ……

  • FFmpeg 结构体学习(一)AVFormatContext 分析
  • FFmpeg 结构体学习(二)AVStream 分析
  • FFmpeg 结构体学习(三)AVPacket 分析
  • FFmpeg 结构体学习(四)AVFrame 分析
  • FFmpeg 结构体学习(五)AVCodec 分析
  • FFmpeg 结构体学习(六)AVCodecContext 分析
  • FFmpeg 结构体学习(七)AVIOContext 分析
  • FFmpeg 结构体学习(八)FFMPEG中重要结构体之间的关系
  • ……

  • FFmpeg 开发之 AVFilter 使用流程总结
  • FFmpeg 过时 Api 汇总整理
  • ……

音视频学习有着一定门槛光看是绝对做不到精通音视频的只有一步一步积累顺着正确的方向不断深入学习才可以做到更好~:https://0a.fit/BzPVh

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: android