OpenHarmony 音频管理
前言
音频可以通过超级终端在其他外部设备上播放本地的音频流
例如使用 Openharmony 或者 HarmonyOS 设备与一台华为sound使用超级终端连接并播放一首歌曲
下面是音频管理的介绍和运行实例的代码片段
官方代码仓库 multimedia_audio_framework: Audio management implementation | 音频管理功能实现
介绍
音频组件用于实现音频相关功能,包括播放、音量管理、设备管理等
架构如下图
应用接入
音频播放
使用AudioRenderer
实现音频播放
1.使用Create
接口和所需要流的类型来获取AudioRenderer
实例
1 | AudioStreamType streamType = STREAM_MUSIC; // 流类型 |
2.[选]静态接口
GetSupportedFormats()
,GetSupportedChannels()
,GetSupportedEncodingTypes()
,GetSupportedSamplingRates()
来获取参数
3.调用实例的SetParams
1 | AudioRendererParams rendererParams; |
4.[选]使用audioRenderer->GetParams(rendererParams)
验证SetParams
5.AudioRenderer
实例调用audioRenderer->Start()
函数启动播放Task
6.使用GetBufferSize
接口获取需写入缓冲区长度
1 | audioRenderer->GetBufferSize(bufferLen); |
7.读取源需播放的音频数据并传输到流中,重复调用Write函数写入渲染数据
1 | bytesToWrite = fread(buffer, 1, bufferLen, wavFile); |
8.调用audioRenderer->Drain()
清空播放流
9.调用audioRenderer->Stop()
停止输出流
10.在播放任务完成后,调用AudioRenderer
实例的audioRenderer->Release()
释放资源
11.使用audioRenderer->SetVolume(float)
和audioRenderer->GetVolume()
设置和获取当前流音量,可选范围为[0.0,1.0]
音频录制
使用仓库内提供的接口让应用程序完成使用输入设备进行声音录制,将语音转换为音频数据,并管理录制的任务
下面的步骤将描述如何使用AudioCapturer
开发音频录制功能
使用
Create
接口和所需流类型来获取AudioCapturer
实例1
2AudioStreamType streamType = STREAM_MUSIC;
std::unique_ptr<AudioCapturer> audioCapturer = AudioCapturer::Create(streamType);[选]静态接口
GetSupportedFormats()
,GetSupportedChannels()
,GetSupportedEncodingTypes()
,GetSupportedSamplingRates()
可用于获取支持的参数准备设备,调用实例的
SetParams
1
2
3
4
5
6
7AudioCapturerParams capturerParams;
capturerParams.sampleFormat = SAMPLE_S16LE;
capturerParams.sampleRate = SAMPLE_RATE_44100;
capturerParams.channelCount = STEREO;
capturerParams.encodingType = ENCODING_PCM;
audioCapturer->SetParams(capturerParams);[选]使用
audioCapturer->GetParams(capturerParams)
验证SetParams()
AudioCapturer
实例调用AudioCapturer->Start()
启动录音任务使用
GetBufferSize
接口获取写入的缓冲区长度1
audioCapturer->GetBufferSize(bufferLen);
读取录制的音频数据并将其转换为字节流,重复调用read函数读取数据直到主动停止
1
2
3
4
5
6
7
8
9
10
11// set isBlocking = true/false for blocking/non-blocking read
bytesRead = audioCapturer->Read(*buffer, bufferLen, isBlocking);
while (numBuffersToCapture) {
bytesRead = audioCapturer->Read(*buffer, bufferLen, isBlockingRead);
if (bytesRead < 0) {
break;
} else if (bytesRead > 0) {
fwrite(buffer, size, bytesRead, recFile); // example shows writes the recorded data into a file
numBuffersToCapture--;
}
}audioCapturer->Flush()
清空录音流缓冲区AudioCapturer
实例调用audioCapturer->Stop()
停止录音在录音任务完成后,调用
AudioCapturer
实例的audioCapturer->Release()
释放资源
音频管理
可以使用audio_system_manager.h的接口来控制音量和设备
使用
GetInstance
接口获取AudioSystemManager
实例1
AudioSystemManager *audioSystemMgr = AudioSystemManager::GetInstance();
音量控制
使用
GetMaxVolume
和GetMinVolume
接口去查询音频流支持的最大和最小音量等级,在此范围内设置音量1
2
3AudioVolumeType streamType = AudioVolumeType::STREAM_MUSIC;
int32_t maxVol = audioSystemMgr->GetMaxVolume(streamType);
int32_t minVol = audioSystemMgr->GetMinVolume(streamType);使用
SetVolume
和GetVolume
接口来设置和获取指定音频流的音量等级1
2int32_t result = audioSystemMgr->SetVolume(streamType, 10);
int32_t vol = audioSystemMgr->GetVolume(streamType);使用
SetMute
和IsStreamMute
接口来设置和获取指定音频流的静音状态1
2int32_t result = audioSystemMgr->SetMute(streamType, true);
bool isMute = audioSystemMgr->IsStreamMute(streamType);使用
SetRingerMode
和GetRingerMode
接口来设置和获取铃声模式,参考在audio_info.h定义的AudioRingerMode
枚举来获取支持的铃声模式1
2int32_t result = audioSystemMgr->SetRingerMode(RINGER_MODE_SILENT);
AudioRingerMode ringMode = audioSystemMgr->GetRingerMode();使用
SetMicrophoneMute
和IsMicrophoneMute
接口来设置和获取麦克风的静音状态1
2int32_t result = audioSystemMgr->SetMicrophoneMute(true);
bool isMicMute = audioSystemMgr->IsMicrophoneMute();设备控制
使用
GetDevices
,deviceType
和deviceRole
接口来获取音频输入输出设备信息,参考audio_info.h内定义的DeviceFlag
,DeviceType
和DeviceRole
枚举1
2
3
4
5
6DeviceFlag deviceFlag = OUTPUT_DEVICES_FLAG;
vector<sptr<AudioDeviceDescriptor>> audioDeviceDescriptors
= audioSystemMgr->GetDevices(deviceFlag);
sptr<AudioDeviceDescriptor> audioDeviceDescriptor = audioDeviceDescriptors[0];
cout << audioDeviceDescriptor->deviceType_;
cout << audioDeviceDescriptor->deviceRole_;使用
SetDeviceActive
和IsDeviceActive
接口去激活/去激活音频设备和获取音频设备激活状态1
2
3ActiveDeviceType deviceType = SPEAKER;
int32_t result = audioSystemMgr->SetDeviceActive(deviceType, true);
bool isDevActive = audioSystemMgr->IsDeviceActive(deviceType);提供其他用途的接口如
IsStreamActive
,SetAudioParameter
和GetAudioParameter
,详细请参考 audio_system_manager.h应用程序可以使用
AudioManagerNapi::On
注册系统音量的更改,在此,如果应用程序监听到系统音量更改的事件,就会用以下参数通知应用程序volumeType
: 更改的系统音量的类型volume
: 当前的音量等级updateUi
: 是否需要显示变化详细信息(如果音量被增大/减小,将updateUi
标志设置为true,在其他情况下,updateUi
设置为false)1
2
3
4
5
6
7
8
9
10
11const audioManager = audio.getAudioManager();
export default {
onCreate() {
audioManager.on('volumeChange', (volumeChange) ==> {
console.info('volumeType = '+volumeChange.volumeType);
console.info('volume = '+volumeChange.volume);
console.info('updateUi = '+volumeChange.updateUi);
}
}
}
音频场景
使用
SetAudioscene
和getAudioScene
接口去更改和检查音频策略1
2int32_t result = audioSystemMgr->SetAudioScene(AUDIO_SCENE_PHONE_CALL);
AudioScene audioScene = audioSystemMgr->GetAudioScene();有关支持的音频场景,请参阅
AudioScene
中的枚举audio_info.h音频流管理
可以使用audio_stream_manager.h提供的接口用于流管理功能
使用
GetInstance
接口获得AudioSystemManager
实例1
AudioStreamManager *audioStreamMgr = AudioStreamManager::GetInstance();
使用
RegisterAudioRendererEventListener
为渲染器状态更改注册侦听器.渲染器状态更改回调,该回调将在渲染器流状态更改时调用,通过重写AudioRendererStateChangeCallback
类中的函数OnRendererStateChange
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16const int32_t clientUID;
class RendererStateChangeCallback : public AudioRendererStateChangeCallback {
public:
RendererStateChangeCallback = default;
~RendererStateChangeCallback = default;
void OnRendererStateChange(
const std::vector<std::unique_ptr<AudioRendererChangeInfo>> &audioRendererChangeInfos) override
{
cout<<"OnRendererStateChange entered"<<endl;
}
};
std::shared_ptr<AudioRendererStateChangeCallback> callback = std::make_shared<RendererStateChangeCallback>();
int32_t state = audioStreamMgr->RegisterAudioRendererEventListener(clientUID, callback);
int32_t result = audioStreamMgr->UnregisterAudioRendererEventListener(clientUID);使用
RegisterAudioCapturerEventListener
为捕获器状态更改注册侦听器,捕获器状态更改回调,该回调将在捕获器流状态更改时调用,通过重写AudioCapturerStateChangeCallback
类中的函数OnCapturerStateChange
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16const int32_t clientUID;
class CapturerStateChangeCallback : public AudioCapturerStateChangeCallback {
public:
CapturerStateChangeCallback = default;
~CapturerStateChangeCallback = default;
void OnCapturerStateChange(
const std::vector<std::unique_ptr<AudioCapturerChangeInfo>> &audioCapturerChangeInfos) override
{
cout<<"OnCapturerStateChange entered"<<endl;
}
};
std::shared_ptr<AudioCapturerStateChangeCallback> callback = std::make_shared<CapturerStateChangeCallback>();
int32_t state = audioStreamMgr->RegisterAudioCapturerEventListener(clientUID, callback);
int32_t result = audioStreamMgr->UnregisterAudioCapturerEventListener(clientUID);使用
GetCurrentRendererChangeInfos
获取所有当前正在运行的流渲染器信息包括clientuid
、sessionid
、renderinfo
、renderstate
和输出设备详细信息1
2std::vector<std::unique_ptr<AudioRendererChangeInfo>> audioRendererChangeInfos;
int32_t currentRendererChangeInfo = audioStreamMgr->GetCurrentRendererChangeInfos(audioRendererChangeInfos);使用
GetCurrentCapturerChangeInfos
获取所有当前正在运行的流捕获器信息,包括clientuid
、sessionid
、capturerInfo
、capturerState
和输入设备详细信息1
2std::vector<std::unique_ptr<AudioCapturerChangeInfo>> audioCapturerChangeInfos;
int32_t currentCapturerChangeInfo = audioStreamMgr->GetCurrentCapturerChangeInfos(audioCapturerChangeInfos);有关结构,请参阅audio_info.h
audioRendererChangeInfos
和audioCapturerChangeInfos
使用
IsAudioRendererLowLatencySupported
检查低延迟功能是否支持1
2const AudioStreamInfo &audioStreamInfo;
bool isLatencySupport = audioStreamMgr->IsAudioRendererLowLatencySupported(audioStreamInfo);JavaScript用法
JavaScript应用可以使用系统提供的音频管理接口,来控制音量和设备
请参考js-apis-audio.md来获取音量和设备管理相关JavaScript接口的用法
铃声管理
可以使用提供的接口iringtone_sound_manager.h和iringtone_player.h实现铃声播放功能
使用
CreateRingtoneManager
接口创建IRingtoneSoundManager
实例1
std::shared_ptr<IRingtoneSoundManager> ringtoneManagerClient = RingtoneFactory::CreateRingtoneManager();
使用
SetSystemRingtoneUri
接口设置系统铃声Uri1
2
3std::string uri = "/data/media/test.wav";
RingtoneType ringtoneType = RINGTONE_TYPE_DEFAULT;
ringtoneManagerClient->SetSystemRingtoneUri(context, uri, ringtoneType);使用
GetRingtonePlayer
接口获取IRingtonePlayer
实例1
std::unique_ptr<IRingtonePlayer> ringtonePlayer = ringtoneManagerClient->GetRingtonePlayer(context, ringtoneType);
使用
Configure
接口配置铃声播放器1
2
3float volume = 1;
bool loop = true;
ringtonePlayer.Configure(volume, loop);使用
Start
,Stop
和Release
接口在铃声播放器实例上控制播放状态1
2
3ringtonePlayer.Start();
ringtonePlayer.Stop();
ringtonePlayer.Release();使用
GetTitle
接口获取当前系统铃声的标题使用
GetRingtoneState
接口获取铃声播放状态RingtoneState
使用
GetAudioRendererInfo
获取AudioRendererInfo
检查内容类型和流使用情况蓝牙SCO呼叫
可以使用提供的接口audio_bluetooth_manager.h实现同步连接导向链路(SCO)的蓝牙呼叫
为监听SCO状态更改,您可以使用
OnScoStateChanged
1
2
3const BluetoothRemoteDevice &device;
int state;
void OnScoStateChanged(const BluetoothRemoteDevice &device, int state);[选]静态接口
RegisterBluetoothScoAgListener()
,UnregisterBluetoothScoAgListener()
,可用于注册蓝牙SCO的侦听器