Browse Source

fix(call): 解决通话与直播功能冲突问题

- 在CallController单例获取逻辑中添加GetX注册检查,确保实例正确获取
- 添加直播间状态检查,防止在直播间内发起或接听通话
- 修改通话状态为waitCalling,优化通话流程状态管理
- 在通话结束逻辑中添加异常处理,确保RTC频道正确清理
- 在RoomController中添加通话状态检查,防止通话期间开始直播或加入直播间
- 修复VideoCallPage挂断通话后页面重复退出问题
- 优化RTCManager中直播频道详情获取逻辑的缩进格式
master
Jolie 3 months ago
parent
commit
c55bd32478
4 changed files with 135 additions and 48 deletions
  1. 36
      lib/controller/discover/room_controller.dart
  2. 85
      lib/controller/message/call_controller.dart
  3. 4
      lib/pages/message/video_call_page.dart
  4. 58
      lib/rtc/rtc_manager.dart

36
lib/controller/discover/room_controller.dart

@ -22,6 +22,7 @@ import '../../pages/discover/live_end_page.dart';
import '../../pages/mine/real_name_page.dart';
import '../../pages/setting/match_spread_page.dart';
import '../../widget/live/live_recharge_popup.dart';
import '../message/call_controller.dart';
import 'svga_player_manager.dart';
//
@ -135,6 +136,27 @@ class RoomController extends GetxController with WidgetsBindingObserver {
if (isLive.value) {
return;
}
//
try {
// 使 Get.find 使 instance
CallController callController;
if (Get.isRegistered<CallController>()) {
callController = Get.find<CallController>();
} else {
callController = CallController.instance;
}
print('⚠️ [RoomController] 检查通话状态: currentCall=${callController.currentCall.value}, hashCode=${callController.hashCode}');
if (callController.currentCall.value != null) {
SmartDialog.showToast('请先结束通话');
print('⚠️ [RoomController] 当前正在通话中,无法开始直播');
return;
}
} catch (e) {
//
print('⚠️ [RoomController] 获取CallController失败(可能没有通话): $e');
}
final granted = await _ensureRtcPermissions();
if (!granted) return;
@ -161,6 +183,20 @@ class RoomController extends GetxController with WidgetsBindingObserver {
}
Future<void> joinChannel(String channelName) async {
//
try {
// 使 CallController.instance使
final callController = CallController.instance;
if (callController.currentCall.value != null) {
SmartDialog.showToast('请先结束通话');
print('⚠️ [RoomController] 当前正在通话中,无法加入直播间');
return;
}
} catch (e) {
//
print('⚠️ [RoomController] 检查通话状态失败: $e');
}
final response = await _networkService.rtcApi.getSwRtcToken(channelName);
final base = response.data;
if (base.isSuccess && base.data != null) {

85
lib/controller/message/call_controller.dart

@ -58,7 +58,16 @@ class CallSession {
class CallController extends GetxController {
static CallController? _instance;
static CallController get instance {
_instance ??= Get.put(CallController());
if (_instance != null) {
return _instance!;
}
// GetX 使 Get.find
if (Get.isRegistered<CallController>()) {
_instance = Get.find<CallController>();
return _instance!;
}
//
_instance = Get.put(CallController(), permanent: true);
return _instance!;
}
@ -178,6 +187,21 @@ class CallController extends GetxController {
return false;
}
//
try {
if (Get.isRegistered<RoomController>()) {
final roomController = Get.find<RoomController>();
if (roomController.isLive.value) {
SmartDialog.showToast('请先退出直播间');
print('⚠️ [CallController] 当前在直播间,无法发起通话');
return false;
}
}
} catch (e) {
//
print('⚠️ [CallController] 检查直播间状态失败: $e');
}
// UID和通话信息
remoteUid.value = null;
@ -202,7 +226,7 @@ class CallController extends GetxController {
final session = CallSession(
targetUserId: targetUserId,
callType: callType,
status: CallStatus.calling,
status: CallStatus.waitCalling,
isInitiator: true,
startTime: DateTime.now(),
);
@ -255,6 +279,21 @@ class CallController extends GetxController {
required EMMessage message,
ChatController? chatController,
}) async {
//
try {
if (Get.isRegistered<RoomController>()) {
final roomController = Get.find<RoomController>();
if (roomController.isLive.value) {
SmartDialog.showToast('请先退出直播间再接听');
print('⚠️ [CallController] 当前在直播间,无法接听通话');
return false;
}
}
} catch (e) {
//
print('⚠️ [CallController] 检查直播间状态失败: $e');
}
final callInfo = _parseCallInfo(message);
if (callInfo == null) {
return false;
@ -620,31 +659,43 @@ class CallController extends GetxController {
callDurationSeconds.value == 0 &&
_callChannelId != null &&
_callChannelId!.isNotEmpty) {
final response = await _networkService.rtcApi.cancelOneOnOneRtcChannel({
'channelId': _callChannelId!,
});
if (!response.data.isSuccess) {
SmartDialog.showToast(response.data.message);
return;
try {
final response = await _networkService.rtcApi.cancelOneOnOneRtcChannel({
'channelId': _callChannelId!,
});
if (response.data.isSuccess) {
print('✅ [CallController] 已调用取消一对一RTC频道接口,channelId: $_callChannelId');
} else {
print('⚠️ [CallController] 取消一对一RTC频道接口失败: ${response.data.message}');
}
} catch (e) {
print('⚠️ [CallController] 调用取消接口异常: $e');
}
print('✅ [CallController] 已调用取消一对一RTC频道接口,channelId: $_callChannelId');
} else if (callSession != null &&
callDurationSeconds.value > 0 &&
_callChannelId != null &&
_callChannelId!.isNotEmpty) {
//
final response = await _networkService.rtcApi.terminateOneOnOneRtcChannel(
{'channelId': _callChannelId!},
);
if (!response.data.isSuccess) {
SmartDialog.showToast(response.data.message);
return;
try {
final response = await _networkService.rtcApi.terminateOneOnOneRtcChannel(
{'channelId': _callChannelId!},
);
if (response.data.isSuccess) {
print('✅ [CallController] 已调用终止一对一RTC频道接口,channelId: $_callChannelId');
} else {
print('⚠️ [CallController] 终止一对一RTC频道接口失败: ${response.data.message}');
}
} catch (e) {
print('⚠️ [CallController] 调用终止接口异常: $e');
}
print('✅ [CallController] 已调用终止一对一RTC频道接口,channelId: $_callChannelId');
}
// RTC频道
await RTCManager.instance.leaveChannel();
try {
await RTCManager.instance.leaveChannel();
} catch (e) {
print('⚠️ [CallController] 离开RTC频道异常: $e');
}
// callStatus为'cancelled''terminated'onMessageContentChanged收到通知

4
lib/pages/message/video_call_page.dart

@ -234,8 +234,8 @@ class _VideoCallPageState extends State<VideoCallPage> {
///
void _hangUp() async {
await _callController.hangUpCall();
//
Get.back();
// hangUpCall() Get.back() 退 VideoCallPage
// Get.back()退MessagePage
}
@override

58
lib/rtc/rtc_manager.dart

@ -133,22 +133,22 @@ class RTCManager {
// RTC类型判断是否执行 RoomController
// RoomController
if (type == RTCType.live) {
// RoomController fetchRtcChannelDetail
final channelId = connection.channelId;
if (Get.isRegistered<RoomController>() &&
channelId != null &&
channelId.isNotEmpty) {
final roomController = Get.find<RoomController>();
await roomController.fetchRtcChannelDetail(channelId);
}
// RoomController fetchRtcChannelDetail
final channelId = connection.channelId;
if (Get.isRegistered<RoomController>() &&
channelId != null &&
channelId.isNotEmpty) {
final roomController = Get.find<RoomController>();
await roomController.fetchRtcChannelDetail(channelId);
}
if (connection.localUid == _currentUid) {
await RTMManager.instance.subscribe(_currentChannelId ?? '');
await RTMManager.instance.publishChannelMessage(
channelName: _currentChannelId ?? '',
message: json.encode({'type': 'join_room', 'uid': _currentUid}),
);
Get.to(() => const LiveRoomPage(id: 0));
if (connection.localUid == _currentUid) {
await RTMManager.instance.subscribe(_currentChannelId ?? '');
await RTMManager.instance.publishChannelMessage(
channelName: _currentChannelId ?? '',
message: json.encode({'type': 'join_room', 'uid': _currentUid}),
);
Get.to(() => const LiveRoomPage(id: 0));
}
}
if (onJoinChannelSuccess != null) {
@ -163,13 +163,13 @@ class RTCManager {
// RTC类型判断是否执行 RoomController
// RoomController
if (type == RTCType.live) {
// RoomController fetchRtcChannelDetail
final channelId = connection.channelId;
if (Get.isRegistered<RoomController>() &&
channelId != null &&
channelId.isNotEmpty) {
final roomController = Get.find<RoomController>();
await roomController.fetchRtcChannelDetail(channelId);
// RoomController fetchRtcChannelDetail
final channelId = connection.channelId;
if (Get.isRegistered<RoomController>() &&
channelId != null &&
channelId.isNotEmpty) {
final roomController = Get.find<RoomController>();
await roomController.fetchRtcChannelDetail(channelId);
}
} else if (type == RTCType.call) {
// CallController
@ -202,13 +202,13 @@ class RTCManager {
// RTC类型判断是否执行 RoomController
// RoomController
if (type == RTCType.live) {
// RoomController fetchRtcChannelDetail
final channelId = connection.channelId;
if (Get.isRegistered<RoomController>() &&
channelId != null &&
channelId.isNotEmpty) {
final roomController = Get.find<RoomController>();
await roomController.fetchRtcChannelDetail(channelId);
// RoomController fetchRtcChannelDetail
final channelId = connection.channelId;
if (Get.isRegistered<RoomController>() &&
channelId != null &&
channelId.isNotEmpty) {
final roomController = Get.find<RoomController>();
await roomController.fetchRtcChannelDetail(channelId);
}
}

Loading…
Cancel
Save