Use qwen3.5-omni-plus-realtime model via AOQ protocol for real-time calls
Describes how to integrate the AOQ Client SDK on Android, iOS, and HarmonyOS to implement audio/video calls using AOQ and qwen3.5-omni-plus-realtime.
For the AOQ Client SDK and the Opus audio plug-in, see SDK download. The Opus codec is provided as a separate plug-in. Include it as needed for your use case.
Copy the core SDK files to your project's dependency directory and declare the required permissions in your project configuration.
Place
Declare permissions in
Follow the AOQ section in Token authentication to set up an AppServer that obtains tokens. Before each call, the client must request a token from your AppServer.
Call the Implement the
Call
Have your AppServer proxy the request to QwenCloud. See Token authentication.
Set codec parameters and call
In the
In the
After muting, the SDK continues to capture audio but sends only silent frames. The
The server pushes ASR results and AI text responses through downstream data messages. In your app, route them by the
Download sample source code:
iOS: aoqdemo.zip
Get the SDK
For the AOQ Client SDK and the Opus audio plug-in, see SDK download. The Opus codec is provided as a separate plug-in. Include it as needed for your use case.
Import the SDK
Copy the core SDK files to your project's dependency directory and declare the required permissions in your project configuration.
Android
Place AoqClientSdk-release.aar in your project's app/libs/ directory. Place libPluginOpus.so by ABI into app/libs/armeabi-v7a/ and app/libs/arm64-v8a/. In app/build.gradle:
AndroidManifest.xml:
RECORD_AUDIO and CAMERA are runtime permissions. Your app must call Android's ActivityCompat.requestPermissions() at runtime to request user authorization.
iOS (framework)
-
Drag
AoqClientSdk.frameworkandPluginOpus.frameworkinto your Xcode project. Under Target > General > Frameworks, Libraries, and Embedded Content, select Embed & Sign. -
Declare permissions: in Xcode, select your Target > Info > Custom iOS Target Properties, and add the following two permission usage descriptions:
Key Value NSMicrophoneUsageDescriptionFor real-time voice calls NSCameraUsageDescriptionFor real-time video calls -
Swift project:
import AoqClientSdk. Objective-C project:#import <AoqClientSdk/AoqClientSdk.h>.
HarmonyOS (har)
-
Place
aoq-client-sdk.harin your project'slibs/directory. PlacelibPluginOpus.soby ABI intoentry/libs/armeabi-v7a/andentry/libs/arm64-v8a/. Declare the dependency inentry/oh-package.json5. -
Add permissions in
entry/src/main/module.json5:
- In
EntryAbility, trigger runtime authorization viaabilityAccessCtrl.createAtManager().requestPermissionsFromUser.
Get a token from the AppServer
Follow the AOQ section in Token authentication to set up an AppServer that obtains tokens. Before each call, the client must request a token from your AppServer.
Implement AI audio/video calls
Create engine and set callbacks
Call the createEngine API to create an AoqClientEngine instance.
- iOS
- Android
- HarmonyOS
AoqEngineDelegate protocol to listen for onConnectionStatusChange, onDataMsg, onError, and other callbacks.Start audio/video capture and playback
Call startAudioCapture and startAudioPlayer to start local audio capture and playback. Call startVideoCapture to start the camera, and use setLocalView to bind the SDK's render target to your preview control.
- iOS
- Android
- HarmonyOS
Get connection credentials
Have your AppServer proxy the request to QwenCloud. See Token authentication.
Configure codecs and establish connection
Set codec parameters and call connect.
Note: qwen3.5-omni-plus-realtime requires the client to start sending media data only after receiving session.updated from the server. To avoid accidentally sending media during the window between a successful connect and the arrival of session.updated, call enableSendMediaStream(trackType, false) for each upstream track before calling connect. For WebSocket event details, see Client events.
- iOS
- Android
- HarmonyOS
The AOQ SDK starts sending media data by default after connecting. This example demonstrates how to disable media sending when connecting to a model.
Configure AI session
In the onConnectionStatusChange(Connected) callback, send a session.update message via sendDataMsg. This message contains session parameters such as modalities, voice, instructions, and turn_detection, completing the session handshake. For WebSocket event details, see Client events.
- iOS
- Android
- HarmonyOS
Enable media sending after receiving session.updated
In the onDataMsg callback, parse incoming messages. When session.updated is received from the model, call enableSendMediaStream(trackType, true) for each track type that was disabled earlier. For WebSocket event details, see Server events.
- iOS
- Android
- HarmonyOS
- Start sending media streams only after receiving
session.updated. The AI may not be ready to receive data before this event. - The audio and video tracks added during connection (AOQ media channels) automatically deliver data to the server.
- Audio: transmitted directly through the audio track -- no need to send
input_audio_buffer.appendevents. - Video: frames are sent through the video track -- no need to send
input_image_buffer.appendevents.
- Audio: transmitted directly through the audio track -- no need to send
Disconnect and destroy engine
Common scenarios
Barge-in
- The SDK is deeply integrated with QwenCloud. Barge-in messages from the model interrupt the previous turn when a new turn begins.
- The SDK provides the
interruptAudioPlayerinterface for local playback interruption. Call this API when the user wants to stop playback.
Mute / unmute
After muting, the SDK continues to capture audio but sends only silent frames. The session is not interrupted.
Switch between front and rear cameras
Call subtitles and ASR results
The server pushes ASR results and AI text responses through downstream data messages. In your app, route them by the type field in the onDataMsg callback. For WebSocket event details, see Server events.
Important notes
-
Singleton semantics:
createEngineis a singleton -- repeated calls return the same instance. The engine can only be recreated afterdestroyis called. For multi-page use, manage the engine lifecycle at the Application or Ability level. -
Local preview view types:
- Android:
SurfaceVieworTextureView. Other types are not supported. - iOS: Any
UIViewsubclass. - HarmonyOS: See the SDK documentation.
- Android:
-
Audio route changes: Events such as headphone insertion/removal or Bluetooth connection trigger
onAudioDeviceRouteChanged. No handling is usually required in your app. If your UI includes a speaker/earpiece toggle, sync the state based on this callback. -
Background audio continuation: For audio to continue when the call moves to the background,
Info.plistmust haveUIBackgroundModes = audioenabled andAVAudioSessionmust be correctly activated in the foreground. The SDK handles most cases; usesetAudioSessionRestriction:for fine-grained control.
Download the demo

Related documents
- Detailed AOQ Client SDK API: AOQ SDK overview
- qwen3.5-omni-plus-realtime model client events: Client events
- qwen3.5-omni-plus-realtime model server events: Server events