yumi-flutter/test/trtc_room_rtc_engine_adapter_test.dart
2026-05-15 21:20:29 +08:00

251 lines
6.6 KiB
Dart

import 'package:flutter_test/flutter_test.dart';
import 'package:tencent_rtc_sdk/trtc_cloud_def.dart';
import 'package:tencent_rtc_sdk/trtc_cloud_listener.dart';
import 'package:tencent_rtc_sdk/tx_audio_effect_manager.dart';
import 'package:yumi/services/audio/room_rtc_engine_adapter.dart';
import 'package:yumi/services/audio/room_rtc_types.dart';
import 'package:yumi/services/audio/trtc_room_rtc_engine_adapter.dart';
void main() {
test('enters TRTC voice room with strRoomId and business userId', () async {
final cloud = _FakeTrtcCloud();
final adapter = TrtcRoomRtcEngineAdapter(cloudFactory: () async => cloud);
await adapter.enterRoomAsAudience(
const RoomRtcEnterRoomConfig(
identity: RoomRtcSessionIdentity(
businessRoomId: 'business-room',
trtcStrRoomId: 'room-account',
trtcUserId: 'user-id',
),
trtcSdkAppId: 20036101,
trtcUserSig: 'sig',
throwOnError: true,
),
);
expect(cloud.enteredParams?.sdkAppId, 20036101);
expect(cloud.enteredParams?.roomId, 0);
expect(cloud.enteredParams?.strRoomId, 'room-account');
expect(cloud.enteredParams?.userId, 'user-id');
expect(cloud.enteredParams?.userSig, 'sig');
expect(cloud.enteredParams?.role, TRTCRoleType.audience);
expect(cloud.enteredScene, TRTCAppScene.voiceChatRoom);
expect(cloud.autoRecvAudio, isTrue);
expect(cloud.autoRecvVideo, isFalse);
expect(cloud.volumeEvaluationEnabled, isTrue);
});
test('switches between anchor and audience with local audio state', () async {
final cloud = _FakeTrtcCloud();
final adapter = TrtcRoomRtcEngineAdapter(cloudFactory: () async => cloud);
await _enter(adapter);
expect(
await adapter.switchToAnchor(const RoomRtcAnchorConfig(muted: true)),
isTrue,
);
expect(cloud.lastRole, TRTCRoleType.anchor);
expect(cloud.localAudioStarted, isTrue);
expect(cloud.localAudioMuted, isTrue);
expect(await adapter.switchToAudience(), isTrue);
expect(cloud.lastRole, TRTCRoleType.audience);
expect(cloud.localAudioStopped, isTrue);
expect(cloud.localAudioMuted, isTrue);
});
test('maps TRTC music calls to AudioEffectManager', () async {
final cloud = _FakeTrtcCloud();
final adapter = TrtcRoomRtcEngineAdapter(cloudFactory: () async => cloud);
final states = <RoomRtcAudioMixingState>[];
final musicAdapter = TrtcRoomRtcEngineAdapter(
cloudFactory: () async => cloud,
onAudioMixingStateChanged: (state, _) => states.add(state),
);
await _enter(adapter);
await _enter(musicAdapter);
await musicAdapter.startAudioMixing(
const RoomRtcAudioMixingConfig(
filePath: '/tmp/a.mp3',
loopback: false,
cycle: 3,
startPos: 1200,
),
);
final musicParam = cloud.audioEffectManager.startedMusicParam!;
expect(musicParam.id, 1);
expect(musicParam.path, '/tmp/a.mp3');
expect(musicParam.publish, isTrue);
expect(musicParam.loopCount, 2);
expect(musicParam.startTimeMS, 1200);
expect(states, contains(RoomRtcAudioMixingState.playing));
await musicAdapter.pauseAudioMixing();
await musicAdapter.resumeAudioMixing();
await musicAdapter.setAudioMixingVolume(80);
expect(cloud.audioEffectManager.pausedIds, contains(1));
expect(cloud.audioEffectManager.resumedIds, contains(1));
expect(cloud.audioEffectManager.playoutVolume, 80);
expect(cloud.audioEffectManager.publishVolume, 80);
});
}
Future<void> _enter(TrtcRoomRtcEngineAdapter adapter) {
return adapter.enterRoomAsAudience(
const RoomRtcEnterRoomConfig(
identity: RoomRtcSessionIdentity(
businessRoomId: 'business-room',
trtcStrRoomId: 'room-account',
trtcUserId: 'user-id',
),
trtcSdkAppId: 20036101,
trtcUserSig: 'sig',
throwOnError: true,
),
);
}
class _FakeTrtcCloud implements RoomTrtcCloud {
final _FakeAudioEffectManager audioEffectManager = _FakeAudioEffectManager();
TRTCCloudListener? listener;
TRTCParams? enteredParams;
TRTCAppScene? enteredScene;
TRTCRoleType? lastRole;
bool? autoRecvAudio;
bool? autoRecvVideo;
bool volumeEvaluationEnabled = false;
bool localAudioStarted = false;
bool localAudioStopped = false;
bool localAudioMuted = false;
@override
void registerListener(TRTCCloudListener listener) {
this.listener = listener;
}
@override
void unRegisterListener(TRTCCloudListener listener) {
if (this.listener == listener) {
this.listener = null;
}
}
@override
void setDefaultStreamRecvMode(bool autoRecvAudio, bool autoRecvVideo) {
this.autoRecvAudio = autoRecvAudio;
this.autoRecvVideo = autoRecvVideo;
}
@override
void enableAudioVolumeEvaluation(
bool enable,
TRTCAudioVolumeEvaluateParams params,
) {
volumeEvaluationEnabled = enable;
}
@override
void enterRoom(TRTCParams param, TRTCAppScene scene) {
enteredParams = param;
enteredScene = scene;
listener?.onEnterRoom?.call(10);
}
@override
void exitRoom() {
listener?.onExitRoom?.call(0);
}
@override
void switchRole(TRTCRoleType role) {
lastRole = role;
}
@override
void startLocalAudio(TRTCAudioQuality quality) {
localAudioStarted = true;
}
@override
void stopLocalAudio() {
localAudioStopped = true;
}
@override
void muteLocalAudio(bool mute) {
localAudioMuted = mute;
}
@override
void muteAllRemoteAudio(bool mute) {}
@override
RoomTrtcAudioEffectManager getAudioEffectManager() {
return audioEffectManager;
}
}
class _FakeAudioEffectManager implements RoomTrtcAudioEffectManager {
TXMusicPlayObserver? observer;
AudioMusicParam? startedMusicParam;
final pausedIds = <int>[];
final resumedIds = <int>[];
int? playoutVolume;
int? publishVolume;
int position = 0;
@override
void setMusicObserver(int musicId, TXMusicPlayObserver? observer) {
this.observer = observer;
}
@override
void startPlayMusic(AudioMusicParam musicParam) {
startedMusicParam = musicParam;
observer?.onStart(musicParam.id, 0);
}
@override
void stopPlayMusic(int id) {}
@override
void pausePlayMusic(int id) {
pausedIds.add(id);
}
@override
void resumePlayMusic(int id) {
resumedIds.add(id);
}
@override
void setMusicPublishVolume(int id, int volume) {
publishVolume = volume;
}
@override
void setMusicPlayoutVolume(int id, int volume) {
playoutVolume = volume;
}
@override
int getMusicCurrentPosInMS(int id) {
return position;
}
@override
int getMusicDurationInMS(String path) {
return 3000;
}
@override
void seekMusicToPosInTime(int id, int pts) {
position = pts;
}
}