introduce

basic

Uniapp_arcall is a voice call, video call, and related call invitation function implemented through UNIApp. This section describes the scenario in which a user sends a call notification to the specified user and the other party accepts the call.

Basic call invitation process

Graph of TD A [he] -- > call | | B} {called received call A - > called answering | | received C [calling execute RTC] A - - > called refuse | | received G/relevant logic B - [called answer] -- > B > D E [called rejected] D - > answer | | notice calling A D - > F [called executive RTC] E - > | notice calling refused to | A - > B H [60 s no operation invited automatic failure]

Basic Call Process

Graph LR A [instance initialization RTC] -- > audio video | B | acquisition [join] room B - > | local collection in audio | C [published and rendering audio and video] - > | through callbacks for the remote audio and video | D/render the remote audio and video

Arcall concrete implementation

Demo source code address

Call invitation logic

Introduce the plug-in required for call invitation

// RTM real-time message import
const rtmModule = uni.requireNativePlugin('AR-RtmModule');
Copy the code

Call invitation initialization

Uniapp_arcall is logged into RTM when the project is launched, so it is written in onLaunch. The following error will occur during debugging

Error: [JS Framework] Failed to receiveTasks, instance (1) is not available.
Copy the code

The reason is that RTM instance initialization for many times will affect the use of RTM. Please kill the program before debugging

// Initialize the callback
await rtmModule.setCallBack(res= > {
			switch (res.rtmEvent) {
			// The connection status between SDK and RTM system has changed.
			case 'onConnectionStateChanged':
				break;
				A point-to-point message callback is received
			case 'onPeerMessageReceived':
			
				break;
				// The subscriber's online status changed
			case 'onPeersOnlineStatusChanged':
				
				break;
				Return to calling party: The called party has accepted the call invitation
			case 'onLocalInvitationAccepted':
				
				break;
				// Return to caller: the call invitation has been cancelled
			case 'onLocalInvitationCanceled':
				
				break;
				// Return to caller: call invitation process failed
			case 'onLocalInvitationFailure':
				
				break;
				Return to calling party: The called party has received the call invitation
			case 'onLocalInvitationReceivedByPeer':
				
				break;
				Return to calling party: the called party has rejected the call invitation
			case 'onLocalInvitationRefused':
			
				break;
				Return to the called party: The call invitation is accepted successfully
			case 'onRemoteInvitationAccepted':
			
				break;
				// Return to called party: the calling party has uninvited the call
			case 'onRemoteInvitationCanceled':
				
				break;
				Return to called: The call invitation process from the calling party failed
			case 'onRemoteInvitationFailure':
				
				break;
				// Return to called party: receive a call invitation
			case 'onRemoteInvitationReceived':
			
				break;
				Return to the called party: The call invitation rejection succeeds
			case 'onRemoteInvitationRefused':
				
				break;
			default:
				break; }})// Initialize the instance
await rtmModule.createInstance({
		"appId": "Your appid"
	}, res= > {
		console.log(res);
	})
// Log in to RTM
await rtmModule.login({
	"token": ""."userId": "Local User ID"
}, (res) = > {
	console.log("Log in to the RTM system", res);
})
// // Call invite using RTM (set listeners for invite call instances)
await rtmModule.setCallEventListener();
Copy the code

calling

  • Query whether a call user is online

    rtmModule.queryPeersOnlineStatus({
    			"peerIds": ["Call subscriber"]},(res) = > {
    			console.log(res);
    		})
    Copy the code
  • Call Initiates a call and subscribes when the user is online

    • Initiate a call to send a locally created channel room
    rtmModule.sendLocalInvitation({
    			"calleeId": calleeId, // The user ID of the caller
    			"content": JSON.stringify(info) // Invite content
    		}, (res) = > {
    			resolve(res.code);
    		})
    Copy the code
    • Subscribe (get online status) Unsubscribe when ending a call or invitation
    rtmModule.subscribePeersOnlineStatus({
    		"peerIds": ["The other uid"]},(res) = > {
    		//smething
    		console.log("Subscribe to specify the online status of one or more users", res);
    	})
    Copy the code
  • The calling party cancels the call

rtmModule.cancelLocalInvitation({
  		"calleeId": calleeId, // The user ID of the caller
  		"content": JSON.stringify(info) // Invite content
  	}, (res) = > {
  		console.log("Uninvite the caller.", res);
  	});
Copy the code

Was called

Through the callback onRemoteInvitationReceived received calling

  • Refused to call
rtmModule.refuseRemoteInvitation({
			"calleeId": userId,
			"response": JSON.stringify(info)/invite content},(res) = >{});Copy the code
  • Accept the call
rtmModule.acceptRemoteInvitation({
			"calleeId": calleeId, // Enable the called party to obtain the user ID of the calling party
			"response": info ? JSON.stringify(info) : "" // Invite response
		}, (res) = >{});// Subscribe to each other's online status.Copy the code

A prompt

The relevant prompts and logic can be manipulated through callbacks

Call correlation logic

The video component must be present on the NVUE page

<AR-CanvasView ref="location" style="flex: 1;" />
Copy the code

After receiving the received callback, the RTC logic can be accessed

  • The introduction of the plugin
const rtcModule = uni.requireNativePlugin('AR-RtcModule');
Copy the code
  • Initialize the
// Initialize the callback
await rtcModule.setCallBack(res= > {
		switch (res.engineEvent) {
			case "onConnectionLost":
				console.log("onConnectionLost", res);
				break;
				// The network connection status has changed
			case "onConnectionStateChanged":
				console.log("Network connection status changed callback", res);
				break;
				// A warning callback occurred
			case "onWarning":
				
				break;
				// An error callback occurred
			case "onError":
				
				break;
				// Join channel callback successfully
			case "onJoinChannelSuccess":
				// Local render
			
				break;
				// Remote user joins current channel callback
			case "onUserJoined":
			
				break;
				// Remote user leaving the current channel callback
			case "onUserOffline":
				console.log("Callback of remote user leaving current channel", res);
			
				break;
				// The network connection status has changed
			case "onConnectionStateChanged":
			
				break;
				// The first frame callback of the remote video is displayed
			case "onFirstRemoteVideoFrame":
				break;
			case "onFirstRemoteVideoDecoded":
			
				break;
				// The remote user's video status has changed callback (this callback may be inaccurate when the number of users in the channel exceeds 17)
			case "onRemoteVideoStateChanged":
			
				break;
				// // The local network type changes
				// case "onNetworkTypeChanged":
				// break;
				// // Network connection is down
				// case "onConnectionLost":
				// break;

				// // The remote audio status changes
				// case "onRemoteAudioStateChanged":
				// break;
				// // Local audio status change callback
				// case "onLocalAudioStateChanged":
				// break;
				// // The local video status changes
				// case "onLocalVideoStateChanged":
				// break;
				// // rejoin the channel callback
				// case "onRejoinChannelSuccess":
				// break;
				// // leave channel callback
				// case "onLeaveChannel":
				// break;
				// The first frame callback of local audio has been sent
				// case "onFirstLocalAudioFrame":
				// break;
				// // local video first frame callback is displayed
				// case "onFirstLocalVideoFrame":
				// break;
				// // Token service is about to expire
				// case "onTokenPrivilegeWillExpire":
				// break;
				// // Token expired callback
				// case "onRequestToken":
				// break;
				// // User role has been switched back (in live broadcast scenarios)
				// case "onClientRoleChanged":
				// break;
				// // Local or remote video size or rotation information change callback
				// case "onVideoSizeChanged":
				// break;
				// // Callback statistics of remote audio streams during a call
				// case "onRemoteAudioStats":
				// break;
				// // Callback of current call statistics. The callback is triggered every two seconds during the call
				// case "onRtcStats":
				// break;
				// // Callback of the last Mile quality report for the upstream and downstream networks of each user during a call
				// case "onNetworkQuality":
				// break;
				// // Local video stream statistics callback during a call
				// case "onLocalVideoStats":
				// break;
				// // Callback local audio stream statistics during a call
				// case "onLocalAudioStats":
				// break;
				// // Callback of remote video stream statistics during a call
				// case "onRemoteVideoStats":
				// break;}});// Initialize the instance
await rtcModule.create({
	"appId": 'your appid'
}, res= > {
	console.log('Initialize instance RTC', res);
});
// Enable intelligent noise reduction
await rtcModule.setParameters({
			Cmd: 'SetAudioAiNoise'.Enable: 1
		}, (res) = > {
			console.log('Personal Customization', res);
		});
Copy the code
  • If you collect audio and video, the following codes can not be executed
// Set the video encoding properties
await rtcModule.setVideoEncoderConfiguration({},res) => {
console.log('the RTC set video encoding attribute setVideoEncoderConfiguration method calls', res.code ===0 ? 'success' :'Failure:' + res);
});
// Enable video
await rtcModule.enableVideo((res) = > {
console.log('RTC enableVideo enableVideo method call ', res.code === 0 ? 'success' : 'Failure:' +res);
});
Copy the code
  • To join the room
rtcModule.joinChannel({
			"token": ' '."channelId": locally created channels/channels delivered by call invitation,"uid": local userid,},(res) = > {
			console.log('RTC joinChannel method call ', res.code === 0 ? 'success' : 'Failure:' + res);
		});
Copy the code
  • Local video rendering

    <AR-CanvasView ref="location" style="flex: 1;" />
    Copy the code

    Access to the container

    // Make sure the container is available
    Store.location = this.$refs.location;
    console.log(Store.location);
    // Print something like this
    {
    	"ref": "68"."type": "AR-CanvasView"."attr": {
    		"@styleScope": "data-v-39c12bd0"
    	},
    	"style": {
    		"flex": "1"}}Copy the code
     // Render the video
    	await Store.location.setupLocalVideo({
    		"renderMode": 1."channelId": Join the channel room"uid": Local userID"mirrorMode": 0
    	}, (res) = > {
    		console.log('Render video', res);
    	});
    	// Local preview
    	await Store.location.startPreview((res) = > {
    		console.log('Local Preview', res);
    	})
    Copy the code
  • The remote video rendering Through callback onFirstRemoteVideoDecoded access to remote users video Store. The remote and Store. The location is similar

    await Store.remote.setupRemoteVideo({
    		"renderMode": 1."channelId": Indicates the channel to join"uid": res.uid
    		"mirrorMode": 0
    	}, (res) = > {
    		console.log('Render remote video', res);
    	})
    	// Local preview
    	await Store.remote.startPreview((res) = > {
    		console.log('Remote Local Preview', res);
    	})
    Copy the code
  • Hang up

    	// Destroy the instance
    		rtcModule.destroyRtc((res) = > {
    			console.log("Destroy instance", res);
    		});
    Copy the code

conclusion

Current logic basic implementation call invite + call needs more detailed, more specific, more comprehensive code please go to demo source address

  • Matters needing attention
    • RTM initialization, RTC initialization only need to be executed once, multiple executions please kill the program
    • RTM can be on the VUE page, and THE RTC video container must be on the NVUE page