音频采集的主要工作是通过输入设备将声音采集并转码为音频数据,同时对采集任务进行管理。
接口名 |
描述 |
---|---|
AudioCapturer(AudioCapturerInfo audioCapturerInfo) throws IllegalArgumentException |
构造函数,设置录音相关音频参数,使用默认录音设备。 |
AudioCapturer(AudioCapturerInfo audioCapturerInfo, AudioDeviceDescriptor devInfo) throws IllegalArgumentException |
构造函数,设置录音相关音频参数并指定录音设备。 |
getMinBufferSize(int sampleRate, int channelCount, int audioFormat) |
获取指定参数条件下所需的最小缓冲区大小。 |
addSoundEffect(UUID type, String packageName) |
增加录音的音频音效。 |
start() |
开始录音。 |
read(byte[] data, int offset, int size) |
读取音频数据。 |
read(byte[] data, int offset, int size, boolean isBlocking) |
读取音频数据并写入传入的byte数组中。 |
read(float[] data, int offsetInFloats, int sizeInFloats) |
阻塞式读取音频数据并写入传入的float数组中。 |
read(float[] data, int offsetInFloats, int sizeInFloats, boolean isBlocking) |
读取音频数据并写入传入的float数组中。 |
read(short[] data, int offsetInShorts, int sizeInShorts) |
阻塞式读取音频数据并写入传入的short数组中。 |
read(short[] data, int offsetInShorts, int sizeInShorts, boolean isBlocking) |
读取音频数据并写入传入的short数组中。 |
read(java.nio.ByteBuffer buffer, int sizeInBytes) |
阻塞式读取音频数据并写入传入的ByteBuffer对象中。 |
read(java.nio.ByteBuffer buffer, int sizeInBytes, boolean isBlocking) |
读取音频数据并写入传入的ByteBuffer对象中。 |
stop() |
停止录音。 |
release() |
释放录音资源。 |
getSelectedDevice() |
获取输入设备信息。 |
getCurrentDevice() |
获取当前正在录制音频的设备信息。 |
getCapturerSessionId() |
获取录音的session ID。 |
getSoundEffects() |
获取已经激活的音频音效列表。 |
getState() |
获取音频采集状态。 |
getSampleRate() |
获取采样率。 |
getAudioInputSource() |
获取录音的输入设备信息。 |
getBufferFrameCount() |
获取以帧为单位的缓冲区大小。 |
getChannelCount() |
获取音频采集通道数。 |
getEncodingFormat() |
获取音频采集的音频编码格式。 |
getAudioTime(Timestamp timestamp, Timestamp.Timebase timebase) |
获取一个即时的捕获时间戳。 |
1. 构造音频流参数的数据结构AudioStreamInfo,推荐使用AudioStreamInfo.Builder类来构造,模板如下,模板中设置的均为AudioStreamInfo.Builder类的默认值,根据音频流的具体规格来设置具体参数。
AudioStreamInfo audioStreamInfo = new AudioStreamInfo.Builder()
.sampleRate(AudioStreamInfo.SAMPLE_RATE_UNSPECIFIED)
.audioStreamFlag(AudioStreamInfo.AudioStreamFlag.AUDIO_STREAM_FLAG_NONE)
.encodingFormat(AudioStreamInfo.EncodingFormat.ENCODING_INVALID)
.channelMask(AudioStreamInfo.ChannelMask.CHANNEL_INVALID)
.streamUsage(AudioStreamInfo.StreamUsage.STREAM_USAGE_UNKNOWN)
.build();
2. (可选)通过采集的采样率、声道数和数据格式,调用getMinBufferSize方法获取采集任务所需的最小buffer,参照该buffer值设置步骤3中AudioCapturerInfo的bufferSizeInBytes。
3. 使用步骤1创建的音频流构建音频采集的参数结构AudioCapturerInfo,推荐使用AudioCapturerInfo.Builder类来构造,根据音频采集的具体规格来设置具体参数。以真实的录制pcm流为例:
AudioStreamInfo audioStreamInfo = new AudioStreamInfo.Builder()
.encodingFormat(AudioStreamInfo.EncodingFormat.ENCODING_PCM_16BIT) // 16-bit PCM
.channelMask(AudioStreamInfo.ChannelMask.CHANNEL_IN_STEREO) // 双声道输入
.sampleRate(44100) // 44.1kHz
.build();
AudioCapturerInfo audioCapturerInfo = new AudioCapturerInfo.Builder().audioStreamInfo(audioStreamInfo)
.build();
4. (可选)设置采集设备,如麦克风、耳机等。通过AudioManager.getDevices(AudioDeviceDescriptor.DeviceFlag.INPUT_DEVICES_FLAG)获取到设备支持的输入设备,然后依照AudioDeviceDescriptor.DeviceType选择要选用的输入设备类型。
5. 通过构造方法获取AudioCapturer类的实例化对象(构造AudioCapturer类的实例化对象前需先去配置录音权限--ohos.permission.MICROPHONE),其中步骤3的参数为必选参数,通过步骤4获取的指定录音设备为可选参数。
录音权限的申请,需要开发者在config.json文件中的“reqPermissions”字段中声明所需要的权限。
"module": {
"reqPermissions": [
{
"name": "ohos.permission.MICROPHONE"
},
{
...
}
]
}
增加Ability接口的访问权限控制:
public class MainAbility extends Ability {
@Override
public void onStart(Intent intent) {
...
requestPermissions(); //在onStart方法中调用申请的权限
}
private void requestPermissions() {
String[] permissions = {
SystemPermission.ohos.permission.MICROPHONE, ...,...
};
requestPermissionsFromUser(Arrays.stream(permissions)
.filter(permission -> verifySelfPermission(permission) != IBundleManager.PERMISSION_GRANTED).toArray(String[]::new), 0);
}
}
实例化AudioCapturer对象:
AudioCapturer audioCapturer = new AudioCapturer(audioCapturerInfo);
6. (可选)设置采集音效,如降噪、回声消除等。使用addSoundEffect(UUID type, String packageName)进行音效设置,其中UUID参考类SoundEffect中提供的静态变量。
7. (可选)构造音频采集回调,首先继承抽象类AudioCapturerCallback,并实现抽象方法onCapturerConfigChanged(List
private AudioManager audioManager = new AudioManager();
public void main() {
AudioCapturerCallback cb = new AudioCapturerCallback() {
@Override
public void onCapturerConfigChanged(List configs) {
configs.forEach(config -> doSomething(config));
}
};
audioManager.registerAudioCapturerCallback(cb);
}
private void doSomething(AudioCapturerConfig config) {
...
}
8. 调用 AudioCapturer实例化对象的start()方法启动采集任务。
9. 采集的音频数据读取为byte流,循环调用AudioCapturer的read方法进行数据读取。
10. 调用AudioCapturer实例化对象的stop()方法停止采集。
11. 采集任务结束后,调用AudioCapturer实例化对象的release()释放资源。
音量管理的主要工作是音量调节,输入/输出设备管理,注册音频中断、音频采集中断的回调等。
当前仅系统应用支持设置静音或响铃等模式。
接口名 |
描述 |
---|---|
AudioManager() |
构造函数。 |
AudioManager(Context context) |
构造函数,由使用者指定应用上下文Context。 |
AudioManager(String packageName) |
构造函数,由使用者指定包信息。 |
activateAudioInterrupt(AudioInterrupt interrupt) |
激活音频中断状态检测。 |
deactivateAudioInterrupt(AudioInterrupt interrupt) |
去激活音频中断状态检测。 |
getAudioParameter(String key) |
获取音频硬件中指定参数keys所对应的参数值。 |
getDevices(DeviceFlag flag) |
获取设备信息。 |
getMaxVolume(AudioVolumeType volumeType) |
获取指定音频流音量最大档位。 |
getMinVolume(AudioVolumeType volumeType) |
获取指定音频流音量最小档位。 |
getRingerMode() |
获取铃声模式。 |
getVersion() |
获取音频套件版本。 |
getVolume(AudioVolumeType volumeType) |
获取指定音频流的音量档位。 |
isDeviceActive(int deviceType) |
判断设备的开关状态。 |
isMute(AudioVolumeType volumeType) |
特定的流是否处于静音状态。 |
mute(AudioVolumeType volumeType) |
将特定流设置为静音状态。 |
setAudioParameter(String key, String value) |
为音频硬件设置可变数量的参数值。 |
setDeviceActive(int deviceType, boolean state) |
设置设备的开关状态。 |
setRingerMode(AudioRingMode mode) |
设置铃声模式。 |
setVolume(AudioVolumeType volumeType, int volume) |
设置特定流的音量档位。 |
unmute(AudioVolumeType volumeType) |
将特定流设置为非静音状态。 |
setMasterMute(boolean isMute) |
将主音频输出设备设置为静音或取消静音状态。 |
setMicrophoneMute(boolean isMute) |
将麦克风设置为静音或取消静音状态。 |
isMicrophoneMute() |
判断麦克风是否处于静音状态。 |
getActiveCapturerConfigs() |
获取设备当前激活的音频采集任务的配置信息。 |
registerAudioCapturerCallback(AudioCapturerCallback cb) |
注册音频采集参数变更回调。 |
unregisterAudioCapturerCallback(AudioCapturerCallback cb) |
去注册音频采集参数变更回调。 |
getRingerUri(Context context, RingToneType type) |
获取指定铃声类型的Uri。 |
setRingerUri(Context context, RingToneType type, Uri uri) |
设置指定铃声类型的Uri。 |
changeVolumeBy(AudioVolumeType volumeType, int index) |
将当前音量增加或减少一定量。 |
connectBluetoothSco() |
连接到蓝牙SCO通道。 |
disconnectBluetoothSco() |
断开与蓝牙SCO通道的连接。 |
getActiveRendererConfigs() |
获取有关活动音频流信息,包括使用类型、内容类型和标志。 |
getMasterOutputFrameCount() |
获取主输出设备缓冲区中的帧数。 |
getMasterOutputSampleRate() |
获取主输出设备的采样率。 |
isMasterMute() |
检查音频流是否全局静音。 |
isStreamActive(AudioVolumeType volumeType) |
检查指定类型的音频流是否处于活动状态。 |
makeSessionId() |
创建一个会话ID,AudioRendererInfo.Builder.sessionID(int)将使用该会话ID来设置音频播放参数,而AudioCapturerInfo.Builder.sessionID(int)将使用该会话ID来设置记录参数。 |
registerAudioRendererCallback(AudioRendererCallback cb) |
注册音频播放参数变更回调。 |
unregisterAudioRendererCallback(AudioRendererCallback cb) |
去注册音频播放参数变更回调。 |
音量管理提供的都是独立的功能,一般作为音频播放和音频采集的功能补充来使用。开发者根据具体使用场景选择方法即可。
音频中断状态检测和音频采集中断状态检测的使用样例,请参考音频播放和音频采集的开发步骤。
短音播放主要负责管理音频资源的加载与播放、tone音的生成与播放以及系统音播放。
短音播放开放能力分为音频资源、tone音和系统音三部分,均定义在SoundPlayer类
接口名 |
描述 |
---|---|
SoundPlayer(int taskType) |
构造函数,仅用于音频资源。 |
createSound(String path) |
从指定的路径加载音频数据生成短音资源。 |
createSound(Context context, int resourceId) |
根据应用程序上下文合音频资源ID加载音频数据生成短音资源。 |
createSound(AssetFD assetFD) |
从指定的AssetFD实例加载音频数据生成短音资源。 |
createSound(java.io.FileDescriptor fd, long offset, long length) |
根据文件描述符从文件加载音频数据生成音频资源。 |
createSound(java.lang.String path, AudioRendererInfo rendererInfo) |
根据从指定路径和播放信息加载音频数据生成短音资源。 |
setOnCreateCompleteListener(SoundPlayer.OnCreateCompleteListener listener) |
设置声音创建完成的回调。 |
setOnCreateCompleteListener(SoundPlayer.OnCreateCompleteListener listener, boolean isDiscarded) |
设置用于声音创建完成的回调,并根据指定的isDiscarded标志位确定是否丢弃队列中的原始回调通知消息。 |
deleteSound(int soundID) |
删除短音同时释放短音所占资源。 |
pause(int taskID) |
根据播放任务ID暂停对应的短音播放。 |
play(int soundID) |
使用默认参数播放短音。 |
play(int soundID, SoundPlayerParameters parameters) |
使用指定参数播放短音。 |
resume(int taskID) |
恢复短音播放任务。 |
setLoop(int taskID, int loopNum) |
设置短音播放任务的循环次数。 |
setPlaySpeedRate(int taskID, float speedRate) |
设置短音播放任务的播放速度。 |
setPriority(int taskID, int priority) |
设置短音播放任务的优先级。 |
setVolume(int taskID, AudioVolumes audioVolumes) |
设置短音播放任务的播放音量。 |
setVolume(int taskID, float volume) |
设置短音播放任务的所有音频声道的播放音量。 |
stop(int taskID) |
停止短音播放任务。 |
pauseAll() |
暂停所有正在播放的任务。 |
resumeAll() |
恢复虽有已暂停的播放任务。 |
tone音的生成与播放API接口功能介绍
接口名 |
描述 |
---|---|
SoundPlayer() |
构造函数,仅用于tone音。 |
createSound(ToneDescriptor.ToneType type, int durationMs) |
创建具有音调频率描述和持续时间(毫秒)的tone音。 |
createSound(AudioStreamInfo.StreamType streamType, float volume) |
根据音量和音频流类型创建tone音。 |
play(ToneDescriptor.ToneType toneType, int durationMs) |
播放指定时长和tone音类型的tone音。 |
pause() |
暂停tone音播放。 |
play() |
播放创建好的tone音。 |
release() |
释放tone音资源。 |
系统音的播放API接口功能介绍
接口名 |
描述 |
---|---|
SoundPlayer(String packageName) |
构造函数,仅用于系统音。 |
playSound(SoundType type) |
播放系统音。 |
playSound(SoundType type, float volume) |
指定音量播放系统音。 |
public SoundPlayer soundPlayer;
public Map soundMap = new HashMap<>();
public int taskId;
public static final int ERRORID = -1;
public void initSoundPlayer() {
// 步骤1:实例化对象
SoundPlayer soundPlayer = new SoundPlayer(AudioManager.AudioVolumeType.STREAM_MUSIC.getValue());
// 步骤2:加载指定音频资源并创建短音
int soundId1 = soundPlayer.createSound("/xxx/sound1_file_path");
soundMap.put(soundId1, false);
int soundId2 = soundPlayer.createSound("/xxx/sound2_file_path");
soundMap.put(soundId2, false);
int soundId3 = soundPlayer.createSound("/xxx/sound3_file_path");
soundMap.put(soundId3, false);
soundPlayer.setOnCreateCompleteListener((soundPlayer1, cacheId, status) -> {
// 对应的短音创建成功
if (status == 0 && soundMap.containsKey(cacheId)) {
soundMap.put(cacheId, true);
}
});
}
public int PlaySound(int soundId) {
// 步骤3:播放指定的短音
if (soundMap.containsKey(cacheId) && soundMap.get(cacheId)) {
taskId = soundPlayer.play(soundId);
} else {
taskId = ERRORID;
HiLog.warn(TAG, "sound id is not ready.");
}
return taskId;
}
public void stopSoundPlayer(int taskId) {
// 步骤4:停止短音资源
if (taskId > 0){
soundPlayer.stop(taskId);
}
}
public void releaseSoundPlayer() {
// 步骤5:释放短音资源
Iterator> iterator = soundMap.entrySet().iterator();
while (iterator.hasNext()){
Map.Entry entry = iterator.next();
int soundId = entry.getKey().intValue();
soundPlayer.deleteSound(soundId);
iterator.remove();
}
soundPlayer.release();
}
下面的样例展示tone音的生成与播放:
public void demo() {
// 步骤1:实例化对象
SoundPlayer soundPlayer = new SoundPlayer();
// 步骤2:创建DTMF_0(高频1336Hz,低频941Hz)持续时间1000ms的tone音
soundPlayer.createSound(ToneDescriptor.ToneType.DTMF_0, 1000);
// 步骤3:tone音播放、暂停和资源释放
soundPlayer.play();
soundPlayer.pause();
soundPlayer.release();
}
下面的样例展示系统音的播放:
public void demo() {
// 步骤1:实例化对象
SoundPlayer soundPlayer = new SoundPlayer("packageName");
// 步骤2:播放键盘敲击音,音量为1.0
soundPlayer.playSound(SoundPlayer.SoundType.KEY_CLICK, 1.0f);
}