二、音视频基础概念:采样率、位深、声道、帧率、分辨率、编码格式(H.264/H.265/AAC/MP3)等核心术语解析

在Android音视频系统开发中,无论是播放器、录制器、音视频编辑器还是实时通信模块,所有功能都建立在一组基础概念之上。如果对这些术语的理解停留在“听说过”的层面,后续面对PCM数据缓冲、编码参数配置、画面卡顿优化等问题时就会寸步难行。本章将系统拆解音频与视频领域的核心术语,从物理原理到工程参数,从原始数据到压缩编码,帮助你建立完整的知识坐标系。

音视频核心概念全景图 音频域(Audio Domain) 采样率 (Sample Rate) 单位:Hz / kHz 位深 (Bit Depth) 单位:bit / sample 声道 (Channels) Mono / Stereo / 5.1 编码格式 AAC / MP3 / Opus 视频域(Video Domain) 分辨率 (Resolution) 1920×1080 / 3840×2160 帧率 (Frame Rate) 单位:fps 编码格式 H.264 / H.265 / VP9 码率 (Bitrate) 单位:kbps / Mbps 同步 原始数据 → 编码压缩 → 封装传输 → 解码还原 PCM / YUV AAC / H.264 MP4 / MKV PCM / YUV 采样率 × 位深 × 声道数 = 音频码率(bps) 分辨率 × 帧率 × 色彩深度 ≈ 视频原始码率(bps) 码率 = 采样率 × 位深 × 声道数(音频) | 码率 = 分辨率 × 帧率 × 色彩深度(视频原始)

2.1 音频核心参数:采样率、位深与声道

2.1.1 核心原理:从模拟到数字的量化过程

音频数字化本质上是将连续变化的声波信号转换为离散的数字序列。这个过程包含两个关键步骤:采样(Sampling)和量化(Quantization)。采样率决定每秒从连续信号中抽取多少个样本点,位深决定每个样本点用多少比特来表示其振幅精度。

根据奈奎斯特采样定理,采样率必须大于信号最高频率的两倍才能无失真重建原始波形。人耳听觉范围约为20Hz-20kHz,因此CD标准的44.1kHz采样率(略高于40kHz)足以覆盖人耳感知范围。而96kHz甚至192kHz采样率主要用于专业录音和母带处理,为后期处理留出频率余量。

位深则决定了动态范围。每个比特位对应约6dB的动态范围,16bit位深提供96dB动态范围,24bit提供144dB。更高的位深意味着更细腻的振幅分辨率和更低的量化噪声,尤其在录制低响度信号时优势明显。

2.1.2 判断方法:如何选择音频参数

在Android开发中,选择音频参数需要根据应用场景权衡质量与性能:

  • 语音通话:采样率8kHz-16kHz,位深16bit,单声道即可满足清晰度要求,同时大幅降低带宽占用。
  • 音乐播放:采样率44.1kHz或48kHz,位深16bit或24bit,立体声是标配。
  • 专业录音:采样率96kHz,位深24bit,多声道(如5.1环绕声)用于影视后期。
  • 流媒体传输:采样率44.1kHz,位深16bit,立体声,配合AAC编码实现128kbps-256kbps的码率。

Android的AudioRecord和AudioTrack API中,采样率、位深和声道数直接对应PCM数据缓冲区的计算:缓冲区大小 = 采样率 × 位深/8 × 声道数 × 时长。例如,1秒的44.1kHz、16bit、立体声PCM数据量为:44100 × 2 × 2 = 176,400字节。

2.1.3 案例拆解:Android录音参数配置实战

假设我们需要开发一个录音功能,要求输出适合微信发送的音频文件。微信语音消息通常使用AMR-NB或AAC编码,采样率16kHz或44.1kHz。我们选择以下配置:

// Android录音参数配置示例
private static final int SAMPLE_RATE = 44100;      // 44.1kHz CD标准
private static final int CHANNEL_CONFIG = AudioFormat.CHANNEL_IN_STEREO; // 立体声
private static final int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;  // 16bit位深

int bufferSize = AudioRecord.getMinBufferSize(
    SAMPLE_RATE, CHANNEL_CONFIG, AUDIO_FORMAT);
AudioRecord recorder = new AudioRecord(
    MediaRecorder.AudioSource.MIC,
    SAMPLE_RATE, CHANNEL_CONFIG, AUDIO_FORMAT, bufferSize);

