closeCamera method
Implementation
Future<void> closeCamera(String from, {bool needUIDisabled = true, bool needToast = true}) async {
// 不再用 `if (!isCameraAvailable.value) return;` 早退。
// 历史问题:trtcError(如 1316/1117 等占用类错误)会把 isCameraAvailable
// 拉到 false,且只有 _onCameraDidReady 才会拉回 true。占用场景下相机
// 起不来 → 此标志永远卡 false → closeCamera 静默 return → 用户怎么点
// 关闭按钮都"没反应"。改为:始终执行 muteLocalVideo(true) 兜底,让
// SDK 内部状态与业务状态收敛;用户主动 close 成功后把 isCameraAvailable
// 重置回 true,便于下次 open 走正常路径。
if (needUIDisabled) {
_trtcStreamInfoObs.updateSelfCameraDeviceDisabled(true);
}
try {
await TRTC.closeCamera(from);
final isCameraAvailable = _trtcStreamInfoObs.isCameraAvailable.value;
var res = await networkService.selfStatusReport(StateReportBody(classId: _config.classId, state: isCameraAvailable ? StateStatusValueEnum.off : StateStatusValueEnum.fail, type: StateTypeEnum.camera));
if (res?.errorCode == 0) {
_membersInfoObs.updateSelfMemberInfoByAction(MemberActionType.cameraClose, isCameraAvailable ? StateStatusValueEnum.off : StateStatusValueEnum.fail);
_trtcStreamInfoObs.updateTRTCStreamInfo(TRTCRoomInfo.fromJson({"userId": _config.userId, "userVideoAvailable": false}), TRTCStreamInfoUpdateType.userVideoAvailableChanged);
// 用户主动关闭成功 → 恢复 isCameraAvailable,让下次 openCamera
// 不会被遗留的 false 状态误导。
if (!isCameraAvailable) {
_trtcStreamInfoObs.updateIsCameraAvailable(true);
}
TCICLog.info("关闭摄像头成功", actionModule: ActionModule.tcicController.name, actionName: ActionName.closeCamera.name);
if (needToast) {
TCICToast.show(StringEnum.closeCameraSuccess);
}
} else {
TCICLog.error("关闭摄像头失败", actionModule: ActionModule.tcicController.name, actionName: ActionName.closeCamera.name);
if (needToast) {
TCICToast.show(StringEnum.closeCameraFailed);
}
}
} catch (e) {
TCICLog.error("关闭摄像头异常: $e", actionModule: ActionModule.tcicController.name, actionName: ActionName.closeCamera.name);
if (needToast) {
TCICToast.show(StringEnum.closeCameraFailed);
}
} finally {
if (needUIDisabled) {
_trtcStreamInfoObs.updateSelfCameraDeviceDisabled(false);
}
}
}