All Products
Search
Document Center

Alibaba Cloud Model Studio:Qwen-Audio-3.0-ASR-Flash-Streaming/Fun-ASR-Realtime Speech Recognition HarmonyOS SDK

Last Updated:Sep 10, 2026

Learn about HarmonyOS SDK integration, request parameters, APIs, callbacks, and sample code for real-time speech recognition.

For model descriptions and selection guidance, see Speech recognition.

Quick start

  1. 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.
  2. 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:
{
  "dependencies": {
    "neonui": "file:libs/neonui.har"
  }
}

For a HarmonyOS C++ integration, use the shared libraries in native/libs and the header files in native/include.

  1. 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.
"requestPermissions": [
  {
    "name": "ohos.permission.INTERNET",
    "reason": "$string:reason_internet",
    "usedScene": { "abilities": ["EntryAbility"], "when": "always" }
  },
  {
    "name": "ohos.permission.MICROPHONE",
    "reason": "$string:reason_microphone",
    "usedScene": { "abilities": ["EntryAbility"], "when": "always" }
  }
]
  1. 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.

Call sequence

  1. Create a NativeNui(Constants.ModeType.MODE_DIALOG) instance.
  2. Call initialize to initialize the SDK and configure connection and control parameters.
  3. Call setParams to configure the model and recognition parameters.
  4. Call startDialog to start recognition.
  5. In onNuiAudioStateChanged, start, pause, or close the recording device based on the audio state.
  6. Continuously supply recording data in onNuiNeedAudioData. If active audio pushing is enabled, call updateAudio instead.
  7. Retrieve recognition results and task states in onNuiEventCallback.
  8. Call stopDialog, and wait for EVENT_TRANSCRIBER_COMPLETE.
  9. When recognition is no longer needed, call release to release resources.

Request parameters

Connection and control parameters

Pass a JSON string in the parameters argument of initialize.

{
  "url": "wss://dashscope.aliyuncs.com/api-ws/v1/inference",
  "device_id": "my_device_id",
  "service_mode": "1",
  "audio_update_manually": "false"
}
ParameterTypeRequiredDescription
urlstringYesService 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_modestringYesRun mode. Set this to "1", which is Constants.ModeFullCloud, for real-time speech recognition.
device_idstringYesA 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.
apikeystringNoAPI 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_manuallystringNoWhether 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.
workspacestringNoDirectory 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_pathstringNoLog directory. This parameter is required when save_log is true. The SDK keeps at most two log files.
save_wavstringNoWhether 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_idstringNoWhether to name saved audio files by task_id for easier retrieval when save_wav is enabled. Default: "false".
max_log_file_sizenumberNoMaximum size of a single log file in bytes. Default: 104857600 (100 MiB). This parameter takes effect only when save_log is true.
log_track_levelnumberNoFilter 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_reconnectionstringNoWhether to enable reconnection and transmission resumption after a network interruption. Default: "false".
aec_paramsobjectNoOn-device AEC settings. Used only when audio_update_manually is "true".
aec_params.enable_aecbooleanNoWhether to enable on-device AEC. It is enabled by default when the SDK build supports it.
aec_params.save_audiobooleanNoWhether 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_callbackbooleanNoWhether to return AEC-processed data through the EVENT_AEC_DATA event of onNuiAssistEventCallback. Default: false.
vad_paramsobjectNoOn-device VAD settings. Used only when audio_update_manually is "true".
vad_params.enable_vadbooleanNoWhether to enable on-device VAD. It is enabled by default when the SDK build supports it.
vad_params.save_audiobooleanNoWhether to save audio processed by VAD. It is enabled by default when save_wav is enabled and debug_path is set.
audio_configobjectNoAudio capture settings for SDK pull mode. Used only when audio_update_manually is "false".
audio_config.mic.enable_volume_calculationbooleanNoWhether to calculate and report volume. Default: true. Disable this option if volume callbacks are not needed.
audio_config.mic.volume_modestringNoVolume calculation mode. Set this to "dbfs" to calculate standard dBFS as 20*log10(rms/32768), where full scale is 0 dB.

Recognition parameters

Pass a JSON string in the params argument of setParams.

{
  "service_type": 4,
  "nls_config": {
    "model": "qwen-audio-3.0-asr-flash-streaming",
    "sr_format": "opus",
    "sample_rate": 16000
  }
}
ParameterTypeRequiredDescription
service_typenumberYesSpeech service type. Set this to 4, which is Constants.kServiceTypeSpeechTranscriber.
nls_configobjectYesRecognition configuration object.
nls_config.modelstringYesModel name. Qwen-Audio-3.0-ASR-Flash-Streaming and Fun-ASR-Realtime model families are supported. See Supported models and regions.
nls_config.sr_formatstringYesAudio format: pcm or opus. When set to opus, your application still supplies PCM data and the SDK encodes it as Opus.
nls_config.sample_ratenumberYesSample 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_enabledbooleanNoWhether 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_silencenumberNoVAD 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_enabledbooleanNoWhether 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.heartbeatbooleanNoWhether 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.vocabulary_idstringNoID 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_vocabularyobjectNoRequest-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.0-asr-flash-streaming supports request-level hotwords. See Request-level hotwords.
nls_config.language_hintsstring[]NoLanguages in the audio. No default. If this field is omitted, the model detects the language. Qwen-Audio-3.0-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_thresholdnumberNoVAD 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.
nls_config.special_word_filterobjectNoSensitive-word filtering settings. See Sensitive-word filtering.
nls_config.enable_connection_fast_checkbooleanNoWhether to enable fast network interruption detection. Default: false.