这里选择44.1kHz而非48kHz,是因为最终要编码为AAC格式,44.1kHz是音乐行业标准采样率,兼容性更好。16bit位深在移动设备上足够,24bit会增加处理开销且对麦克风硬件要求更高。立体声虽然数据量翻倍,但能保留空间感,适合录制环境音。

经验提醒:在Android上获取最小缓冲区大小时,不同设备返回的值差异很大(从几百字节到几十KB不等)。建议使用AudioRecord.getMinBufferSize()返回值乘以2作为实际缓冲区,避免缓冲区过小导致音频数据丢失。

2.1.4 常见误区与总结

误区 正确理解
采样率越高越好 超过48kHz对普通用户无感知差异,但会显著增加存储和CPU开销
位深越大音质越好 位深提升的是动态范围,对响度差异大的录音有帮助,但受限于麦克风硬件
声道数越多越好 多声道需要更多存储和带宽,且播放端需支持对应声道配置
忽略采样率转换 不同采样率的音频混音时需先统一采样率,否则会产生音调偏移

音频参数的选择本质是质量、存储、带宽和功耗的平衡。在Android开发中,务必通过AudioManager查询设备支持的采样率和声道配置,避免硬编码导致兼容性问题。

2.2 视频核心参数:分辨率、帧率与色彩深度

2.2.1 核心原理:视频的时空采样

视频可以理解为在时间轴上连续排列的静态图像帧。分辨率定义每帧图像的像素数量,帧率定义每秒显示的帧数,色彩深度定义每个像素用多少比特表示颜色信息。三者共同决定视频的原始数据量。

分辨率通常表示为宽×高,如1920×1080(1080p)。像素总数直接影响画面细节,但并非越高越好——在手机屏幕上,720p和1080p的视觉差异远小于在4K电视上的差异。帧率则影响运动流畅度,24fps是电影标准,30fps是电视广播标准,60fps适合体育赛事和游戏。

色彩深度(色深)常用8bit、10bit表示,对应每个颜色通道的比特数。8bit色深提供1670万色(256³),10bit提供10.7亿色。更高的色深能减少色彩渐变区域的色带现象(Banding),对HDR内容尤为重要。

2.2.2 判断方法:视频参数选择策略

在Android视频开发中,参数选择需考虑目标设备、网络条件和应用场景:

  • 短视频录制:1080p@30fps,8bit色深,H.264编码,码率8-12Mbps。
  • 直播推流:720p@30fps,8bit色深,H.264编码,码率1.5-3Mbps(根据网络自适应)。
  • 本地高清播放:4K@60fps,10bit色深,H.265/HEVC编码,码率35-50Mbps。
  • 视频通话:480p@30fps,8bit色深,VP8/VP9编码,码率500kbps-1Mbps。

原始视频数据量计算公式:原始码率 = 分辨率宽 × 分辨率高 × 帧率 × 色彩深度 × 3(RGB三通道)。以1080p@30fps@8bit为例:1920 × 1080 × 30 × 8 × 3 ≈ 1.49Gbps,这就是为什么视频必须经过压缩编码才能存储和传输。

2.2.3 案例拆解:Android视频录制参数调优

假设我们要开发一个支持慢动作录制的相机应用,需要录制120fps的720p视频。关键约束是:手机摄像头传感器支持的最大帧率、编码器的实时处理能力、存储写入速度。

