RTC with uni-app and uni-app x
UniApp uses the matching uni_modules/akstream-rtc plugin. Android and iOS apps bridge to native SDKs through UTS; Web reuses the Web SDK; the mini-program target uses its platform adapter. Your page consumes events and arranges views, without implementing SDP, WebSocket recovery, or native media threads.
sequenceDiagram
participant Page as UniApp page
participant Bridge as UTS bridge
participant SDK as Native or Web SDK
Page->>Bridge: roomAction + requestId
Bridge-->>Page: accepted: command received
Bridge->>SDK: Perform room action
SDK-->>Page: roomActionResult: actual result
Prepare the target runtime
- Copy UTS source, Android AAR, iOS XCFrameworks, Web/mini-program core, and offline whiteboard resources from the same SDK delivery. Keep the directory structure.
- Use your own DCloud AppID, bundle ID, signing, and business HTTPS endpoint. Lab identities and test CAs do not belong in a production package.
- Build a custom base or full install package after native dependencies change. A page hot update cannot replace an AAR or Framework. A standard base reporting the plugin unavailable is not proof that the SDK itself is broken.
- Compile Android and iOS separately and inspect the whole log. HBuilderX's final “compile succeeded” message does not erase an earlier UTS or Swift error.
Native video in classic uni-app uses nvue; uni-app x uses uvue. Web uses its Web rendering path. Bind each remote view to a real publicationId; camera and screen share are distinct publications. An accepted event means the bridge received a command, not that admission, media, or recording completed. Wait for the final event or query.
Create a handle and subscribe before joining. Here serverUrl/roomId/accessTicket came from your backend; the page includes the matching plugin:
import { createRtcClient, invokeRtcClient, disposeRtcClient } from '@/uni_modules/akstream-rtc'
const rtcId = createRtcClient({
serverUrl,
onEvent(event) {
const detail = JSON.parse(event.payloadJson || 'null')
console.log('RTC event', event.type, detail)
}
})
invokeRtcClient(rtcId, 'join', JSON.stringify({
roomId, accessTicket, microphone: false, camera: false
}), result => {
if (!result.accepted) console.error(result.message)
})
// On final page disposal: disposeRtcClient(rtcId)
result.accepted is not a completed join. Wait for the join event, and show Waiting rather than publishing when the room requires admission. Ask your backend for a new one-use ticket after leaving; do not replay an old ticket.
Put media on the page
Use the plugin view for local and remote native video. Key a remote card by its real publicationId; remove only that card when the SDK reports its publication gone:
<akstream-rtc :clientId="rtcId" :localPreview="true" />
<akstream-rtc :clientId="rtcId" :publicationId="remotePublicationId" />
Classic uni-app native video pages use nvue; uni-app x uses uvue. The Web target follows the Web SDK DOM/media path. Two cameras and one screen share make three separate media views. Audio is managed by the SDK; do not create a duplicate audio player for every video card.
Use getRtcFeatures(id) to distinguish supported, unsupported, configurationRequired, and notImplemented. Configuration may mean an iOS ReplayKit extension is missing. A host-muted microphone is not a missing device; show the actual restriction instead of claiming the platform cannot capture audio.
The the matching version AkRtcUniClient exposes startContinuousRecording(), stopContinuousRecording(recordingId), and getContinuousRecording(). Native recordingState reports current status. The host builds recording/replay UI. roomAction waits for the real requestId result, not just a bridge ACK. Archives use createUniArchiveClient or matching native UTS after backend-issued short-lived access. See UniApp methods for the full facade and state contract.
Use leave to exit a meeting and disposeRtcClient when the page/module is gone. Compilation and native bridge tests do not replace a full custom-base run on both physical platforms. See the acceptance checklist.
For acceptance, record the complete HBuilderX UTS logs, matching AAR/XCFramework versions in the custom base, actual Android/iOS package identities, and video/audio received by each other device. If a standard base reports the native plugin unavailable, rebuild the custom base first. If an iOS build installs but cannot launch, resolve developer trust and provisioning before debugging RTC. After a recording command ACK, wait for the matching roomActionResult and verify another client saw recordingState; a changed button color is not proof that files were written.