APIs

NativeNui

Import the SDK:

import { AsrResult, Constants, INativeNuiCallback, KwsResult, NativeNui } from 'neonui';

Create an instance

constructor(mode_type: Constants.ModeType, flag?: string)
ParameterTypeDescription
mode_typeConstants.ModeTypeSDK 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.
flagstringOptional instance identifier used to distinguish logs.

initialize

initialize(
  callback: INativeNuiCallback,
  parameters: string,
  level: number,
  save_log: boolean = false
): number

Initializes the SDK. This method can block. Do not call it on the UI thread.

ParameterTypeDescription
callbackINativeNuiCallbackEvent and data callback.
parametersstringJSON string of connection and control parameters.
levelnumberSDK log level: LOG_LEVEL_VERBOSE (0), LOG_LEVEL_DEBUG (1), LOG_LEVEL_INFO (2), LOG_LEVEL_WARNING (3), LOG_LEVEL_ERROR (4), or LOG_LEVEL_NONE (5).
save_logbooleanWhether to save local logs. Default: false. If set to true, set debug_path in parameters. You can also set max_log_file_size.

The method returns an error code.

setParams

setParams(params: string): number

Sets recognition parameters before startDialog. params is a JSON string that contains the recognition parameters. The method returns an error code.

startDialog

startDialog(vad_mode: Constants.VadMode, dialog_params: string): number

Starts recognition.

ParameterTypeDescription
vad_modeConstants.VadModeVAD mode. Set this to Constants.VadMode.TYPE_P2T for real-time speech recognition.
dialog_paramsstringJSON string. Use it to refresh an expired temporary API key or pass input context in input_context.

Example:

{
  "apikey": "st-****",
  "input_context": [
    { "role": "user", "content": [{ "type": "input_text", "text": "Example context" }] }
  ]
}

The method returns an error code.

stopDialog

stopDialog(): number

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.

cancelDialog

cancelDialog(): number

Immediately terminates recognition without waiting for a final server result. The method returns an error code.

dialogAction

dialogAction(action_params: string): number

Sends a runtime action to update recognition context or notify AEC of playback state changes.

ParameterTypeDescription
action_paramsstringJSON string that contains the action.
action_params.typestringSet this to "action".
action_params.commandstringAction command: "context" updates input context, "play_start" notifies AEC that reference-audio playback has started, and "play_over" notifies AEC that playback has ended.
action_params.contextobject[]Input context to use when command is "context".

Example for updating context:

{
  "type": "action",
  "command": "context",
  "context": [
    {
      "role": "user",
      "content": [
        { "text": "Example context", "type": "input_text" }
      ]
    }
  ]
}

The method returns an error code.

updateAudio

updateAudio(data: ArrayBuffer, first_pack: boolean): number

When audio_update_manually is "true", actively pushes recording data through this method instead of filling onNuiNeedAudioData.

ParameterTypeDescription
dataArrayBufferAudio data to recognize.
first_packbooleanWhether this is the first audio packet. Set this to true for the first packet and false for subsequent packets.

The method returns an error code.

pushReferenceData

pushReferenceData(data: ArrayBuffer, first_pack: boolean): number

When audio_update_manually is "true" and on-device AEC is enabled, pushes audio played by the player as the AEC reference signal.

ParameterTypeDescription
dataArrayBufferReference audio data.
first_packbooleanWhether this is the first audio packet. Set this to true for the first packet and false for subsequent packets.

The method returns an error code.

release

release(): number

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.

GetVersion

GetVersion(): string

Returns the current SDK version.

refreshApikey

refreshApikey(apikey: string, url: string = ''): string

Refreshes an API key and returns a temporary authentication token. This method performs a synchronous network call. Do not call it on the UI thread.

ParameterTypeDescription
apikeystringExisting API key.
urlstringOptional authentication endpoint. Default: an empty string, which uses the default endpoint.

INativeNuiCallback

onNuiEventCallback

onNuiEventCallback: (
  event: Constants.NuiEvent,
  resultCode: number,
  arg2: number,
  kwsResult: KwsResult,
  asrResult: AsrResult
) => void;

Receives recognition events and results.

