第16章_HarmonyOs开发图解之 音频

第16章 HarmonyOs开发图解之 音频

HarmonyOS 学习系统 | 阶段三:高级深耕期


学习目标

序号 能力
1 理解音频采样的基本原理(采样率、位深度、声道)
2 掌握 AudioRenderer(音频播放)和 AudioCapturer(音频采集)的使用
3 能够使用 SoundPlayer 播放短音效

核心图解

内容讲解

16.1 音频基础概念

生活化类比:音频采样就像电影胶片的帧

声音是连续的声波,就像连续的河流。我们无法记录整条河流,所以每隔一小段距离取一个水样------这就是"采样"。采样率(如 44100Hz)就像每秒拍 44100 张照片的帧率,帧率越高,还原越精确。44100Hz 意味着每秒从声波中取 44100 个"快照"。人耳能听到 20Hz~20kHz 的声音,根据奈奎斯特定理,采样率至少要是最高频率的 2 倍,所以 44100Hz 能完美还原 22.05kHz 以下的声音。PCM(脉冲编码调制)就是把这些"快照"转换成数字的过程。

16.2 音频播放 AudioRenderer

AudioRenderer 是 HarmonyOS 音频播放的核心类,支持流式播放模式(边读边播)和静态播放模式(一次加载完整播放)。

java 复制代码
// 初始化 AudioRenderer
AudioRendererInfo audioRendererInfo = new AudioRendererInfo.Builder()
    .contentType(AudioRendererInfo.ContentType.CONTENT_TYPE_MUSIC)
    .usage(AudioRendererInfo.StreamUsage.STREAM_USAGE_MUSIC)
    .build();
AudioRenderer audioRenderer = new AudioRenderer(audioRendererInfo, PlayMode.MODE_STREAM);

// 读取音频文件并播放(在后台线程中执行)
getGlobalTaskDispatcher(TaskPriority.DEFAULT).asyncDispatch(() -> {
    InputStream is = getResourceManager().getResource(MediaTable.INPUT);
    byte[] data = new byte[4096];
    while (is.available() > 0) {
        int readLen = is.read(data);
        audioRenderer.write(data, 0, readLen);
    }
    audioRenderer.release();
});

// 控制播放
audioRenderer.start();
audioRenderer.pause();
audioRenderer.stop();

16.3 音频采集 AudioCapturer

AudioCapturer 用于从麦克风采集音频数据,适合录音、语音识别等场景。

java 复制代码
// 初始化 AudioCapturer
AudioCapturerInfo capturerInfo = new AudioCapturerInfo.Builder()
    .contentType(AudioCapturerInfo.ContentType.CONTENT_TYPE_SPEECH)
    .usage(AudioCapturerInfo.StreamUsage.STREAM_USAGE_VOICE_COMMUNICATION)
    .build();
AudioCapturer audioCapturer = new AudioCapturer(capturerInfo);

// 读取音频数据
audioCapturer.start();
byte[] buffer = new byte[4096];
while (isRecording) {
    int readLen = audioCapturer.read(buffer, 0, buffer.length);
    // 处理采集到的音频数据...
}
audioCapturer.release();

16.4 短音效播放 SoundPlayer

SoundPlayer 适合播放简短的音效(如按钮点击声、通知声),资源占用更少。

java 复制代码
// 加载短音资源
SoundPlayer soundPlayer = new SoundPlayer(context);
int soundId = soundPlayer.createSound(ResourceTable.Media_button_click);

// 播放
soundPlayer.play(soundId);

// 释放
soundPlayer.release();

代码速查卡

API 功能 示例
new AudioRenderer(info, mode) 创建音频播放器 new AudioRenderer(info, MODE_STREAM)
write(byte[], offset, size) 写入音频数据 renderer.write(data, 0, len)
start() / pause() / stop() 控制播放状态 renderer.start()
new AudioCapturer(info) 创建音频采集器 new AudioCapturer(info)
read(byte[], offset, size) 读取音频数据 capturer.read(buf, 0, buf.length)
SoundPlayer.createSound(id) 加载短音资源 player.createSound(soundId)
soundPlayer.play(soundId) 播放短音 player.play(soundId)
getMinBufferSize(rate, fmt, mask) 获取最小缓冲区大小 AudioRenderer.getMinBufferSize(44100, ...)

