From 1b39b9a74bc8f1edebf9116589d0294f55dd23ae Mon Sep 17 00:00:00 2001 From: zengyawen Date: Mon, 17 Oct 2022 09:50:56 +0800 Subject: [PATCH] update docs Signed-off-by: zengyawen --- zh-cn/application-dev/media/audio-capturer.md | 125 +++--- .../media/audio-interruptmode.md | 47 ++- zh-cn/application-dev/media/audio-renderer.md | 365 +++++++++--------- .../media/audio-stream-manager.md | 19 +- .../application-dev/media/opensles-capture.md | 6 +- .../media/opensles-playback.md | 8 +- 6 files changed, 291 insertions(+), 279 deletions(-) diff --git a/zh-cn/application-dev/media/audio-capturer.md b/zh-cn/application-dev/media/audio-capturer.md index 3e91bd1d88..6d37e14b6d 100644 --- a/zh-cn/application-dev/media/audio-capturer.md +++ b/zh-cn/application-dev/media/audio-capturer.md @@ -1,77 +1,88 @@ # 音频采集开发指导 -## 场景介绍 +## 简介 -AudioCapturer提供了用于获取原始音频文件的方法。开发者可以通过本指导了解应用如何通过AudioCapturer采集音频。 +AudioCapturer提供了用于获取原始音频文件的方法。开发者可以通过本指导了解应用如何通过AudioCapturer接口的调用实现音频数据的采集。 -### 状态检查 +- **状态检查**:在进行应用开发的过程中,建议开发者通过on('stateChange')方法订阅AudioCapturer的状态变更。因为针对AudioCapturer的某些操作,仅在音频采集器在固定状态时才能执行。如果应用在音频采集器处于错误状态时执行操作,系统可能会抛出异常或生成其他未定义的行为。 -在进行应用开发的过程中,建议开发者通过on('stateChange')方法订阅AudioCapturer的状态变更。因为针对AudioCapturer的某些操作,仅在音频采集器在固定状态时才能执行。如果应用在音频采集器处于错误状态时执行操作,系统可能会抛出异常或生成其他未定义的行为。 +## 运作机制 -详细API含义可参考:[音频管理API文档AudioCapturer](../reference/apis/js-apis-audio.md#audiocapturer8) +该模块提供了音频采集模块的状态变化示意图 + +**图1** 音频采集状态变化示意图 + +![audio-capturer-state](figures/audio-capturer-state.png) + +**PREPARED状态:** 通过调用create()方法进入到该状态。
+**RUNNING状态:** 正在进行音频数据播放,可以在prepared状态通过调用start()方法进入此状态,也可以在stopped状态通过调用start()方法进入此状态。
+**STOPPED状态:** 在running状态可以通过stop()方法停止音频数据的播放。
+**RELEASED状态:** 在prepared和stop状态,用户均可通过release()方法释放掉所有占用的硬件和软件资源,并且不会再进入到其他的任何一种状态了。
+ +## 约束与限制 -**图1** 音频采集状态机 +开发者在进行音频数据采集功能开发前,需要先对所开发的应用配置麦克风权限(ohos.permission.MICROPHONE),权限配置相关内容可参考:[访问控制授权申请指导](../security/accesstoken-guidelines.md) -![](figures/audio-capturer-state.png) +## 开发指导 -## 开发步骤 +详细API含义可参考:[音频管理API文档AudioCapturer](../reference/apis/js-apis-audio.md#audiocapturer8) 1. 使用createAudioCapturer()创建一个AudioCapturer实例。 在audioCapturerOptions中设置音频采集器的相关参数。该实例可用于音频采集、控制和获取采集状态,以及注册通知回调。 ```js - var audioStreamInfo = { - samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_44100, - channels: audio.AudioChannel.CHANNEL_1, - sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE, - encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW - } - - var audioCapturerInfo = { - source: audio.SourceType.SOURCE_TYPE_MIC, - capturerFlags: 1 - } - - var audioCapturerOptions = { - streamInfo: audioStreamInfo, - capturerInfo: audioCapturerInfo - } - - let audioCapturer = await audio.createAudioCapturer(audioCapturerOptions); - var state = audioRenderer.state; + var audioStreamInfo = { + samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_44100, + channels: audio.AudioChannel.CHANNEL_1, + sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE, + encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW + } + + var audioCapturerInfo = { + source: audio.SourceType.SOURCE_TYPE_MIC, + capturerFlags: 1 + } + + var audioCapturerOptions = { + streamInfo: audioStreamInfo, + capturerInfo: audioCapturerInfo + } + + let audioCapturer = await audio.createAudioCapturer(audioCapturerOptions); + var state = audioRenderer.state; ``` 2. (可选)使用on('stateChange')订阅音频采集器状态更改。 -如果应用需要在采集器状态更新时进行一些操作,可以订阅该事件。更多事件请参考[API参考文档](../reference/apis/js-apis-audio.md)。 - - ```js - audioCapturer.on('stateChange',(state) => { - console.info('AudioCapturerLog: Changed State to : ' + state) - switch (state) { - case audio.AudioState.STATE_PREPARED: - console.info('--------CHANGE IN AUDIO STATE----------PREPARED--------------'); - console.info('Audio State is : Prepared'); - break; - case audio.AudioState.STATE_RUNNING: - console.info('--------CHANGE IN AUDIO STATE----------RUNNING--------------'); - console.info('Audio State is : Running'); - break; - case audio.AudioState.STATE_STOPPED: - console.info('--------CHANGE IN AUDIO STATE----------STOPPED--------------'); - console.info('Audio State is : stopped'); - break; - case audio.AudioState.STATE_RELEASED: - console.info('--------CHANGE IN AUDIO STATE----------RELEASED--------------'); - console.info('Audio State is : released'); - break; - default: - console.info('--------CHANGE IN AUDIO STATE----------INVALID--------------'); - console.info('Audio State is : invalid'); - break; - } - }); - ``` + 如果应用需要在采集器状态更新时进行一些操作,可以订阅该事件。更多事件请参考[API参考文档](../reference/apis/js-apis-audio.md)。 + + ```js + audioCapturer.on('stateChange',(state) => { + console.info('AudioCapturerLog: Changed State to : ' + state) + switch (state) { + case audio.AudioState.STATE_PREPARED: + console.info('--------CHANGE IN AUDIO STATE----------PREPARED--------------'); + console.info('Audio State is : Prepared'); + break; + case audio.AudioState.STATE_RUNNING: + console.info('--------CHANGE IN AUDIO STATE----------RUNNING--------------'); + console.info('Audio State is : Running'); + break; + case audio.AudioState.STATE_STOPPED: + console.info('--------CHANGE IN AUDIO STATE----------STOPPED--------------'); + console.info('Audio State is : stopped'); + break; + case audio.AudioState.STATE_RELEASED: + console.info('--------CHANGE IN AUDIO STATE----------RELEASED--------------'); + console.info('Audio State is : released'); + break; + default: + console.info('--------CHANGE IN AUDIO STATE----------INVALID--------------'); + console.info('Audio State is : invalid'); + break; + } + }); + ``` 3. 调用start()方法来启动/恢复采集任务。 @@ -131,7 +142,7 @@ AudioCapturer提供了用于获取原始音频文件的方法。开发者可以 6. 采集完成后,调用stop方法,停止录制。 - ``` + ```js await audioCapturer.stop(); if (audioCapturer.state == audio.AudioState.STATE_STOPPED) { console.info('AudioRecLog: Capturer stopped'); diff --git a/zh-cn/application-dev/media/audio-interruptmode.md b/zh-cn/application-dev/media/audio-interruptmode.md index 897fa18ec4..b6b112551b 100644 --- a/zh-cn/application-dev/media/audio-interruptmode.md +++ b/zh-cn/application-dev/media/audio-interruptmode.md @@ -1,19 +1,16 @@ # 音频焦点模式开发指导 -## 场景介绍 +## 简介 音频焦点模式指的是应用内,允许对多个声音的播放进行控制。
音频应用可以在AudioRenderer下设置独立焦点模式、共享焦点模式。
当设置在共享的模式下,多个音频共用一个会话ID;独立焦点模式下,每一个音频拥有单独会话ID。 -### 异步操作 +- **异步操作**:为保证UI线程不被阻塞,大部分AudioRenderer调用都是异步的。对于每个API均提供了callback函数和Promise函数,以下示例均采用Promise函数。 -为保证UI线程不被阻塞,大部分AudioRenderer调用都是异步的。对于每个API均提供了callback函数和Promise函数,以下示例均采用Promise函数。 - -## 开发步骤 +## 开发指导 详细API含义可参考:[音频管理API文档AudioRenderer](../reference/apis/js-apis-audio.md#audiorenderer8) - 1. 使用createAudioRenderer()创建一个AudioRenderer实例。
在audioRendererOptions中设置相关参数。
该实例可用于音频渲染、控制和获取采集状态,以及注册通知回调。
@@ -21,25 +18,25 @@ ```js import audio from '@ohos.multimedia.audio'; - var audioStreamInfo = { - samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_44100, - channels: audio.AudioChannel.CHANNEL_1, - sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE, - encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW - } - - var audioRendererInfo = { - content: audio.ContentType.CONTENT_TYPE_SPEECH, - usage: audio.StreamUsage.STREAM_USAGE_VOICE_COMMUNICATION, - rendererFlags: 1 - } - - var audioRendererOptions = { - streamInfo: audioStreamInfo, - rendererInfo: audioRendererInfo - } - - let audioRenderer = await audio.createAudioRenderer(audioRendererOptions); + var audioStreamInfo = { + samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_44100, + channels: audio.AudioChannel.CHANNEL_1, + sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE, + encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW + } + + var audioRendererInfo = { + content: audio.ContentType.CONTENT_TYPE_SPEECH, + usage: audio.StreamUsage.STREAM_USAGE_VOICE_COMMUNICATION, + rendererFlags: 1 + } + + var audioRendererOptions = { + streamInfo: audioStreamInfo, + rendererInfo: audioRendererInfo + } + + let audioRenderer = await audio.createAudioRenderer(audioRendererOptions); ``` 2. 设置焦点模式。 diff --git a/zh-cn/application-dev/media/audio-renderer.md b/zh-cn/application-dev/media/audio-renderer.md index 4a59bcca54..1e573b9a1e 100644 --- a/zh-cn/application-dev/media/audio-renderer.md +++ b/zh-cn/application-dev/media/audio-renderer.md @@ -1,52 +1,53 @@ # 音频渲染开发指导 -## 场景介绍 +## 简介 -AudioRenderer提供了渲染音频文件和控制播放的接口,开发者可以通过本指导,了解如何在输出设备中播放音频文件并管理播放任务。 +AudioRenderer提供了渲染音频文件和控制播放的接口,开发者可以通过本指导,了解如何在输出设备中播放音频文件并管理播放任务。同时,AudioRenderer支持音频中断的功能。 +开发者在调用AudioRenderer提供的各个接口时,需要理解以下名词: -同时,AudioRenderer支持音频中断的功能。 +- **音频中断**:当优先级较高的音频流需要播放时,AudioRenderer会中断优先级较低的流。例如,当用户在收听音乐时有来电,则优先级较低音乐播放将被暂停。 +- **状态检查**:在进行应用开发的过程中,建议开发者通过on('stateChange')方法订阅AudioRenderer的状态变更。因为针对AudioRenderer的某些操作,仅在音频播放器在固定状态时才能执行。如果应用在音频播放器处于错误状态时执行操作,系统可能会抛出异常或生成其他未定义的行为。 +- **异步操作**:为保证UI线程不被阻塞,大部分AudioRenderer调用都是异步的。对于每个API均提供了callback函数和Promise函数,以下示例均采用Promise函数,更多方式可参考[音频管理API文档AudioRenderer](../reference/apis/js-apis-audio.md#audiorenderer8)。 -### 音频中断 +## 运作机制 -当优先级较高的音频流需要播放时,AudioRenderer会中断优先级较低的流。例如,当用户在收听音乐时有来电,则优先级较低音乐播放将被暂停,具体可参考[开发步骤](#开发步骤)。 +该模块提供了音频渲染模块的状态变化示意 -### 状态检查 +**图1** 音频渲染状态示意图 -在进行应用开发的过程中,建议开发者通过on('stateChange')方法订阅AudioRenderer的状态变更。因为针对AudioRenderer的某些操作,仅在音频播放器在固定状态时才能执行。如果应用在音频播放器处于错误状态时执行操作,系统可能会抛出异常或生成其他未定义的行为。 +![audio-renderer-state](figures/audio-renderer-state.png) -**图1** 音频渲染状态机 +**PREPARED状态:** 通过调用create()方法进入到该状态。
+**RUNNING状态:** 正在进行音频数据播放,可以在prepared状态通过调用start()方法进入此状态,也可以在pause状态和stopped状态通过调用start()方法进入此状态。
+**PAUSED状态:** 在running状态可以通过pause()方法暂停音频数据的播放,暂停播放之后可以通过调用start()方法继续音频数据播放。
+**STOPPED状态:** 在paused状态可以通过调用stop()方法停止音频数据的播放,在running状态可以通过stop()方法停止音频数据的播放。
+**RELEASED状态:** 在prepared、paused、stop等状态,用户均可通过release()方法释放掉所有占用的硬件和软件资源,并且不会再进入到其他的任何一种状态了。
-![](figures/audio-renderer-state.png) - -### 异步操作 - -为保证UI线程不被阻塞,大部分AudioRenderer调用都是异步的。对于每个API均提供了callback函数和Promise函数,以下示例均采用Promise函数,更多方式可参考[音频管理API文档AudioRenderer](../reference/apis/js-apis-audio.md#audiorenderer8)。 - -## 开发步骤 +## 开发指导 1. 使用createAudioRenderer()创建一个AudioRenderer实例。 在audioCapturerOptions中设置相关参数。该实例可用于音频渲染、控制和获取采集状态,以及注册通知回调。 ```js - var audioStreamInfo = { - samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_44100, - channels: audio.AudioChannel.CHANNEL_1, - sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE, - encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW - } - - var audioRendererInfo = { - content: audio.ContentType.CONTENT_TYPE_SPEECH, - usage: audio.StreamUsage.STREAM_USAGE_VOICE_COMMUNICATION, - rendererFlags: 1 - } - - var audioRendererOptions = { - streamInfo: audioStreamInfo, - rendererInfo: audioRendererInfo - } - - let audioRenderer = await audio.createAudioRenderer(audioRendererOptions); + var audioStreamInfo = { + samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_44100, + channels: audio.AudioChannel.CHANNEL_1, + sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE, + encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW + } + + var audioRendererInfo = { + content: audio.ContentType.CONTENT_TYPE_SPEECH, + usage: audio.StreamUsage.STREAM_USAGE_VOICE_COMMUNICATION, + rendererFlags: 1 + } + + var audioRendererOptions = { + streamInfo: audioStreamInfo, + rendererInfo: audioRendererInfo + } + + let audioRenderer = await audio.createAudioRenderer(audioRendererOptions); ``` 2. 使用on('interrupt')方法订阅音频中断事件。 @@ -58,49 +59,49 @@ AudioRenderer提供了渲染音频文件和控制播放的接口,开发者可 在音频中断的情况下,应用可能会碰到音频数据写入失败的问题。所以建议不感知、不处理中断的应用在写入音频数据前,使用audioRenderer.state检查播放器状态。而订阅音频中断事件,可以获取到更多详细信息,具体可参考[InterruptEvent](../reference/apis/js-apis-audio.md#interruptevent9)。 ```js - audioRenderer.on('interrupt', (interruptEvent) => { - console.info('InterruptEvent Received'); - console.info('InterruptType: ' + interruptEvent.eventType); - console.info('InterruptForceType: ' + interruptEvent.forceType); - console.info('AInterruptHint: ' + interruptEvent.hintType); - - if (interruptEvent.forceType == audio.InterruptForceType.INTERRUPT_FORCE) { - switch (interruptEvent.hintType) { - // Force Pause: Action was taken by framework. - // Halt the write calls to avoid data loss. - case audio.InterruptHint.INTERRUPT_HINT_PAUSE: - isPlay = false; - break; - // Force Stop: Action was taken by framework. - // Halt the write calls to avoid data loss. - case audio.InterruptHint.INTERRUPT_HINT_STOP: - isPlay = false; - break; - // Force Duck: Action was taken by framework, - // just notifying the app that volume has been reduced. - case audio.InterruptHint.INTERRUPT_HINT_DUCK: - break; - // Force Unduck: Action was taken by framework, - // just notifying the app that volume has been restored. - case audio.InterruptHint.INTERRUPT_HINT_UNDUCK: - break; - } - } else if (interruptEvent.forceType == audio.InterruptForceType.INTERRUPT_SHARE) { - switch (interruptEvent.hintType) { - // Share Resume: Action is to be taken by App. - // Resume the force paused stream if required. - case audio.InterruptHint.INTERRUPT_HINT_RESUME: - startRenderer(); - break; - // Share Pause: Stream has been interrupted, - // It can choose to pause or play concurrently. - case audio.InterruptHint.INTERRUPT_HINT_PAUSE: - isPlay = false; - pauseRenderer(); - break; - } - } - }); + audioRenderer.on('interrupt', (interruptEvent) => { + console.info('InterruptEvent Received'); + console.info('InterruptType: ' + interruptEvent.eventType); + console.info('InterruptForceType: ' + interruptEvent.forceType); + console.info('AInterruptHint: ' + interruptEvent.hintType); + + if (interruptEvent.forceType == audio.InterruptForceType.INTERRUPT_FORCE) { + switch (interruptEvent.hintType) { + // Force Pause: Action was taken by framework. + // Halt the write calls to avoid data loss. + case audio.InterruptHint.INTERRUPT_HINT_PAUSE: + isPlay = false; + break; + // Force Stop: Action was taken by framework. + // Halt the write calls to avoid data loss. + case audio.InterruptHint.INTERRUPT_HINT_STOP: + isPlay = false; + break; + // Force Duck: Action was taken by framework, + // just notifying the app that volume has been reduced. + case audio.InterruptHint.INTERRUPT_HINT_DUCK: + break; + // Force Unduck: Action was taken by framework, + // just notifying the app that volume has been restored. + case audio.InterruptHint.INTERRUPT_HINT_UNDUCK: + break; + } + } else if (interruptEvent.forceType == audio.InterruptForceType.INTERRUPT_SHARE) { + switch (interruptEvent.hintType) { + // Share Resume: Action is to be taken by App. + // Resume the force paused stream if required. + case audio.InterruptHint.INTERRUPT_HINT_RESUME: + startRenderer(); + break; + // Share Pause: Stream has been interrupted, + // It can choose to pause or play concurrently. + case audio.InterruptHint.INTERRUPT_HINT_PAUSE: + isPlay = false; + pauseRenderer(); + break; + } + } + }); ``` 3. 调用start()方法来启动/恢复播放任务。 @@ -108,24 +109,24 @@ AudioRenderer提供了渲染音频文件和控制播放的接口,开发者可 启动完成后,渲染器状态将变更为STATE_RUNNING,然后应用可以开始读取缓冲区。 ```js - async function startRenderer() { - var state = audioRenderer.state; - // state should be prepared, paused or stopped. - if (state != audio.AudioState.STATE_PREPARED || state != audio.AudioState.STATE_PAUSED || - state != audio.AudioState.STATE_STOPPED) { - console.info('Renderer is not in a correct state to start'); - return; - } - - await audioRenderer.start(); - - state = audioRenderer.state; - if (state == audio.AudioState.STATE_RUNNING) { - console.info('Renderer started'); - } else { - console.error('Renderer start failed'); - } - } + async function startRenderer() { + var state = audioRenderer.state; + // state should be prepared, paused or stopped. + if (state != audio.AudioState.STATE_PREPARED || state != audio.AudioState.STATE_PAUSED || + state != audio.AudioState.STATE_STOPPED) { + console.info('Renderer is not in a correct state to start'); + return; + } + + await audioRenderer.start(); + + state = audioRenderer.state; + if (state == audio.AudioState.STATE_RUNNING) { + console.info('Renderer started'); + } else { + console.error('Renderer start failed'); + } + } ``` 4. 调用write()方法向缓冲区写入数据。 @@ -133,83 +134,83 @@ AudioRenderer提供了渲染音频文件和控制播放的接口,开发者可 将需要播放的音频数据读入缓冲区,重复调用write()方法写入。 ```js - async function writeBuffer(buf) { - var state = audioRenderer.state; - if (state != audio.AudioState.STATE_RUNNING) { - console.error('Renderer is not running, do not write'); - isPlay = false; - return; - } - let writtenbytes = await audioRenderer.write(buf); - - console.info('Actual written bytes: ' + writtenbytes); - if (writtenbytes < 0) { - console.error('Write buffer failed. check the state of renderer'); - } - } - - // Reasonable minimum buffer size for renderer. However, the renderer can accept other read sizes as well. - const bufferSize = await audioRenderer.getBufferSize(); - const path = '/data/file_example_WAV_2MG.wav'; - let ss = fileio.createStreamSync(path, 'r'); - const totalSize = 2146166; // file_example_WAV_2MG.wav - let rlen = 0; - let discardHeader = new ArrayBuffer(44); - ss.readSync(discardHeader); - rlen += 44; + async function writeBuffer(buf) { + var state = audioRenderer.state; + if (state != audio.AudioState.STATE_RUNNING) { + console.error('Renderer is not running, do not write'); + isPlay = false; + return; + } + let writtenbytes = await audioRenderer.write(buf); + + console.info('Actual written bytes: ' + writtenbytes); + if (writtenbytes < 0) { + console.error('Write buffer failed. check the state of renderer'); + } + } - var id = setInterval(() => { - if (isPlay || isRelease) { - if (rlen >= totalSize || isRelease) { - ss.closeSync(); - stopRenderer(); - clearInterval(id); - } - let buf = new ArrayBuffer(bufferSize); - rlen += ss.readSync(buf); - console.info('Total bytes read from file: ' + rlen); - writeBuffer(buf); - } else { - console.info('check after next interval'); - } - } , 30); // interval to be set based on audio file format + // Reasonable minimum buffer size for renderer. However, the renderer can accept other read sizes as well. + const bufferSize = await audioRenderer.getBufferSize(); + const path = '/data/file_example_WAV_2MG.wav'; + let ss = fileio.createStreamSync(path, 'r'); + const totalSize = 2146166; // file_example_WAV_2MG.wav + let rlen = 0; + let discardHeader = new ArrayBuffer(44); + ss.readSync(discardHeader); + rlen += 44; + + var id = setInterval(() => { + if (isPlay || isRelease) { + if (rlen >= totalSize || isRelease) { + ss.closeSync(); + stopRenderer(); + clearInterval(id); + } + let buf = new ArrayBuffer(bufferSize); + rlen += ss.readSync(buf); + console.info('Total bytes read from file: ' + rlen); + writeBuffer(buf); + } else { + console.info('check after next interval'); + } + } , 30); // interval to be set based on audio file format ``` 5. (可选)调用pause()方法或stop()方法暂停/停止渲染音频数据。 ```js - async function pauseRenderer() { - var state = audioRenderer.state; - if (state != audio.AudioState.STATE_RUNNING) { - console.info('Renderer is not running'); - return; - } - - await audioRenderer.pause(); - - state = audioRenderer.state; - if (state == audio.AudioState.STATE_PAUSED) { - console.info('Renderer paused'); - } else { - console.error('Renderer pause failed'); - } - } - - async function stopRenderer() { - var state = audioRenderer.state; - if (state != audio.AudioState.STATE_RUNNING || state != audio.AudioState.STATE_PAUSED) { - console.info('Renderer is not running or paused'); - return; - } - - await audioRenderer.stop(); - - state = audioRenderer.state; - if (state == audio.AudioState.STATE_STOPPED) { - console.info('Renderer stopped'); - } else { - console.error('Renderer stop failed'); - } + async function pauseRenderer() { + var state = audioRenderer.state; + if (state != audio.AudioState.STATE_RUNNING) { + console.info('Renderer is not running'); + return; + } + + await audioRenderer.pause(); + + state = audioRenderer.state; + if (state == audio.AudioState.STATE_PAUSED) { + console.info('Renderer paused'); + } else { + console.error('Renderer pause failed'); + } + } + + async function stopRenderer() { + var state = audioRenderer.state; + if (state != audio.AudioState.STATE_RUNNING || state != audio.AudioState.STATE_PAUSED) { + console.info('Renderer is not running or paused'); + return; + } + + await audioRenderer.stop(); + + state = audioRenderer.state; + if (state == audio.AudioState.STATE_STOPPED) { + console.info('Renderer stopped'); + } else { + console.error('Renderer stop failed'); + } } ``` @@ -218,20 +219,20 @@ AudioRenderer提供了渲染音频文件和控制播放的接口,开发者可 AudioRenderer会使用大量的系统资源,所以请确保完成相关任务后,进行资源释放。 ```js - async function releaseRenderer() { - if (state_ == RELEASED || state_ == NEW) { - console.info('Resourced already released'); - return; - } - - await audioRenderer.release(); - - state = audioRenderer.state; - if (state == STATE_RELEASED) { - console.info('Renderer released'); - } else { - console.info('Renderer release failed'); - } - - } + async function releaseRenderer() { + if (state_ == RELEASED || state_ == NEW) { + console.info('Resourced already released'); + return; + } + + await audioRenderer.release(); + + state = audioRenderer.state; + if (state == STATE_RELEASED) { + console.info('Renderer released'); + } else { + console.info('Renderer release failed'); + } + + } ``` \ No newline at end of file diff --git a/zh-cn/application-dev/media/audio-stream-manager.md b/zh-cn/application-dev/media/audio-stream-manager.md index 84f3f72152..eae42fd248 100644 --- a/zh-cn/application-dev/media/audio-stream-manager.md +++ b/zh-cn/application-dev/media/audio-stream-manager.md @@ -1,27 +1,30 @@ # 音频流管理开发指导 -## 场景介绍 +## 简介 AudioStreamManager提供了音频流管理的方法。开发者可以通过本指导了解应用如何通过AudioStreamManager管理音频流。 -### 工作流程 +## 运作机制 -在进行应用开发的过程中,开发者需要使用getStreamManager()创建一个AudioStreamManager实例,进而通过该实例管理音频流。开发者可通过调用on('audioRendererChange')、on('audioCapturerChange')监听音频播放应用和音频录制应用,在应用状态变化、设备变化、音频属性变化时获得通知。同时可通过off('audioRendererChange')、off('audioCapturerChange')取消相关事件的监听。与此同时,开发者可以通过调用(可选)使用getCurrentAudioRendererInfoArray()获取当前音频播放应用的音频流唯一ID、音频播放客户端的UID、音频状态等信息,同理可调用getCurrentAudioCapturerInfoArray()获取音频录制应用的信息。其具体调用关系可参考音频流管理调用关系图。 - -详细API含义可参考:[音频管理API文档AudioStreamManager](../reference/apis/js-apis-audio.md#audiostreammanager9) +该模块提供了音频流管理调用关系图 **图1** 音频流管理调用关系图 -![](figures/zh-ch_image_audio_stream_manager.png) +![zh-ch_image_audio_stream_manager](figures/zh-ch_image_audio_stream_manager.png) + +**说明**:在进行应用开发的过程中,开发者需要使用getStreamManager()创建一个AudioStreamManager实例,进而通过该实例管理音频流。开发者可通过调用on('audioRendererChange')、on('audioCapturerChange')监听音频播放应用和音频录制应用,在应用状态变化、设备变化、音频属性变化时获得通知。同时可通过off('audioRendererChange')、off('audioCapturerChange')取消相关事件的监听。与此同时,开发者可以通过调用(可选)使用getCurrentAudioRendererInfoArray()获取当前音频播放应用的音频流唯一ID、音频播放客户端的UID、音频状态等信息,同理可调用getCurrentAudioCapturerInfoArray()获取音频录制应用的信息。 -## 开发步骤 +## 开发指导 + +详细API含义可参考:[音频管理API文档AudioStreamManager](../reference/apis/js-apis-audio.md#audiostreammanager9) 1. 创建AudioStreamManager实例。 在使用AudioStreamManager的API前,需要使用getStreamManager()创建一个AudioStreamManager实例。 ```js - var audioStreamManager = audio.getStreamManager(); + var audioManager = audio.getAudioManager(); + var audioStreamManager = audioManager.getStreamManager(); ``` 2. (可选)使用on('audioRendererChange')监听音频渲染器更改事件。 diff --git a/zh-cn/application-dev/media/opensles-capture.md b/zh-cn/application-dev/media/opensles-capture.md index ef458a0911..4c9a885315 100644 --- a/zh-cn/application-dev/media/opensles-capture.md +++ b/zh-cn/application-dev/media/opensles-capture.md @@ -1,10 +1,10 @@ # OpenSL ES音频录制开发指导 -## 场景介绍 +## 简介 -开发者可以通过本文了解到在**OpenHarmony**如何使用 **OpenSL ES** 进行录音相关操作;当前仅实现了部分[**OpenSL ES**接口](https://gitee.com/openharmony/third_party_opensles/blob/master/api/1.0.1/OpenSLES.h),未实现接口调用后会返回**SL_RESULT_FEATURE_UNSUPPORTED**。 +开发者可以通过本文档了解在**OpenHarmony**中如何使用**OpenSL ES**进行录音相关操作;当前仅实现了部分[**OpenSL ES**接口](https://gitee.com/openharmony/third_party_opensles/blob/master/api/1.0.1/OpenSLES.h),因此调用未实现接口后会返回**SL_RESULT_FEATURE_UNSUPPORTED**。 -## 开发步骤 +## 开发指导 以下步骤描述了在**OpenHarmony**如何使用 **OpenSL ES** 开发音频录音功能: diff --git a/zh-cn/application-dev/media/opensles-playback.md b/zh-cn/application-dev/media/opensles-playback.md index 66e90957f3..51108a83dc 100644 --- a/zh-cn/application-dev/media/opensles-playback.md +++ b/zh-cn/application-dev/media/opensles-playback.md @@ -1,10 +1,10 @@ # OpenSL ES音频播放开发指导 -## 场景介绍 +## 简介 -开发者可以通过本文了解到在**OpenHarmony**如何使用**OpenSL ES**进行音频播放相关操作;当前仅实现了部分[**OpenSL ES**接口](https://gitee.com/openharmony/third_party_opensles/blob/master/api/1.0.1/OpenSLES.h),未实现接口调用后会返回**SL_RESULT_FEATURE_UNSUPPORTED** +开发者可以通过本文档了解在**OpenHarmony**中如何使用**OpenSL ES**进行音频播放相关操作;当前仅实现了部分[**OpenSL ES**接口](https://gitee.com/openharmony/third_party_opensles/blob/master/api/1.0.1/OpenSLES.h),因此调用未实现接口后会返回**SL_RESULT_FEATURE_UNSUPPORTED** -## 开发步骤 +## 开发指导 以下步骤描述了在**OpenHarmony**如何使用**OpenSL ES**开发音频播放功能: @@ -58,7 +58,7 @@ 5. 获取接口 **SL_IID_OH_BUFFERQUEUE** 的 **bufferQueueItf** 实例 - ``` + ```c++ SLOHBufferQueueItf bufferQueueItf; (*pcmPlayerObject)->GetInterface(pcmPlayerObject, SL_IID_OH_BUFFERQUEUE, &bufferQueueItf); ``` -- GitLab