// 使用Camera2 API配置高帧率录制
StreamConfigurationMap map = characteristics.get(
    CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
Range<Integer>[] fpsRanges = map.getHighSpeedVideoFpsRanges();
// 选择支持120fps的配置
for (Range<Integer> range : fpsRanges) {
    if (range.getUpper() == 120) {
        // 配置MediaRecorder使用高速录制模式
        mediaRecorder.setVideoFrameRate(120);
        mediaRecorder.setVideoSize(1280, 720);
        mediaRecorder.setVideoEncodingBitRate(20 * 1000 * 1000); // 20Mbps
        break;
    }
}

这里将码率提高到20Mbps,因为120fps的视频帧间差异更大,需要更高码率保持画质。同时要注意,高帧率录制会显著增加传感器发热和功耗,需要监控设备温度并做好降级策略。

风险提示:并非所有Android设备都支持120fps录制。在调用getHighSpeedVideoFpsRanges()前必须检查返回值是否为空,并准备30fps/60fps的降级方案。此外,高帧率视频在播放时需确认播放器支持,否则会出现慢动作效果丢失或音画不同步问题。

2.2.4 常见误区与总结

误区 正确理解
分辨率越高画质越好 画质还取决于码率、编码器效率、显示设备尺寸和观看距离
帧率越高越流畅 超过显示设备刷新率(如60Hz屏幕显示120fps)时,多余帧被丢弃,反而增加解码负担
忽略色彩空间 BT.601(标清)、BT.709(高清)、BT.2020(4K HDR)色彩空间不匹配会导致颜色失真
码率设置随意 码率过低产生块效应,过高浪费存储和带宽,应根据分辨率和帧率合理设置

视频参数的核心是理解“分辨率×帧率×色深”决定原始数据量,而编码格式和码率决定压缩后的实际数据量。在Android开发中,务必通过CamcorderProfile查询设备支持的录制配置,避免使用不支持的参数组合。

2.3 编码格式:H.264/H.265/AAC/MP3深度解析

2.3.1 核心原理:有损压缩与感知编码

音视频编码的核心思想是利用人类感知系统的局限性,去除人眼和人耳不敏感的信息。视频编码利用空间冗余(相邻像素相似)、时间冗余(相邻帧相似)和视觉冗余(人眼对高频细节不敏感);音频编码利用听觉掩蔽效应(强音掩盖弱音)和频率敏感度差异。

H.264(AVC)是目前最广泛使用的视频编码标准,采用混合编码框架:帧内预测消除空间冗余,帧间预测(运动估计与补偿)消除时间冗余,变换量化消除视觉冗余。H.264的Profile(如Baseline、Main、High)和Level(如3.1、4.0、5.1)定义了不同的工具集和性能上限。

H.265(HEVC)是H.264的继任者,在相同画质下码率可降低约50%。它引入了更灵活的编码树单元(CTU)、更多帧内预测方向(35种 vs H.264的9种)和更先进的运动矢量预测。但H.265的编码复杂度约为H.264的3-5倍,对移动设备CPU/GPU要求更高。

AAC(Advanced Audio Coding)是MP3的继任者,在相同码率下提供更好的音质。AAC支持更多采样率(8kHz-96kHz)、更多声道(最多48个)和更灵活的帧长度(1024/960/512/480样本)。LC-AAC是兼容性最好的Profile,HE-AAC(SBR技术)适合低码率流媒体。

MP3(MPEG-1 Audio Layer 3)虽然技术较老,但兼容性极广。MP3使用心理声学模型和霍夫曼编码,典型码率128kbps-320kbps。在Android开发中,MP3解码是标配,但编码通常不推荐(专利和效率问题)。

2.3.2 判断方法:编码格式选择指南

场景 推荐编码 理由
Android视频录制 H.264 High Profile 硬件编码器支持广泛,兼容性好,码率适中
4K/8K视频存储 H.265 Main 10 高压缩率,支持10bit色深,适合大分辨率
在线直播 H.264 Baseline + AAC-LC 低延迟,兼容所有播放器,AAC保证音质
音乐流媒体 AAC-LC 256kbps 接近CD音质,码率适中,支持流式播放
语音消息 AMR-NB / Opus 低码率(12.2kbps),专为语音优化

在Android中,通过MediaCodecInfo可以查询设备支持的编码器类型和Profile/Level。例如,检查是否支持H.265编码:

MediaCodecList list = new MediaCodecList(MediaCodecList.ALL_CODECS);
for (MediaCodecInfo codecInfo : list.getCodecInfos()) {
    if (codecInfo.isEncoder() && 
        codecInfo.getSupportedTypes().contains(MediaFormat.MIMETYPE_VIDEO_HEVC)) {
        // 设备支持H.265编码
        MediaCodecInfo.CodecCapabilities caps = 
            codecInfo.getCapabilitiesForType(MediaFormat.MIMETYPE_VIDEO_HEVC);
        // 检查Profile和Level支持情况
    }
}

2.3.3 案例拆解:视频转码参数优化实战

假设我们需要将一段1080p@30fps的H.264视频(码率12Mbps)转码为适合手机端播放的720p@30fps H.264视频(码率4Mbps),同时保持可接受的画质。关键步骤:

  1. 分析源视频:使用MediaExtractor获取源视频的编码格式、分辨率、帧率、码率等元数据。
  2. 配置编码器:设置输出分辨率1280×720,帧率30fps,码率4Mbps,I帧间隔2秒(60帧),Profile设为High。
  3. 处理音频:将AAC音频从256kbps降至128kbps,采样率从48kHz降至44.1kHz(如需统一)。
  4. 执行转码:使用MediaCodec进行解码-编码,注意处理色彩空间转换(BT.709保持不变)。
  5. 验证输出:检查输出文件的码率、分辨率、音画同步是否正常。

转码过程中,码率从12Mbps降至4Mbps,压缩比达到3:1。由于分辨率从1080p降至720p(像素减少55%),4Mbps码率在720p下仍能保持较好的画质。如果直接使用4Mbps编码1080p,会出现明显的块效应。

关键经验:视频转码时,码率与分辨率的关系并非线性。通常720p建议码率2-5Mbps,1080p建议5-10Mbps,4K建议20-40Mbps。码率过低会导致画面模糊和块效应,码率过高则浪费存储和带宽。Android的MediaCodec支持码率控制模式(CBR/VBR/CQ),VBR模式在相同码率下画质更好,但码率波动较大。

2.3.4 常见误区与总结

  • 误区一:H.265一定比H.264好。H.265在低码率下优势明显,但在高码率下差异缩小,且编码延迟更高,不适合实时通信。
  • 误区二:AAC一定比MP3好。在128kbps以下,HE-AAC优于MP3;但在256kbps以上,两者差异人耳难以分辨。
  • 误区三:忽略Profile/Level兼容性。H.264 High Profile编码的视频在旧设备上可能无法硬解,需降级到Main或Baseline。
  • 误区四:编码参数随意设置。GOP大小、B帧数量、参考帧数量都会影响压缩效率和延迟,需根据场景调整。

编码格式的选择是压缩效率、计算复杂度、兼容性和延迟的权衡。在Android开发中,优先使用硬件编码器(MediaCodec),并针对不同设备做兼容性测试。对于实时通信场景,建议使用VP8/VP9或H.264 Baseline Profile以减少编码延迟。

2.4 码率与画质/音质的平衡艺术

2.4.1 核心原理:码率决定信息量

码率(Bitrate)是单位时间内传输的数据量,直接决定压缩后的音视频质量。对于视频,码率越高,每帧分配的数据越多,画质越精细;对于音频,码率越高,频率细节保留越完整。但码率并非越高越好,超过一定阈值后,人眼/人耳无法感知差异,只会浪费存储和带宽。

视频码率与画质的关系遵循“收益递减”规律:从1Mbps提升到2Mbps,画质提升明显;从8Mbps提升到16Mbps,画质提升微弱。音频方面,128kbps的AAC已接近CD音质,256kbps以上人耳几乎无法区分。

2.4.2 判断方法:码率设置经验值

视频分辨率 帧率 建议码率范围 适用场景
480p (854×480) 30fps 1-2.5 Mbps 移动网络直播
720p (1280×720) 30fps 2.5-5 Mbps 高清视频通话
1080p (1920×1080) 30fps 5-10 Mbps 短视频录制
1080p (1920×1080) 60fps 10-15 Mbps 运动视频
4K (3840×2160) 30fps 20-40 Mbps 本地高清播放

音频码率参考:语音8-32kbps(AMR/Opus),音乐64-128kbps(AAC-LC),高品质音乐192-320kbps(AAC/MP3)。

2.4.3 案例拆解:自适应码率流媒体实现

在直播或点播场景中,网络带宽波动是常态。自适应码率(ABR)技术通过实时监测网络状况,动态调整视频码率,保证播放流畅性。Android的ExoPlayer支持HLS和DASH协议的自适应码率切换。

// ExoPlayer自适应码率配置示例
DefaultTrackSelector trackSelector = new DefaultTrackSelector();
DefaultTrackSelector.Parameters parameters = trackSelector.buildUponParameters()
    .setMaxVideoBitrate(4_000_000)   // 最大4Mbps
    .setMinVideoBitrate(500_000)     // 最小500kbps
    .setMaxVideoSize(1920, 1080)     // 最大1080p
    .build();
trackSelector.setParameters(parameters);

ExoPlayer player = new ExoPlayer.Builder(context)
    .setTrackSelector(trackSelector)
    .build();

实现ABR的关键是准备多档码率的视频切片(如HLS的m3u8索引文件),播放器根据当前网络带宽和缓冲区状态自动选择最合适的码率档位。码率切换时需注意:切换点应选择在关键帧(I帧)位置,避免画面花屏;切换策略应避免频繁抖动(如带宽在2Mbps和3Mbps之间波动