与 Android/iOS 对比

特性 HarmonyOS Android iOS
音频播放 AudioRenderer AudioTrack / MediaPlayer AVAudioPlayer
音频采集 AudioCapturer AudioRecord AVAudioEngine
短音效 SoundPlayer SoundPool AudioServicesPlaySystemSound
音频焦点 AudioManager AudioManager AVAudioSession
采样率配置 AudioRendererInfo 中设置 AudioFormat.Builder AVAudioFormat

⚠️ 踩坑回忆录

为什么播放出来的声音像"滋滋"电流声?

因为采样率不匹配!我设置了 48000Hz 的 AudioRenderer,但音频文件本身是 44100Hz 的,结果播放出来就像快进的磁带------声音又快又尖。解决方案:播放前先查询音频文件的实际采样率,然后让 AudioRenderer 的采样率与之匹配。可以用 AudioManager.getDevices() 查询设备支持的格式和采样率。

另外,AudioRenderer 用完必须 release(),否则音频焦点会被一直占用,其他 App 就播放不了声音了。我曾在调试时忘记 release,结果整个手机的音效系统都"哑"了,重启才恢复。


必做实操任务

序号 任务 难度
1 实现一个简单的音频播放器,支持播放/暂停/停止
2 使用 AudioCapturer 录制音频并保存为 PCM 文件
3 使用 SoundPlayer 为按钮添加点击音效
4 查询设备支持的音频采样率和格式
5 实现一个录音 + 回放的 Demo

学习检查清单

  • 能解释采样率、位深度、声道数的基本概念
  • 能使用 AudioRenderer 播放音频文件
  • 能使用 AudioCapturer 录制音频
  • 知道为什么 AudioRenderer 采样率必须与音频文件匹配
  • 能使用 SoundPlayer 播放短音效
  • 能在后台线程中执行音频读写操作
  • 知道为什么必须手动 release 音频资源
  • 理解 MODE_STREAM 和 MODE_STATIC 的区别

进阶方向

  • 结合第 17 章媒体会话,实现后台音乐播放并显示系统通知栏控制
  • 学习音频编解码(AAC、MP3),实现格式转换
  • 探索音频可视化(将音频数据转换为频谱图)
    必须手动 release 音频资源
  • 理解 MODE_STREAM 和 MODE_STATIC 的区别

进阶方向

  • 结合第 17 章媒体会话,实现后台音乐播放并显示系统通知栏控制
  • 学习音频编解码(AAC、MP3),实现格式转换
  • 探索音频可视化(将音频数据转换为频谱图)
相关推荐
lqj_本人30 分钟前
Flutter 三方库「drag_and_drop_flutter」的鸿蒙化适配指南
flutter·华为·harmonyos
JoyCong19981 小时前
知识科普:ToDesk鸿蒙版高级功能免费开放使用了!
运维·服务器·华为·智能手机·harmonyos·远程工作
可乐鸡翅yeah_1 小时前
HLS CORS 跨域问题完整排查实战,解决 M3U8 与 TS 分片跨域报错
android·ios·音视频·m3u8·音视频在线播放
美狐美颜SDK开放平台2 小时前
从视频处理到实时渲染:直播APP中视频美颜SDK的关键技术解析
前端·人工智能·架构·实时互动·音视频·视频美颜sdk
小唔w2 小时前
文字一键生成播客音频,2026年几款AI工具功能梳理
人工智能·音视频
HwJack202 小时前
HarmonyOS单版本表模式与 schema 实战:多端共编文档的冲突解决
华为·harmonyos
可乐鸡翅yeah_3 小时前
多浏览器 HLS 兼容性差异排查,Chrome、Firefox、Safari 表现不一致定位
chrome·ffmpeg·音视频·firefox·safari·m3u8
烟雨江南7853 小时前
呼叫中心如何用语音识别做客服质检?从人工抽检到全量通话分析的落地方案
人工智能·websocket·音视频·语音识别·ai客服
小柯南敲键盘3 小时前
跨马翻译:跨境电商图片翻译工具,批量处理视频字幕与抠图
python·音视频
ygwelcome4 小时前
视频收割机-VideoHarvester架构功能介绍
pdf·音视频