Obtain an API key. Do not hard-code a long-lived API key in a client application. We recommend that your application server obtain a temporary API key and send it to the client.
Download the latest SDK package. Extract the package, copy entry/libs/neonui.har to the entry/libs directory of your application, and add the dependency to entry/oh-package.json5:
For a HarmonyOS C++ integration, use the shared libraries in native/libs and the header files in native/include.
Declare network and microphone permissions in the application module.json5 file, and request microphone permission at runtime. reason_internet and reason_microphone are example resource names. Define the corresponding descriptions in your application resources.
Open the sample project from the SDK package in DevEco Studio. The sample page is entry/src/main/ets/pages/dashscope/DashFunAsrSpeechTranscriberPage.ets. Configure an API key and run the project.
Service endpoint. Use the public endpoint wss://dashscope.aliyuncs.com/api-ws/v1/inference, or a workspace-specific endpoint: wss://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api-ws/v1/inference for Beijing or wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/inference for Singapore. Replace {WorkspaceId} with your workspace ID.
service_mode
string
Yes
Run mode. Set this to "1", which is Constants.ModeFullCloud, for real-time speech recognition.
device_id
string
Yes
A unique end-user identifier, such as an in-app user ID or a client-generated device ID. It is used mainly for log tracing and troubleshooting.
apikey
string
No
API key. You can pass it during initialization. We recommend that you pass a temporary API key in the dialog_params argument of startDialog.
audio_update_manually
string
No
Whether to enable active audio push mode. Default: "false". If set to "true", call updateAudio. If set to "false", the SDK pulls audio through onNuiNeedAudioData. When this field is "true" and the SDK supports on-device audio processing such as AEC or VAD, the supported capabilities are enabled by default.
workspace
string
No
Directory that stores on-device resource files. This parameter is required when audio_update_manually is "true" and on-device audio processing such as AEC or VAD is enabled.
debug_path
string
No
Log directory. This parameter is required when save_log is true. The SDK keeps at most two log files.
save_wav
string
No
Whether to save debugging audio. Default: "false". Audio files are saved in debug_path. If set to "true", also set debug_path and pass true for save_log to initialize.
save_wav_by_id
string
No
Whether to name saved audio files by task_id for easier retrieval when save_wav is enabled. Default: "false".
max_log_file_size
number
No
Maximum size of a single log file in bytes. Default: 104857600 (100 MiB). This parameter takes effect only when save_log is true.
log_track_level
number
No
Filter level for logs returned through onNuiLogTrackCallback. Default: 2. Valid values: 0 (VERBOSE), 1 (DEBUG), 2 (INFO), 3 (WARNING), 4 (ERROR), and 5 (NONE). A log is returned only if its level is greater than or equal to both log_track_level and the level argument of initialize. For example, if the values are 2 and 3, only WARNING and higher-level logs are returned.
enable_reconnection
string
No
Whether to enable reconnection and transmission resumption after a network interruption. Default: "false".
aec_params
object
No
On-device AEC settings. Used only when audio_update_manually is "true".
aec_params.enable_aec
boolean
No
Whether to enable on-device AEC. It is enabled by default when the SDK build supports it.
aec_params.save_audio
boolean
No
Whether to save audio processed by AEC. It is enabled by default when save_wav is enabled and debug_path is set.
aec_params.enable_aec_data_callback
boolean
No
Whether to return AEC-processed data through the EVENT_AEC_DATA event of onNuiAssistEventCallback. Default: false.
vad_params
object
No
On-device VAD settings. Used only when audio_update_manually is "true".
vad_params.enable_vad
boolean
No
Whether to enable on-device VAD. It is enabled by default when the SDK build supports it.
vad_params.save_audio
boolean
No
Whether to save audio processed by VAD. It is enabled by default when save_wav is enabled and debug_path is set.
audio_config
object
No
Audio capture settings for SDK pull mode. Used only when audio_update_manually is "false".
audio_config.mic.enable_volume_calculation
boolean
No
Whether to calculate and report volume. Default: true. Disable this option if volume callbacks are not needed.
audio_config.mic.volume_mode
string
No
Volume calculation mode. Set this to "dbfs" to calculate standard dBFS as 20*log10(rms/32768), where full scale is 0 dB.
Pass a JSON string in the params argument of setParams.
The qwen-audio-3.1-asr-flash-message model does not support the following parameters: nls_config.language_hints, nls_config.semantic_punctuation_enabled, nls_config.multi_threshold_mode_enabled, nls_config.special_word_filter.
Audio format: pcm or opus. When set to opus, your application still supplies PCM data and the SDK encodes it as Opus.
nls_config.sample_rate
number
Yes
Sample rate in Hz. 8 kHz models require 8000; other models accept any sample rate. A sample rate of 8000 Hz is not supported when on-device AEC or VAD is enabled.
nls_config.semantic_punctuation_enabled
boolean
No
Whether to enable semantic sentence segmentation. Default: false. true enables semantic segmentation and disables VAD segmentation, which is suitable for meeting transcription scenarios that prioritize segmentation accuracy. false enables VAD segmentation and disables semantic segmentation, which is suitable for interactive scenarios that prioritize low latency.
nls_config.max_sentence_silence
number
No
VAD silence threshold in milliseconds. The system determines that an utterance has ended when the silence after speech exceeds this threshold. Default: 1300. Valid range: [200, 6000]. When semantic segmentation is enabled, this parameter is not used to determine sentence_end, but an excessively small value may still affect recognition.
nls_config.multi_threshold_mode_enabled
boolean
No
Whether to enable multi-threshold mode. Default: false. This mode helps prevent excessively long VAD segments. It takes effect only when semantic_punctuation_enabled is false.
nls_config.heartbeat
boolean
No
Whether to enable heartbeat packets. Default: false. When enabled, continuously sending silent audio can keep the connection active. Otherwise, the connection times out after a period of time. Silent audio contains no audible signal in the audio file or stream.
nls_config.disfluency_removal_enabled
boolean
No
Supported only by qwen-audio-3.1-asr-flash-message. Whether to filter filler words and polish the output. Defaults to false. Set to true to enable this feature.
nls_config.intermediate_result_enabled
boolean
No
Supported only by qwen-audio-3.1-asr-flash-message. Whether to return intermediate streaming results. Defaults to false. Set to true to return intermediate streaming results.
nls_config.vocabulary_id
string
No
ID of a precompiled hotword list. Create the list in advance. Use this field when the vocabulary is known and relatively stable and the same list must be reused across requests. See Precompiled hotwords.
nls_config.instant_vocabulary
object
No
Request-level hotwords. Keys are hotword strings, and values are integer weights. No list must be created in advance, making this field suitable for temporary session-level optimization. Valid weights are [1, 5] or 50. For [1, 5], a larger value makes the model more likely to output the word. At most 50 super hotwords with a weight of 50 are allowed. When precompiled and request-level hotwords are both configured, the sets are merged. If the merged set exceeds 2000 entries, 2000 are selected at random. Only qwen-audio-3.1-asr-flash-message and qwen-audio-3.0-asr-flash-streaming support request-level hotwords. See Request-level hotwords.
nls_config.language_hints
string[]
No
Languages in the audio. No default. If this field is omitted, the model detects the language. Qwen-Audio-3.x-ASR-Flash-Streaming uses at most the first four values. Fun-ASR-Realtime uses only the first value. For supported language codes, see the real-time speech recognition guide.
nls_config.speech_noise_threshold
number
No
VAD speech/noise threshold. Valid range: [-1.0, 1.0]. Values closer to -1 classify more noise as speech and may transcribe more noise. Values closer to 1 classify more speech as noise and may filter some speech. This advanced setting can significantly affect recognition. Test it thoroughly and adjust it in small increments of 0.1.
SDK mode: MODE_DIALOG for dialog or recognition, MODE_TTS for speech synthesis, or MODE_STREAM_INPUT_TTS for streaming-input text-to-speech. Set this to MODE_DIALOG for real-time speech recognition.
flag
string
Optional instance identifier used to distinguish logs.
Notifies the server to finish recognition and return the final result. The task ends when EVENT_TRANSCRIBER_COMPLETE is received. The method returns an error code.
Sends a runtime action to update recognition context or notify AEC of playback state changes.
Parameter
Type
Description
action_params
string
JSON string that contains the action.
action_params.type
string
Set this to "action".
action_params.command
string
Action command: "context" updates input context, "play_start" notifies AEC that reference-audio playback has started, and "play_over" notifies AEC that playback has ended.
Releases all internal SDK resources. The instance cannot be used after this call. To use it again, call initialize first. The method returns an error code.
Error code. This field is valid for EVENT_ASR_ERROR.
arg2
number
Reserved.
kwsResult
KwsResult
Wake-word result. Ignore this field for real-time speech recognition.
asrResult
AsrResult
Recognition result. allResponse contains the complete server JSON response. Retrieve the task ID from header.task_id and utterance text from payload.output.sentence.text.
Events:
Event
Description
EVENT_TRANSCRIBER_STARTED
The task has started. header.task_id in asrResult.allResponse contains the task ID. Record this ID for troubleshooting.
EVENT_VAD_START
Triggered after the task starts. This event does not indicate that the start of speech was detected.
EVENT_VAD_END
The end of speech was detected.
EVENT_SENTENCE_START
The start of an utterance was detected.
EVENT_ASR_PARTIAL_RESULT
An intermediate recognition result is available.
EVENT_SENTENCE_END
The end of an utterance was detected, and the complete result for the utterance is available.
EVENT_ASR_WARN
A non-fatal warning occurred during recognition, such as a network interruption when reconnection is enabled.
EVENT_ASR_ERROR
An error occurred during recognition. resultCode contains the error code.
EVENT_MIC_ERROR
No audio data was received for two consecutive seconds. Check the recording code, permissions, or whether another application is using the recorder.
EVENT_TRANSCRIBER_COMPLETE
Recognition has ended.
EVENT_AEC_DATA
AEC-processed audio data returned through onNuiAssistEventCallback.
The SDK uses this callback to notify the application when to start or stop recording.
State
Description
STATE_OPEN
The interaction has started. The recording device can be opened.
STATE_PAUSE
The interaction has stopped. Recording can be stopped.
STATE_CLOSE
The SDK instance has been released. The recording device can be closed completely.
On HarmonyOS, AudioCapturer is created asynchronously. Create the recorder instance during initialization. When STATE_CLOSE is received, stop recording but retain the instance for reuse. Release it in the unified release flow. This prevents a recreated recorder from ignoring an immediate start call when the next STATE_OPEN event arrives.
Called continuously when the SDK pulls audio. Fill buffer.byteLength bytes, typically 20 ms of mono 16-bit PCM, and return the number of bytes written. A value less than or equal to 0 indicates an error or no available data.
Reports the current audio volume for UI updates. When audio_config.mic.volume_mode is "dbfs", val ranges from -160 to 0. The callback implementation can return 0.
The following code shows the core SDK flow. For complete permission handling, recording queue, and response parsing, see DashFunAsrSpeechTranscriberPage.ets in the SDK package.
Copy
import { AsrResult, Constants, INativeNuiCallback, KwsResult, NativeNui } from 'neonui';const callback: INativeNuiCallback = { onNuiEventCallback: (event: Constants.NuiEvent, resultCode: number, arg2: number, kwsResult: KwsResult, asrResult: AsrResult): void => { if (event == Constants.NuiEvent.EVENT_ASR_PARTIAL_RESULT || event == Constants.NuiEvent.EVENT_SENTENCE_END) { // Parse payload.output.sentence.text from asrResult.allResponse. } else if (event == Constants.NuiEvent.EVENT_TRANSCRIBER_COMPLETE) { // Recognition is complete. } else if (event == Constants.NuiEvent.EVENT_ASR_ERROR) { // resultCode contains the error code. } }, onNuiAudioStateChanged: (state: Constants.AudioState): void => { // Control AudioCapturer for STATE_OPEN, STATE_PAUSE, and STATE_CLOSE. }, onNuiNeedAudioData: (buffer: ArrayBuffer): number => { // Copy recording data to buffer and return the number of bytes written. return 0; }, onNuiAudioRMSChanged: (val: number): number => 0, onNuiLogTrackCallback: (level: Constants.LogLevel, log: string): void => {}};const nuiInstance = new NativeNui(Constants.ModeType.MODE_DIALOG);const initParams: Record<string, Object> = {};initParams['url'] = 'wss://dashscope.aliyuncs.com/api-ws/v1/inference';initParams['device_id'] = 'my_device_id';initParams['service_mode'] = Constants.ModeFullCloud;initParams['audio_update_manually'] = 'false';const initResult = nuiInstance.initialize( callback, JSON.stringify(initParams), Constants.LogLevel.LOG_LEVEL_DEBUG, false);if (initResult == Constants.NuiResultCode.SUCCESS) { const nlsConfig: Record<string, Object> = { 'model': 'qwen-audio-3.0-asr-flash-streaming', 'sr_format': 'opus', 'sample_rate': 16000 }; const params: Record<string, Object> = { 'service_type': Constants.kServiceTypeSpeechTranscriber, 'nls_config': nlsConfig }; nuiInstance.setParams(JSON.stringify(params)); const dialogParams: Record<string, Object> = { 'apikey': 'st-****' }; nuiInstance.startDialog(Constants.VadMode.TYPE_P2T, JSON.stringify(dialogParams));}// Stop recognition when the user finishes recording, and wait for EVENT_TRANSCRIBER_COMPLETE.function stopRecognition(): void { nuiInstance.stopDialog();}// Call nuiInstance.release() from the EVENT_TRANSCRIBER_COMPLETE handler.
Use AudioCapturer from @kit.AudioKit for recording. Audio must be mono 16-bit PCM with a sample rate supported by the selected model.