ParameterTypeDescription
eventConstants.NuiEventCallback event.
resultCodenumberError code. This field is valid for EVENT_ASR_ERROR.
arg2numberReserved.
kwsResultKwsResultWake-word result. Ignore this field for real-time speech recognition.
asrResultAsrResultRecognition 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:

EventDescription
EVENT_TRANSCRIBER_STARTEDThe task has started. header.task_id in asrResult.allResponse contains the task ID. Record this ID for troubleshooting.
EVENT_VAD_STARTTriggered after the task starts. This event does not indicate that the start of speech was detected.
EVENT_VAD_ENDThe end of speech was detected.
EVENT_SENTENCE_STARTThe start of an utterance was detected.
EVENT_ASR_PARTIAL_RESULTAn intermediate recognition result is available.
EVENT_SENTENCE_ENDThe end of an utterance was detected, and the complete result for the utterance is available.
EVENT_ASR_WARNA non-fatal warning occurred during recognition, such as a network interruption when reconnection is enabled.
EVENT_ASR_ERRORAn error occurred during recognition. resultCode contains the error code.
EVENT_MIC_ERRORNo audio data was received for two consecutive seconds. Check the recording code, permissions, or whether another application is using the recorder.
EVENT_TRANSCRIBER_COMPLETERecognition has ended.
EVENT_AEC_DATAAEC-processed audio data returned through onNuiAssistEventCallback.

onNuiAudioStateChanged

onNuiAudioStateChanged: (state: Constants.AudioState) => void;

The SDK uses this callback to notify the application when to start or stop recording.

StateDescription
STATE_OPENThe interaction has started. The recording device can be opened.
STATE_PAUSEThe interaction has stopped. Recording can be stopped.
STATE_CLOSEThe 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.

onNuiNeedAudioData

onNuiNeedAudioData: (buffer: ArrayBuffer) => number;

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.

onNuiAudioRMSChanged

onNuiAudioRMSChanged: (val: number) => number;

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.

onNuiAssistEventCallback

onNuiAssistEventCallback?: (
  event: Constants.NuiEvent,
  info: string,
  infoLen: number,
  data: ArrayBuffer
) => void;

Optional callback for internal SDK auxiliary events and data. Omit this callback if the information is not needed.

ParameterTypeDescription
eventConstants.NuiEventAuxiliary event.
infostringAdditional information, usually a JSON string.
infoLennumberLength of the additional information.
dataArrayBufferAuxiliary data, such as AEC-processed audio.

onNuiLogTrackCallback

onNuiLogTrackCallback: (level: Constants.LogLevel, log: string) => void;

Receives SDK trace logs. The returned levels are determined by both log_track_level and the level argument of initialize.

Result objects

AsrResult

PropertyTypeDescription
finishbooleanWhether the current result is final.
resultCodenumberResult status code.
asrResultstringRecognition text. For EVENT_ASR_ERROR, this field contains the error message.
allResponsestringComplete server response as a JSON string, including the task ID and utterance text.

KwsResult

PropertyTypeDescription
typeConstants.WuwTypeWake-word type. Ignore this field for real-time speech recognition.
kwsstringWake word. Ignore this field for real-time speech recognition.

Constants and enumerations

NameDescription
Constants.ModeTypeSDK modes: MODE_DIALOG, MODE_TTS, and MODE_STREAM_INPUT_TTS.
Constants.VadModeVAD mode. Real-time speech recognition uses TYPE_P2T, where the user calls stopDialog to end recognition.
Constants.AudioStateAudio states: STATE_OPEN, STATE_PAUSE, and STATE_CLOSE.
Constants.LogLevelLog levels from LOG_LEVEL_VERBOSE (0) to LOG_LEVEL_NONE (5).
Constants.NuiResultCodeSDK error codes, such as SUCCESS (0), ILLEGAL_PARAM (240002), NECESSARY_PARAM_LACK (240004), and SDK_NOT_INIT (240011).
Constants.kServiceTypeSpeechTranscriberservice_type value for real-time speech recognition. The value is 4.
Constants.ModeFullCloudFull-cloud mode. The service_mode value is "1".

Sample code

The following code shows the core SDK flow. For complete permission handling, recording queue, and response parsing, see DashFunAsrSpeechTranscriberPage.ets in the SDK package.

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.

import { audio } from '@kit.AudioKit';

const options: audio.AudioCapturerOptions = {
  streamInfo: {
    samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_16000,
    channels: audio.AudioChannel.CHANNEL_1,
    sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE,
    encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW
  },
  capturerInfo: {
    source: audio.SourceType.SOURCE_TYPE_MIC,
    capturerFlags: 0
  }
};

const capturer = await audio.createAudioCapturer(options);
capturer.on('readData', (buffer: ArrayBuffer): void => {
  // Pull mode: enqueue data for onNuiNeedAudioData.
  // Push mode: call nuiInstance.updateAudio(buffer, firstPack).
});
await capturer.start();