openHarmony如何使用开发音频功能(铃声和媒体)
目录
1.配置音频渲染参数AudioRendererOption并创建AudioRenderer实例:
前置
API版本:OpenHarmony SDK 11(full sdk)
IDE版本:DevEco Studio 4.1 Release
参考文档:
openHarmony AudioRenderer开发音频播放功能
https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/media/audio/using-audiorenderer-for-playback.md
@ohos.multimedia.audio (音频管理)
https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/reference/apis-audio-kit/js-apis-audio.md
开发步骤:
1.配置音频渲染参数AudioRendererOption并创建AudioRenderer实例:
const TAG = "Audio: "
private readonly audioRendererOptions: audio.AudioRendererOptions[] = [
{
streamInfo: {
samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_44100, // 采样率
channels: audio.AudioChannel.CHANNEL_2, // 通道
sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE, // 采样格式
encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW // 编码格式
},
rendererInfo: {
usage: audio.StreamUsage.STREAM_USAGE_MUSIC, // 音频流使用类型
rendererFlags: 0 // 音频渲染器标志
}
},
{
streamInfo: {
samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_44100,
channels: audio.AudioChannel.CHANNEL_2,
sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE,
encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW
},
rendererInfo: {
usage: audio.StreamUsage.STREAM_USAGE_RINGTONE,
rendererFlags: 0
}
}
];
private readonly audioSources = ['ring.wav', 'ring.wav'];
// 音频管理属性
audioRenderers: audio.AudioRenderer[] = [];
private fileDescriptors: resourceManager.RawFileDescriptor[] = [];//音频资源数组
设置好渲染参数之后这里我们定义一个初始化铃声ringInit()方法:
async ringInit(): Promise<void> {
//设置铃声
await this.getStageFileDescriptor(this.audioSources[0]);
await this.getStageFileDescriptor(this.audioSources[1]);
try {
this.audioRenderers[1] = await audio.createAudioRenderer(this.audioRendererOptions[1]);
await this.audioRenderers[1].setInterruptMode(audio.InterruptMode.INDEPENDENT_MODE);
this.listenState(1);
} catch (err) {
let error = err as BusinessError;
Logger.error(TAG, `audioRenderer create ,Error: ${JSON.stringify(error)}`);
return;
}
}
其中getStageFileDescriptor方法是为了从rawfile目录获取资源文件:
async getStageFileDescriptor(fileName: string): Promise<void> {
this.appContext = getContext(this)
if (this.appContext) {
Logger.error(TAG + "appContext successful")
let mgr = this.appContext.resourceManager;
await mgr.getRawFd(fileName).then(value => {
this.fileDescriptors.push(value) //成功后push到数组中
Logger.info(TAG, 'case getRawFileDescriptor success fileName: ' + fileName)
}).catch((error: BusinessError) => {
Logger.info(TAG, 'case getRawFileDescriptor err: ' + error)
});
} else {
Logger.error(TAG + "appContext undefined")
}
}
而listenState方法是设置监听事件:
private listenState(index: number): void {
this.audioRenderers[index].on('stateChange', (state) => {
Logger.info(TAG, `Player ${index} state changed to: ${state}`);
});
}
一切准备就绪之后就可以开启渲染功能的开发了。
2.音频渲染开发
async ringPlay(): Promise<void> {
if (this.audioRenderers[1] === null) {
Logger.error(TAG, "audioRenderers null")
return
}
let bufferSize: number = 0;
try {
bufferSize = await this.audioRenderers[1].getBufferSize();
await this.audioRenderers[1].start();
Logger.info(TAG, "audioRenderers successful")
}
catch (err) {
let error = err as BusinessError;
Logger.error(TAG + `audioRenderer start : Error: ${JSON.stringify(error)}`);
return;
}
try {
let buf = new ArrayBuffer(bufferSize);
let start = this.fileDescriptors[1].offset;
let cur = start;
// 添加数据循环写入
while (cur < start + this.fileDescriptors[1].length) {
let options: Options = { offset: cur, length: bufferSize };
await fs.read(this.fileDescriptors[1].fd, buf, options);
await this.audioRenderers[1].write(buf);
cur += bufferSize;
}
Logger.error(TAG + AudioManager.Audio.audioRenderers[1].state)
} catch (err) {
Logger.error(TAG, `Write data failed: ${err}`);
}
}
代码分析:其中的输出日志封装Logger可参考GitCode - 全球开发者的开源社区,开源代码托管平台GitCode是面向全球开发者的开源社区,包括原创博客,开源代码托管,代码协作,项目管理等。与开发者社区互动,提升您的研发效率和质量。
https://gitcode.com/openharmony-sig/ohos_axios/blob/master/library/src/main/ets/components/lib/LogUtil.js
下面为暂停代码:
async ringStop(): Promise<void> {
try {
await this.audioRenderers[1].stop();
Logger.info(TAG, 'stop successful')
}
catch (err) {
let error = err as BusinessError;
Logger.error(TAG, `render stop err:${JSON.stringify(error)}`);
}
}
需要注意的是音频管理的状态应遵循AudioRenderer状态变化示意图:

3.总结
后续会继续分享音频音量管理的功能。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)