1、音视频基础与RTMP协议入门

各位同学好,我是老张。今天咱们正式开始《Android音视频传输RTMP实战》的第一章。

说实话,音视频开发这个领域,入门门槛确实不低。我当年刚接触时也是一头雾水,什么采样率、码率、帧率,听着就头大。但你别怕,这些东西说白了就是几个数字游戏。咱们今天就把这些基础概念掰开揉碎了讲清楚。

1.1 音视频基础知识

先聊聊声音和图像在计算机里是怎么存的。你想想看,现实世界的声音是连续的波形,图像是连续的光信号。但计算机只能处理离散的0和1。所以我们需要「采样」——把连续信号变成离散数据。

采样率(Sample Rate)

采样率,简单说就是一秒钟采了多少个样。单位是Hz(赫兹)。

  • 8kHz:电话语音质量,够用但声音闷
  • 44.1kHz:CD音质,音乐常用
  • 48kHz:视频制作标准,我项目里最常用
我的经验:做直播推流时,音频采样率我一般选44.1kHz或48kHz。选低了声音发闷,选高了带宽扛不住。48kHz是行业默认标准,兼容性最好。

这里有个关键点——奈奎斯特采样定理。说白了就是:采样率至少要达到信号最高频率的两倍,才能完整还原。人耳能听到20Hz~20kHz,所以44.1kHz刚好覆盖。

码率(Bitrate)

码率就是一秒钟用了多少比特来编码。单位是bps(比特每秒),常用kbps或Mbps。

场景 视频码率 音频码率
标清直播(480p) 500~800 kbps 64~128 kbps
高清直播(720p) 1.5~3 Mbps 128 kbps
全高清(1080p) 4~8 Mbps 128~256 kbps
避坑指南:我曾经在一个项目里把视频码率设到10Mbps,结果用户手机网络一波动就卡成PPT。后来学乖了,直播场景建议用动态码率,或者至少做码率自适应。

码率和画质的关系,其实是个平衡问题。码率越高画质越好,但带宽要求也越高。我个人的习惯是:移动端直播用1.5~2.5Mbps,WiFi环境下可以上到4Mbps。

帧率(Frame Rate)

帧率就是一秒钟显示多少帧画面。单位是fps(frames per second)。

  • 24fps:电影标准,有胶片感
  • 30fps:电视/直播常用,流畅度够用
  • 60fps:游戏/体育直播,丝滑流畅

嗯,这里要注意:帧率不是越高越好。60fps虽然流畅,但编码压力大,手机发热也快。我做直播时一般选30fps,兼顾流畅度和性能。

核心公式:视频数据量 = 分辨率 × 帧率 × 色彩深度 × 压缩比。你想想看,1080p@30fps的原始数据量有多大?1920×1080×30×3字节 ≈ 178MB/s!所以必须压缩编码。

1.2 RTMP协议简介

RTMP全称Real-Time Messaging Protocol,实时消息传输协议。是Adobe搞出来的,主要用于直播推流。

为什么选RTMP?说白了就三个原因:

  1. 低延迟:端到端延迟可以做到1~3秒
  2. 兼容性好:几乎所有直播平台都支持
  3. 传输稳定:基于TCP,丢包会重传

RTMP工作在TCP之上,默认端口1935。它把音视频数据切成小块(chunk),然后一个个发出去。每个chunk可以独立解码,这样即使丢了一两个chunk,画面也不会全崩。

我记得刚开始做RTMP时,总搞不清它和HTTP-FLV、HLS的区别。简单说:

  • RTMP:推流用,延迟低,但需要Flash播放器(现在用WebRTC替代)
  • HTTP-FLV:拉流用,兼容性好,延迟也低
  • HLS:苹果家的,切片传输,延迟高但跨平台好

1.3 RTMP握手与连接流程

RTMP的握手流程,说白了就是客户端和服务器互相确认身份的过程。一共三步:

  1. C0/C1:客户端发版本号和随机数据
  2. S0/S1/S2:服务器回复版本号、随机数据,并确认客户端的随机数据
  3. C2:客户端确认服务器的随机数据

握手完成后,就可以建立连接了。连接流程是这样的:

  • 客户端发 connect 命令,带上应用名(比如 live)
  • 服务器回复 _result,表示连接成功
  • 客户端发 createStream 命令,创建流
  • 服务器回复 _result,返回流ID
  • 客户端发 publishplay 命令,开始推流或拉流
我的经验:握手阶段最容易出问题的是版本号不匹配。我曾经遇到一个服务器只支持RTMP 1.0,客户端发了3.0的版本号,结果一直握手失败。后来在代码里写死了版本号才解决。

下面这张图展示了RTMP从握手到推流的完整流程:

RTMP握手与连接流程 客户端 RTMP服务器 握手阶段 C0/C1 (版本号 + 随机数据) S0/S1/S2 (版本号 + 随机数据 + 确认) C2 (确认服务器随机数据) 连接阶段 connect (应用名: live) _result (连接成功) createStream _result (返回流ID) 推流阶段 publish (推流) 音视频数据 (持续发送)

你看,整个流程其实不复杂。握手3步,连接4步,然后就可以推流了。实际开发中,这些步骤都由RTMP库帮我们处理了,但理解底层原理对排查问题很有帮助。

注意:RTMP握手是阻塞的。如果网络不好,握手超时会导致连接失败。我建议在客户端设置合理的超时时间,一般5~10秒就够了。太短容易误判,太长用户体验差。

好了,第一章的内容就到这里。采样率、码率、帧率这些基础概念,你只要记住它们决定了音视频的质量和带宽消耗。RTMP协议的核心就是握手+连接+推流三步走。下一章咱们会深入RTMP的chunk格式和消息类型,到时候手写一个简单的RTMP推流器。


公众号:蓝海资料掘金营,微信deep3321