Skip to main content

Qwen-Audio-ASR-Message AOQ access

This section describes the authentication, media configuration, connection establishment, and task-event handling flow for accessing Qwen-Audio-ASR-Message via AOQ.

When accessing Qwen-Audio-ASR-Message through AOQ, the client uploads audio via the Audio track, sends task events and receives recognition results via the Data track.

Prerequisites

  • Use qwen-audio-3.1-asr-flash-message. For specific supported scopes, see Model and Protocol Support Scope.
  • Configure and call the API Key on the business AppServer, matching the region and workspace.
  • Import the platform-specific AOQ SDK by downloading fromSDK. The following explanation uses Android Java and Opus transmission as an example; please also import the Opus plugin. When using a microphone for audio capture, request recording permissions on the client side.

1. Obtain Connection Credentials

Set the environment variable DASHSCOPE_API_KEY on the AppServer, replacing {endpoint} with the access domain name for the selected region and workspace. Use the Inference connection path for Qwen-Audio-ASR-Message; the following example uses qwen-audio-3.1-asr-flash-message.
curl -X POST \
  "https://{endpoint}/api/v1/webrtc/inference?model=qwen-audio-3.1-asr-flash-message" \
  -H "Authorization: Bearer ${DASHSCOPE_API_KEY}" \
  -H "Content-Type: application/json" \
  -H "x-dashscope-rtc-transport: moq" \
  -d '{}'
If using Token Plan, the WorkspaceId in the access domain name is fixed as token-plan. The clientIp in the request body is optional; enter the client’s real public IP address so that the gateway can select a Relay access point. If left blank, the gateway uses the request source IP. The API Key is stored only on the AppServer. The AppServer returns the connection parameters in the table below to the client; the sidExpiresInSecs in the response indicates the session validity period, in seconds.
Gateway Response FieldsAoqConnectConfig Field
aoqTokenForClienttoken
sidsid
clientRelayCertFingerprintcertFingerprint
clientRelayEndpointsrelayEndpoints, convert endpoint, port, and route_index item by item
extraInfo.workspaceIdHashworkspaceIdHash

2. Initialize SDK and Connect

Use AoqCreateConfig to set the SDK working directory, call AoqClientEngine.createEngine to create the engine and register callbacks. Handle connection status in onConnectionStatusChange, parse model events in onDataMsg, and handle SDK errors in onError. Android SDK provides complete interface documentation for engine initialization and connection fields. After filling the credential returned by the AppServer into connectConfig, publish the Audio and Data tracks and subscribe to the Data track. The following example configures 16 kHz mono Opus encoding and built-in capture, and disables Audio track transmission during connection establishment. The model’s input format is specified by the task event, and the SDK encoding configuration is used for media track transmission.
AoqClientEngine.AoqAudioCodecConfig codec = new AoqClientEngine.AoqAudioCodecConfig();
codec.trackType = AoqClientEngine.AoqTrackType.AoqTrackTypeAudio;
codec.codecType = AoqClientEngine.AoqEncoderType.AoqEncoderTypeAudioOpus;
codec.sampleRate = 16000;
codec.channel = 1;
codec.bitrate = 24000;
engine.setAudioEncoderConfig(codec);

AoqClientEngine.AoqTrackParam audio = new AoqClientEngine.AoqTrackParam();
audio.trackType = AoqClientEngine.AoqTrackType.AoqTrackTypeAudio;
connectConfig.publishTracks.add(audio);
AoqClientEngine.AoqTrackParam publishData = new AoqClientEngine.AoqTrackParam();
publishData.trackType = AoqClientEngine.AoqTrackType.AoqTrackTypeData;
connectConfig.publishTracks.add(publishData);
AoqClientEngine.AoqTrackParam subscribeData = new AoqClientEngine.AoqTrackParam();
subscribeData.trackType = AoqClientEngine.AoqTrackType.AoqTrackTypeData;
connectConfig.subscribeTracks.add(subscribeData);

AoqClientEngine.AoqAudioCaptureConfig capture = new AoqClientEngine.AoqAudioCaptureConfig();
capture.channel = 1;
capture.isExternal = false;
engine.startAudioCapture(capture);
engine.enableSendMediaStream(AoqClientEngine.AoqTrackType.AoqTrackTypeAudio, false);
engine.connect(connectConfig);
Wait for onConnectionStatusChange to return AoqConnectionStatusConnected before starting the task. In case of connection exceptions, clear the local task state; re-establishing the connection requires obtaining new connection credentials.

3. Start the recognition task and handle events

Serialize the following JSON into UTF-8, write it into AoqDataMsg.data, and then send it via the Data track using sendDataMsg. Each task generates a new task_id; all events in this round use the same value.
{
  "header": {
    "action": "run-task",
    "task_id": "0706c14c-dc16-4e45-8cb6-9d00686e8e19",
    "streaming": "duplex"
  },
  "payload": {
    "task_group": "audio",
    "task": "asr",
    "function": "recognition",
    "model": "qwen-audio-3.1-asr-flash-message",
    "parameters": {
      "format": "pcm",
      "sample_rate": 16000
    },
    "input": {}
  }
}
Read header.event from onDataMsg. Uplink audio is allowed only after receiving task-started.
engine.enableSendMediaStream(AoqClientEngine.AoqTrackType.AoqTrackTypeAudio, true);
Read the recognition text from payload.output.sentence in result-generated, skipping the heartbeat of heartbeat=true. By default, the final sentence text is returned. If intermediate_result_enabled=true is configured in run-task, editable intermediate text is also returned. Update the text for the same sentence according to sentence_id. Upon receiving task-failed, stop this round of uplink and read header.error_code and header.error_message. Task parameters and event fields are detailed in Client Events and Server Events.

4. End the Task and Release Resources

After recording ends, stop capturing new audio and wait for any pending audio to be sent. Call enableSendMediaStream to close the Audio track uplink, then send finish-task via the Data track. Keep the connection open to receive remaining recognition results and await task-finished.
{
  "header": {
    "action": "finish-task",
    "task_id": "0706c14c-dc16-4e45-8cb6-9d00686e8e19",
    "streaming": "duplex"
  },
  "payload": {
    "input": {}
  }
}
When the connection is no longer needed, call stopAudioCapture, disconnect, and AoqClientEngine.destroy in sequence to release resources.