From a27ed1d61a0745f517a32d8c0f1572122947117a Mon Sep 17 00:00:00 2001 From: gxz Date: Mon, 23 Oct 2023 18:14:37 +0800 Subject: [PATCH] feat: onNetworkQuality --- packages/fake/rtc/package.json | 2 +- packages/rtc/package.json | 2 +- packages/rtc/src/engine/IrisClientManager.ts | 28 +++++++++++++++++-- packages/rtc/src/engine/IrisRtcEngine.ts | 28 +++++++++++++++++-- .../event_handler/IrisClientEventHandler.ts | 17 +++++++++-- .../rtc/src/impl/IAgoraRtcEngineExImpl.ts | 8 +++++- packages/rtc/src/impl/IAgoraRtcEngineImpl.ts | 3 +- packages/rtc/src/state/IrisGlobalState.ts | 2 ++ .../rtc/test/impl/IAgoraRtcEngineImpl.test.ts | 7 ++++- 9 files changed, 85 insertions(+), 12 deletions(-) diff --git a/packages/fake/rtc/package.json b/packages/fake/rtc/package.json index 701a40b..f363ed4 100644 --- a/packages/fake/rtc/package.json +++ b/packages/fake/rtc/package.json @@ -1,6 +1,6 @@ { "name": "iris-web-rtc-fake", - "version": "0.1.2-dev.2", + "version": "0.1.2-dev.3", "description": "wait", "main": "./index.ts", "scripts": { diff --git a/packages/rtc/package.json b/packages/rtc/package.json index 1d2a01d..11e64e5 100644 --- a/packages/rtc/package.json +++ b/packages/rtc/package.json @@ -1,6 +1,6 @@ { "name": "iris-web-rtc", - "version": "0.1.2-dev.2", + "version": "0.1.2-dev.3", "description": "wait", "main": "./src/index.ts", "scripts": { diff --git a/packages/rtc/src/engine/IrisClientManager.ts b/packages/rtc/src/engine/IrisClientManager.ts index ef8f60c..08792b5 100644 --- a/packages/rtc/src/engine/IrisClientManager.ts +++ b/packages/rtc/src/engine/IrisClientManager.ts @@ -25,7 +25,7 @@ import { AgoraConsole } from '../util'; import { IrisClient } from './IrisClient'; import { IrisClientObserver } from './IrisClientObserver'; -import { IrisRtcEngine } from './IrisRtcEngine'; +import { IrisIntervalType, IrisRtcEngine } from './IrisRtcEngine'; export type WalkILocalVideoPackageTrackFun = (track: VideoTrackPackage) => void; @@ -330,9 +330,32 @@ export class IrisClientManager { })[0]; } - addRemoteUserPackage(remoteUserPackage: RemoteUserPackage) { + addRemoteUserPackage( + remoteUserPackage: RemoteUserPackage, + agoraRTCClient: IAgoraRTCClient + ) { this.remoteUserPackages.push(remoteUserPackage); this.irisClientObserver.addRemoteUserPackageObserver(remoteUserPackage); + if (agoraRTCClient) { + let intervalFunction = setInterval(() => { + let stats = agoraRTCClient.getRemoteNetworkQuality(); + let connection: NATIVE_RTC.RtcConnection = { + channelId: agoraRTCClient.channelName, + localUid: agoraRTCClient.uid as number, + }; + this._engine.rtcEngineEventHandler.onNetworkQualityEx( + connection, + remoteUserPackage.uid as number, + stats[remoteUserPackage.uid].downlinkNetworkQuality, + stats[remoteUserPackage.uid].uplinkNetworkQuality + ); + }, this._engine.globalState.networkQualityInterval); + this._engine.addIrisInterval( + IrisIntervalType.networkQuality, + intervalFunction, + remoteUserPackage.uid + ); + } } removeRemoteUserPackage(uid: UID) { @@ -342,6 +365,7 @@ export class IrisClientManager { this.remoteUserPackages.splice(i, 1); i--; this.irisClientObserver.removeRemoteUserPackageObserver(userPackage); + this._engine.removeIrisIntervalByUid(uid); userPackage.dispose(); break; diff --git a/packages/rtc/src/engine/IrisRtcEngine.ts b/packages/rtc/src/engine/IrisRtcEngine.ts index 421d61c..ed79628 100644 --- a/packages/rtc/src/engine/IrisRtcEngine.ts +++ b/packages/rtc/src/engine/IrisRtcEngine.ts @@ -52,6 +52,7 @@ import { IrisClientManager } from './IrisClientManager'; export enum IrisIntervalType { enableAudioVolumeIndication = 0, + networkQuality = 1, } export class IrisRtcEngine implements ApiInterceptor { @@ -71,6 +72,7 @@ export class IrisRtcEngine implements ApiInterceptor { public irisIntervalList: { type: IrisIntervalType; interval: NodeJS.Timeout; + uid: UID; }[] = []; public irisRtcErrorHandler: IrisRtcErrorHandler = new IrisRtcErrorHandler( this @@ -211,10 +213,16 @@ export class IrisRtcEngine implements ApiInterceptor { await this.irisClientManager.release(); } - public addIrisInterval(type: IrisIntervalType, interval: NodeJS.Timeout) { + public addIrisInterval( + type: IrisIntervalType, + interval: NodeJS.Timeout, + uid: UID + ) { + //如果添加的是远端用户的轮训,uid用远端的 this.irisIntervalList.push({ type, interval, + uid, }); } @@ -222,8 +230,24 @@ export class IrisRtcEngine implements ApiInterceptor { this.irisIntervalList.filter((a) => type == a.type); } + public removeIrisIntervalByUid(uid: UID) { + this.irisIntervalList.filter((a) => { + if (uid == a.uid) { + a.interval && clearInterval(a.interval); + } else { + return a; + } + }); + } + public removeIrisIntervalByType(type: IrisIntervalType) { - this.irisIntervalList.filter((a) => type != a.type); + this.irisIntervalList.filter((a) => { + if (type == a.type) { + a.interval && clearInterval(a.interval); + } else { + return a; + } + }); } public clearIrisInterval() { diff --git a/packages/rtc/src/event_handler/IrisClientEventHandler.ts b/packages/rtc/src/event_handler/IrisClientEventHandler.ts index 44090c8..b105471 100644 --- a/packages/rtc/src/event_handler/IrisClientEventHandler.ts +++ b/packages/rtc/src/event_handler/IrisClientEventHandler.ts @@ -197,7 +197,10 @@ export class IrisClientEventHandler { NATIVE_RTC.VIDEO_SOURCE_TYPE.VIDEO_SOURCE_REMOTE, IrisAudioSourceType.kAudioSourceTypeRemote ); - this._engine.irisClientManager.addRemoteUserPackage(userPackage); + this._engine.irisClientManager.addRemoteUserPackage( + userPackage, + this.agoraRTCClient + ); } else { userPackage.update({ uid: user.uid, @@ -444,8 +447,16 @@ export class IrisClientEventHandler { } onEventNetworkQuality(stats: NetworkQuality): void { - //不能对应 onNetworkQuality, 因为这里是得到自己的网络状况,而 onNetworkQuality 是别人的网络状况 - //暂时没有找到对应的回调 + let connection: NATIVE_RTC.RtcConnection = { + channelId: this.agoraRTCClient.channelName, + localUid: this.agoraRTCClient.uid as number, + }; + this._engine.rtcEngineEventHandler.onNetworkQualityEx( + connection, + 0, + stats.downlinkNetworkQuality, + stats.uplinkNetworkQuality + ); } //todo 后边再做 diff --git a/packages/rtc/src/impl/IAgoraRtcEngineExImpl.ts b/packages/rtc/src/impl/IAgoraRtcEngineExImpl.ts index 763ee23..528e746 100644 --- a/packages/rtc/src/impl/IAgoraRtcEngineExImpl.ts +++ b/packages/rtc/src/impl/IAgoraRtcEngineExImpl.ts @@ -172,7 +172,13 @@ export class IRtcEngineExImpl implements NATIVE_RTC.IRtcEngineEx { canvas.uid, NATIVE_RTC.VIDEO_SOURCE_TYPE.VIDEO_SOURCE_REMOTE ); - this._engine.irisClientManager.addRemoteUserPackage(userPackage); + let irisClient = this._engine.irisClientManager.getIrisClientByConnection( + connection + ); + this._engine.irisClientManager.addRemoteUserPackage( + userPackage, + irisClient?.agoraRTCClient + ); } return this._engine.returnResult(); diff --git a/packages/rtc/src/impl/IAgoraRtcEngineImpl.ts b/packages/rtc/src/impl/IAgoraRtcEngineImpl.ts index c92b4d4..13fe162 100644 --- a/packages/rtc/src/impl/IAgoraRtcEngineImpl.ts +++ b/packages/rtc/src/impl/IAgoraRtcEngineImpl.ts @@ -1063,7 +1063,8 @@ export class IRtcEngineImpl implements IRtcEngineExtensions { }, interval); this._engine.addIrisInterval( IrisIntervalType.enableAudioVolumeIndication, - intervalFunction + intervalFunction, + agoraRTCClient.uid ); } this._engine.globalState.enableAudioVolumeIndication = true; diff --git a/packages/rtc/src/state/IrisGlobalState.ts b/packages/rtc/src/state/IrisGlobalState.ts index b01e6e9..d8bf4ea 100644 --- a/packages/rtc/src/state/IrisGlobalState.ts +++ b/packages/rtc/src/state/IrisGlobalState.ts @@ -9,6 +9,8 @@ export interface DeviceInfo { export class IrisGlobalState { public rtcEngineContext: NATIVE_RTC.RtcEngineContext; + public networkQualityInterval: number = 2000; + //C++ SetAudioProfile() initialize() public audioProfile: NATIVE_RTC.AUDIO_PROFILE_TYPE; diff --git a/packages/rtc/test/impl/IAgoraRtcEngineImpl.test.ts b/packages/rtc/test/impl/IAgoraRtcEngineImpl.test.ts index 17e3d14..d5591cf 100644 --- a/packages/rtc/test/impl/IAgoraRtcEngineImpl.test.ts +++ b/packages/rtc/test/impl/IAgoraRtcEngineImpl.test.ts @@ -257,6 +257,7 @@ describe('IAgoraRtcEngineImpl', () => { test('joinChannel', async () => { jest.spyOn(rtcEngineImpl, 'joinChannel2'); + expect(irisRtcEngine.irisIntervalList.length == 0).toBeTruthy(); await joinChannel(apiEnginePtr, null); expect(rtcEngineImpl.joinChannel2).toBeCalledWith( @@ -265,6 +266,7 @@ describe('IAgoraRtcEngineImpl', () => { TEST_UID, irisRtcEngine.irisClientManager.getIrisClient().irisClientState ); + expect(irisRtcEngine.irisIntervalList.length == 1).toBeTruthy(); }); test('joinChannel', async () => { @@ -332,7 +334,8 @@ describe('IAgoraRtcEngineImpl', () => { expect( irisRtcEngine.globalState.enableAudioVolumeIndicationConfig.smooth ).toBe(param.smooth); - expect(irisRtcEngine.irisIntervalList.length == 1).toBeTruthy(); + //irisIntervalList是因为一个是远端的onnetworkquality 一个是enableAudioVolumeIndication的 + expect(irisRtcEngine.irisIntervalList.length == 2).toBeTruthy(); expect(irisRtcEngine.globalState.enableAudioVolumeIndication).toBeTruthy(); jest.advanceTimersByTime(param.interval); expect( @@ -342,9 +345,11 @@ describe('IAgoraRtcEngineImpl', () => { test('leaveChannel', async () => { await joinChannel(apiEnginePtr, null); + expect(irisRtcEngine.irisIntervalList.length == 1).toBeTruthy(); jest.spyOn(rtcEngineImpl, 'leaveChannel2'); await callIris(apiEnginePtr, 'RtcEngine_leaveChannel'); expect(rtcEngineImpl.leaveChannel2).toBeCalled(); + expect(irisRtcEngine.irisIntervalList.length == 0).toBeTruthy(); }); test('leaveChannel2', async () => {