Compare commits

..

No commits in common. "d008eebe6465adddc8fcdee789b4248ae61518ae" and "44180f9924f4f472cba52d41940b613572ad6130" have entirely different histories.

4 changed files with 713 additions and 751 deletions

View File

@ -27,251 +27,11 @@ import 'meeting_main_state.dart';
class MeetingMainLogic extends GetxController with RequestToolMixin { class MeetingMainLogic extends GetxController with RequestToolMixin {
final MeetingMainState state = MeetingMainState(); final MeetingMainState state = MeetingMainState();
late RtcEngineEventHandler _rtcEngineEventHandler;
@override @override
void onInit() { void onInit() {
super.onInit(); super.onInit();
_rtcEngineEventHandler = RtcEngineEventHandler(
//
onError: (ErrorCodeType err, String msg){
debugPrint("wgs输出===RTC-错误回调:${err}---${msg}");
},
//
onJoinChannelSuccess: (RtcConnection connection, int elapsed) {
state.isJoinSuccess.value = true;
debugPrint("meeting流程====》3加入频道" );
debugPrint("wgs输出===RTC-自己加入会议室ID${connection.localUid}");
},
onRejoinChannelSuccess: (RtcConnection connection, int elapsed) {
state.isJoinSuccess.value = true;
debugPrint("meeting流程====》4加入频道" );
debugPrint("wgs输出===RTC-自己加入会议室ID${connection.localUid}");
},
//
onLeaveChannel: (RtcConnection connection, RtcStats stats) {
debugPrint("wgs输出===RTC-自己离开会议室ID${connection.localUid}");
},
// -
onUserJoined: (RtcConnection connection, int remoteUid, int elapsed) {
debugPrint("wgs输出===RTC-远端用户或主播加入会议室用户或主机的ID$remoteUid");
},
// -
onUserOffline: (RtcConnection connection, int remoteUid,
UserOfflineReasonType reason) async {
//
if (remoteUid.toString().length == 9) {
for (var i = 0; i < state.cacheUsers.value.length; i++) {
if (remoteUid.toString() ==
state.cacheUsers.value[i].screenShareId) {
state.cacheUsers.value[i].enableShare = false;
}
}
}
update();
debugPrint("wgs输出===RTC-远端用户或主播离开会议室用户或主机的ID$remoteUid");
},
//
onAudioRoutingChanged: (int routing) {
debugPrint("wgs输出===RTC-音频路由切换:$routing");
state.communicationMode.value = routing;
if (routing == 1) {
debugPrint("wgs输出===RTC-音频路由切换为听筒");
} else if (routing == 3) {
debugPrint("wgs输出===RTC-音频路由切换为扬声器");
} else {
debugPrint("wgs输出===RTC-音频路由切换为外接设备");
}
},
//
onLocalAudioStateChanged: (RtcConnection connection,
LocalAudioStreamState state, LocalAudioStreamReason reason) {
debugPrint("wgs输出===RTC-音频采集开关:$state");
},
//
onRemoteVideoStateChanged: (RtcConnection connection,
int remoteUid,
RemoteVideoState remoteVideoState,
RemoteVideoStateReason remoteVideoStateReason,
int elapsed) {
debugPrint(
"wgs输出===RTC-远端视频状态发生改变ID-$remoteUid-状态-$remoteVideoStateReason");
if (remoteVideoStateReason ==
RemoteVideoStateReason.remoteVideoStateReasonRemoteMuted) {
//
if (remoteUid.toString().length != 9) {
//
if (remoteUid.toString() == state.remoteUid.value) {
//
doHttpGetTvAnchor();
}
} else {
//
}
}
},
//
onAudioVolumeIndication: (RtcConnection connection,
List<AudioVolumeInfo> speakers,
int speakerNumber,
int totalVolume) {
if (speakers.isNotEmpty) {
for (AudioVolumeInfo avi in speakers) {
if (avi.uid == 0) {
// debugPrint("wgs输出===RTC-本地用户音量提示:${avi.uid}--${avi.volume}");
for (MeetingRoomUser mru in state.cacheUsers.value) {
if (UserStore.to.userInfoEntity.value!.uid == mru.uid) {
mru.volume = CountMicrophoneVolume.getVolume(avi.volume!);
state.microphoneVolume.value =
CountMicrophoneVolume.getVolume(avi.volume!);
}
}
} else {
// debugPrint("wgs输出===RTC-远端用户音量提示:${avi.uid}--${avi.volume}");
for (MeetingRoomUser mru in state.cacheUsers.value) {
mru.volume = CountMicrophoneVolume.getVolume(avi.volume!);
if (avi.volume != 0) {
state.spokesman.value = mru.userName;
state.spokesmanVolume.value =
CountMicrophoneVolume.getVolume(avi.volume!);
} else {
state.spokesman.value = "";
state.spokesmanVolume.value = 0;
}
}
}
/*for (MeetingRoomUser mru in state.cacheUsers.value) {
//
if (avi.uid == 0) {
// debugPrint("wgs输出===RTC-用户音量提示(自己):${CountMicrophoneVolume.getVolume(avi.volume!)}");
mru.volume = CountMicrophoneVolume.getVolume(avi.volume!);
state.microphoneVolume.value =
CountMicrophoneVolume.getVolume(avi.volume!);
} else {
debugPrint("wgs输出===RTC-用户音量提示:${avi.uid}--${mru.uid}");
if (avi.uid.toString() == mru.uid) {
debugPrint("wgs输出===RTC-用户音量提示(远端用户):${speakers[0].uid}--${speakers[0].volume}");
mru.volume = CountMicrophoneVolume.getVolume(avi.volume!);
if (avi.volume != 0) {
state.spokesman.value = mru.userName;
state.spokesmanVolume.value =
CountMicrophoneVolume.getVolume(avi.volume!);
} else {
state.spokesman.value = "";
state.spokesmanVolume.value = 0;
}
}
}
}*/
}
}
},
//
onClientRoleChanged: (RtcConnection connection,
ClientRoleType oldRole,
ClientRoleType newRole,
ClientRoleOptions newRoleOptions) {
debugPrint(
"wgs输出===RTC-切换用户角色为:${newRole == ClientRoleType.clientRoleBroadcaster ? "主播" : "观众"}");
},
// token即将在30秒内过期回调
onTokenPrivilegeWillExpire: (RtcConnection connection, String token) {
doHttpGetMeetingToken(false);
},
// token已过期
onRequestToken: (RtcConnection connection){
doHttpGetMeetingToken(false);
},
//
onLocalVideoStateChanged: (VideoSourceType source,
LocalVideoStreamState state, LocalVideoStreamReason reason) {
debugPrint("wgs输出===RTC-本地视频状态发生改变:$source--$state--$reason");
},
//
onConnectionStateChanged: (RtcConnection connection,
ConnectionStateType stateType,
ConnectionChangedReasonType reason) {
debugPrint("wgs输出===RTC-网络连接状态发生改变:"
"会议室编号(${connection.channelId}"
"网络状态($stateType-${AgoraUtil.getConnectionStateChangedType(stateType)}"
"网络改变原因($reason-${AgoraUtil.getConnectionChangedReasonType(reason)}");
if(reason == ConnectionChangedReasonType.connectionChangedTokenExpired){
// 使token已过期
doHttpGetMeetingToken(false);
}else{
if (stateType == ConnectionStateType.connectionStateReconnecting) {
if (EasyLoading.isShow == false) {
ToastUtils.showLoadingToMask(
"网络故障,正在重连...", EasyLoadingMaskType.black);
}
} else if (stateType ==
ConnectionStateType.connectionStateConnected &&
reason ==
ConnectionChangedReasonType
.connectionChangedRejoinSuccess) {
ToastUtils.dismiss();
if (EasyLoading.isShow == false) {
ToastUtils.showSuccessToMask(
"重连成功!", EasyLoadingMaskType.black);
}
} else if (reason ==
ConnectionChangedReasonType.connectionChangedLost) {
// 15signalR Socket一致SDK继续重连
Future.delayed(const Duration(milliseconds: 15000), () {
ToastUtils.dismiss();
if (state.isShowOkAlertDialog.value == false) {
showOkAlertDialog(
context: Get.context!,
title: "提示",
message: "网络错误,请重新加入会议室",
okLabel: "确定",
barrierDismissible: false,
).then((OkCancelResult value) {
Get.back();
Get.back();
});
}
});
}
}
},
//
onFirstRemoteVideoFrame: (RtcConnection connection, int remoteUid,
int width, int height, int elapsed) async {
debugPrint("wgs输出===RTC-渲染器已接收首帧远端视频回调:${remoteUid}--${width}--${height}--${elapsed}");
},
//
onFirstRemoteVideoDecoded: (RtcConnection connection, int remoteUid,
int width, int height, int elapsed) {
debugPrint("wgs输出===RTC-已接收到远端视频并完成解码回调:${remoteUid}--${width}--${height}--${elapsed}");
}
//
/*onPermissionError: (PermissionType permissionType){
debugPrint("wgs输出===RTC-获取设备权限出错:$permissionType");
if(permissionType == PermissionType.screenCapture){
//
state.isOpenShare.value = false;
stopScreenCapture();
}
}*/
);
// //
var data = Get.arguments; var data = Get.arguments;
state.roomNumber.value = data["roomNumber"]; state.roomNumber.value = data["roomNumber"];
@ -304,13 +64,10 @@ class MeetingMainLogic extends GetxController with RequestToolMixin {
await getClient().getMeetingToken(state.roomNumber.value); await getClient().getMeetingToken(state.roomNumber.value);
state.meetingToken.value = res.data!; state.meetingToken.value = res.data!;
debugPrint("meeting流程====》1获取token成功" );
if (isInit) { if (isInit) {
signalRSocket(); signalRSocket();
} else { } else {
renewToken(state.meetingToken.value); initRtc();
// initRtc();
} }
} }
@ -622,8 +379,6 @@ class MeetingMainLogic extends GetxController with RequestToolMixin {
await state.hubConnection.value?.start(); await state.hubConnection.value?.start();
debugPrint("meeting流程====》2socket链接成功" );
// //
state.hubConnection.value?.onreconnecting((error) { state.hubConnection.value?.onreconnecting((error) {
debugPrint("wgs输出===SignalR Socket-重连$error"); debugPrint("wgs输出===SignalR Socket-重连$error");
@ -1019,9 +774,7 @@ class MeetingMainLogic extends GetxController with RequestToolMixin {
/// SDK /// SDK
Future<void> initRtc() async { Future<void> initRtc() async {
// RtcEngine // RtcEngine
await leaveMeetingToRtc(); state.rctEngine.value = createAgoraRtcEngineEx();
state.rctEngine.value = createAgoraRtcEngine();
// RtcEngine channelProfileLiveBroadcasting // RtcEngine channelProfileLiveBroadcasting
await state.rctEngine.value?.initialize(RtcEngineContext( await state.rctEngine.value?.initialize(RtcEngineContext(
@ -1029,10 +782,8 @@ class MeetingMainLogic extends GetxController with RequestToolMixin {
channelProfile: ChannelProfileType.channelProfileLiveBroadcasting, channelProfile: ChannelProfileType.channelProfileLiveBroadcasting,
// logConfig:const LogConfig() // logConfig:const LogConfig()
)); ));
state.rctEngine.value?.registerEventHandler(_rtcEngineEventHandler);
// //
// //
await enableVideo(); await enableVideo();
// //
@ -1044,12 +795,232 @@ class MeetingMainLogic extends GetxController with RequestToolMixin {
await state.rctEngine.value await state.rctEngine.value
?.setDualStreamMode(mode: SimulcastStreamMode.enableSimulcastStream); ?.setDualStreamMode(mode: SimulcastStreamMode.enableSimulcastStream);
WidgetsBinding.instance.addPostFrameCallback((_)=>joinMeetingToRtc()); //
state.rctEngine.value?.registerEventHandler(
RtcEngineEventHandler(
//
onJoinChannelSuccess: (RtcConnection connection, int elapsed) {
state.isJoinSuccess.value = true;
debugPrint("wgs输出===RTC-自己加入会议室ID${connection.localUid}");
},
//
onLeaveChannel: (RtcConnection connection, RtcStats stats) {
debugPrint("wgs输出===RTC-自己离开会议室ID${connection.localUid}");
},
// -
onUserJoined: (RtcConnection connection, int remoteUid, int elapsed) {
debugPrint("wgs输出===RTC-远端用户或主播加入会议室用户或主机的ID$remoteUid");
},
// -
onUserOffline: (RtcConnection connection, int remoteUid,
UserOfflineReasonType reason) async {
//
if (remoteUid.toString().length == 9) {
for (var i = 0; i < state.cacheUsers.value.length; i++) {
if (remoteUid.toString() ==
state.cacheUsers.value[i].screenShareId) {
state.cacheUsers.value[i].enableShare = false;
}
}
}
update();
debugPrint("wgs输出===RTC-远端用户或主播离开会议室用户或主机的ID$remoteUid");
},
//
onAudioRoutingChanged: (int routing) {
debugPrint("wgs输出===RTC-音频路由切换:$routing");
state.communicationMode.value = routing;
if (routing == 1) {
debugPrint("wgs输出===RTC-音频路由切换为听筒");
} else if (routing == 3) {
debugPrint("wgs输出===RTC-音频路由切换为扬声器");
} else {
debugPrint("wgs输出===RTC-音频路由切换为外接设备");
}
},
//
onLocalAudioStateChanged: (RtcConnection connection,
LocalAudioStreamState state, LocalAudioStreamReason reason) {
debugPrint("wgs输出===RTC-音频采集开关:$state");
},
//
onRemoteVideoStateChanged: (RtcConnection connection,
int remoteUid,
RemoteVideoState remoteVideoState,
RemoteVideoStateReason remoteVideoStateReason,
int elapsed) {
debugPrint(
"wgs输出===RTC-远端视频状态发生改变ID-$remoteUid-状态-$remoteVideoStateReason");
if (remoteVideoStateReason ==
RemoteVideoStateReason.remoteVideoStateReasonRemoteMuted) {
//
if (remoteUid.toString().length != 9) {
//
if (remoteUid.toString() == state.remoteUid.value) {
//
doHttpGetTvAnchor();
}
} else {
//
}
}
},
//
onAudioVolumeIndication: (RtcConnection connection,
List<AudioVolumeInfo> speakers,
int speakerNumber,
int totalVolume) {
if (speakers.isNotEmpty) {
for (AudioVolumeInfo avi in speakers) {
if (avi.uid == 0) {
// debugPrint("wgs输出===RTC-本地用户音量提示:${avi.uid}--${avi.volume}");
for (MeetingRoomUser mru in state.cacheUsers.value) {
if (UserStore.to.userInfoEntity.value!.uid == mru.uid) {
mru.volume = CountMicrophoneVolume.getVolume(avi.volume!);
state.microphoneVolume.value =
CountMicrophoneVolume.getVolume(avi.volume!);
}
}
} else {
// debugPrint("wgs输出===RTC-远端用户音量提示:${avi.uid}--${avi.volume}");
for (MeetingRoomUser mru in state.cacheUsers.value) {
mru.volume = CountMicrophoneVolume.getVolume(avi.volume!);
if (avi.volume != 0) {
state.spokesman.value = mru.userName;
state.spokesmanVolume.value =
CountMicrophoneVolume.getVolume(avi.volume!);
} else {
state.spokesman.value = "";
state.spokesmanVolume.value = 0;
}
}
}
/*for (MeetingRoomUser mru in state.cacheUsers.value) {
//
if (avi.uid == 0) {
// debugPrint("wgs输出===RTC-用户音量提示(自己):${CountMicrophoneVolume.getVolume(avi.volume!)}");
mru.volume = CountMicrophoneVolume.getVolume(avi.volume!);
state.microphoneVolume.value =
CountMicrophoneVolume.getVolume(avi.volume!);
} else {
debugPrint("wgs输出===RTC-用户音量提示:${avi.uid}--${mru.uid}");
if (avi.uid.toString() == mru.uid) {
debugPrint("wgs输出===RTC-用户音量提示(远端用户):${speakers[0].uid}--${speakers[0].volume}");
mru.volume = CountMicrophoneVolume.getVolume(avi.volume!);
if (avi.volume != 0) {
state.spokesman.value = mru.userName;
state.spokesmanVolume.value =
CountMicrophoneVolume.getVolume(avi.volume!);
} else {
state.spokesman.value = "";
state.spokesmanVolume.value = 0;
}
}
}
}*/
}
}
},
//
onClientRoleChanged: (RtcConnection connection,
ClientRoleType oldRole,
ClientRoleType newRole,
ClientRoleOptions newRoleOptions) {
debugPrint(
"wgs输出===RTC-切换用户角色为:${newRole == ClientRoleType.clientRoleBroadcaster ? "主播" : "观众"}");
},
// token即将在30秒内过期回调
onTokenPrivilegeWillExpire: (RtcConnection connection, String token) {
doHttpGetMeetingToken(false);
},
//
onLocalVideoStateChanged: (VideoSourceType source,
LocalVideoStreamState state, LocalVideoStreamReason reason) {
debugPrint("wgs输出===RTC-本地视频状态发生改变:$source--$state--$reason");
},
//
onConnectionStateChanged: (RtcConnection connection,
ConnectionStateType stateType,
ConnectionChangedReasonType reason) {
debugPrint("wgs输出===RTC-网络连接状态发生改变:"
"会议室编号(${connection.channelId}"
"网络状态($stateType-${AgoraUtil.getConnectionStateChangedType(stateType)}"
"网络改变原因($reason-${AgoraUtil.getConnectionChangedReasonType(reason)}");
if (stateType == ConnectionStateType.connectionStateReconnecting) {
if (EasyLoading.isShow == false) {
ToastUtils.showLoadingToMask(
"网络故障,正在重连...", EasyLoadingMaskType.black);
}
} else if (stateType ==
ConnectionStateType.connectionStateConnected &&
reason ==
ConnectionChangedReasonType
.connectionChangedRejoinSuccess) {
ToastUtils.dismiss();
if (EasyLoading.isShow == false) {
ToastUtils.showSuccessToMask(
"重连成功!", EasyLoadingMaskType.black);
}
} else if (reason ==
ConnectionChangedReasonType.connectionChangedLost) {
// 15signalR Socket一致SDK继续重连
Future.delayed(const Duration(milliseconds: 15000), () {
ToastUtils.dismiss();
if (state.isShowOkAlertDialog.value == false) {
showOkAlertDialog(
context: Get.context!,
title: "提示",
message: "网络错误,请重新加入会议室",
okLabel: "确定",
barrierDismissible: false,
).then((OkCancelResult value) {
Get.back();
Get.back();
});
}
});
}
},
//
onFirstRemoteVideoFrame: (RtcConnection connection, int remoteUid,
int width, int height, int elapsed) async {
debugPrint("wgs输出===RTC-渲染器已接收首帧远端视频回调:${remoteUid}--${width}--${height}--${elapsed}");
// await joinMeetingToRtc(); },
//
onFirstRemoteVideoDecoded: (RtcConnection connection, int remoteUid,
int width, int height, int elapsed) {
debugPrint("wgs输出===RTC-已接收到远端视频并完成解码回调:${remoteUid}--${width}--${height}--${elapsed}");
}
//
/*onPermissionError: (PermissionType permissionType){
debugPrint("wgs输出===RTC-获取设备权限出错:$permissionType");
if(permissionType == PermissionType.screenCapture){
//
state.isOpenShare.value = false;
stopScreenCapture();
}
}*/
),
);
await joinMeetingToRtc();
} }
/// ///
@ -1077,7 +1048,6 @@ class MeetingMainLogic extends GetxController with RequestToolMixin {
/// ///
Future<void> leaveMeetingToRtc() async { Future<void> leaveMeetingToRtc() async {
state.rctEngine.value?.unregisterEventHandler(_rtcEngineEventHandler);
// //
await state.rctEngine.value?.leaveChannel(); await state.rctEngine.value?.leaveChannel();
// //
@ -1131,9 +1101,4 @@ class MeetingMainLogic extends GetxController with RequestToolMixin {
Future<void> switchCamera() async { Future<void> switchCamera() async {
await state.rctEngine.value?.switchCamera(); await state.rctEngine.value?.switchCamera();
} }
/// Token
Future<void> renewToken(String token) async {
await state.rctEngine.value?.renewToken(token);
}
} }

View File

@ -101,7 +101,7 @@ class MeetingMainState {
/// ///
final String appId = "4a4f7be64fa1404ebda74784fe9ac381"; final String appId = "4a4f7be64fa1404ebda74784fe9ac381";
Rx<RtcEngine?> rctEngine = Rx<RtcEngine?>(null); Rx<RtcEngineEx?> rctEngine = Rx<RtcEngineEx?>(null);
/// ///
late RxBool isAutoSubscribeVideo = false.obs; late RxBool isAutoSubscribeVideo = false.obs;
/// ///

View File

@ -68,9 +68,7 @@ class MeetingMainPageState extends State<MeetingMainPage> {
), ),
backgroundColor: ColorUtil.Color_41_41_41, backgroundColor: ColorUtil.Color_41_41_41,
), ),
body: Obx((){ body: Obx(() => Stack(
return Stack(
children: [ children: [
Column( Column(
children: [ children: [
@ -306,7 +304,7 @@ class MeetingMainPageState extends State<MeetingMainPage> {
], ],
) )
: Container( : Container(
color: ColorUtil.Color_0_0_0_0, color: Colors.red,
/*child: Text('加载反馈:是否成功加入会议室${state.isJoinSuccess.value}-会议室对象${state.rctEngine.value}-成员列表${state.users.value.length}-全员观看ID${state.remoteUid.value}'),*/ /*child: Text('加载反馈:是否成功加入会议室${state.isJoinSuccess.value}-会议室对象${state.rctEngine.value}-成员列表${state.users.value.length}-全员观看ID${state.remoteUid.value}'),*/
)), )),
@ -632,8 +630,7 @@ class MeetingMainPageState extends State<MeetingMainPage> {
meetingInfoFloatingLayer(), meetingInfoFloatingLayer(),
meetingAudioFloatingLayer(), meetingAudioFloatingLayer(),
], ],
); ))),
}),),
)); ));
} }

View File

@ -96,7 +96,7 @@ class UserPageState extends State<UserPage> {
), ),
Container( Container(
padding: const EdgeInsets.only(left: 16, right: 16), padding: const EdgeInsets.only(left: 16, right: 16),
margin: const EdgeInsets.only(top: 30), margin: const EdgeInsets.only(top: 20),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [